Neo的Compiler工作怎么实现
这篇文章主要介绍"Neo的Compiler工作怎么实现",在日常操作中,相信很多人在Neo的Compiler工作怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Neo的Compiler工作怎么实现"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
Compiler作用
在Neo区块链系统中,智能合约是一段代码,可以完成一定的逻辑,最后算出合约的结果。现在已经有很多具体的应用了,感兴趣的可以看一下基于Neo做的项目。
如果对比特币或者智能合约不了解,不知道为什么需要有这些代码,可以看一下比特币的白皮书。这里简单说一下,在比特币系统中,当一个"人"(可以看成一个公钥)需要和另一个"人"产生交易的时候,这段代码用来检查身份,分配比特币。具体的了解可以看一下普林斯顿的公开课
下面进入到Neo compiler的介绍了,前面所需的基础知识本文不在关注。
Compiler的框架
基本的流程
Neo可以用各种语言写,不过现在主要是C#。
Neo的编译器主要是一个翻译器
C#代码被C#编译器编译成MSIL,对MSIL的理解可以查看Standard ECMA-335 Common Language Infrastructure (CLI)
Neo compiler使用Mono.Cecil读取IL
Neo编译器只关注C#中的static function,所以只是C#语言的一个超级阉割版
Neo的编译器遍历IL,根据语义转成Neo虚拟机的opcode
至于MSIL向neo.vm的opcode怎么转,需要仔细研究neo.vm的opcode的设计
Compiler工作一个具体事例
先看一段智能合约代码
这段代码没有什么实际的作用,就是返回a+b,但是main可以接受参数。
using Neo.SmartContract.Framework;using Neo.SmartContract.Framework.Services.Neo;public class Sum : SmartContract{ public static int Main(int a, int b) { return a + b; }}
MSIL
main function IL code
IL_0000 NopIL_0001 Ldarg_0IL_0002 Ldarg_1IL_0003 AddIL_0004 Stloc_0IL_0005 Br_SIL_0007 Ldloc_0IL_0008 Ret
这段代码很简单,就是读取参数Ldarg_0,Add,返回。可以看到CLR的虚拟机也是堆栈虚拟机。
关于基于栈的虚拟机和基于寄存器的虚拟机可以看一下这些文章:
栈式虚拟机和寄存器式虚拟机?
另外还有一篇概念讲解的很详细的文章虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩
neo.compiler
为了感性的认识neo编译器做了什么,我们可以看一下上面的只能合约被翻译成了什么
hex:53-C5-6B-6C-76-6B-00-52-7A-C4-6C-76-6B-51-52-7A-C4-61-6C-76-6B-00-C3-6C-76-6B-51-C3-93-6C-76-6B-52-52-7A-C4-62-03-00-6C-76-6B-52-C3-61-6C-75-66
实际上是一串数字了,每个数字对应一个vm的操作码或者是数值,为了更好理解,把汇编代码放出来
PUSH4PUSH3RETPUSH3NEWARRAYTOTALSTACKFROMALSTACKDUPTOALTSTACKPUSH0PUSH2ROLLSETITEMFROMALSTACKDUPTOTALSTACKPUSH1PUSH2ROLLSETITEMNOPFROMALSTACKDUPTOTALSTACKPUSH0PICKITEMFROMALSTACKDUPTOTALSTACKPUSH1PICKITEMADDFROMALSTACKDUPTOTALSTACKPUSH2PUSH2ROLLSETITEMJMPFROMALSTACKDUPTOTALSTACKPUSH2PICKITEMNOPFROMALSTACKDROPret
neo汇编的说明,可以查看这个文档
我们可以发现如下情况:
MSIL的代码很短,Neo.VM的代码很长,这是由于虚拟机的指令和能力不同造成的。我们只需要关注,汇编代码处理了局部变量的存贮获取,参数的传递,程序的退出,还有add指令。
汇编代码和compiler的生成算法相关,需要我们去同时研究neo的编译器和虚拟机,才能明白具体的细节。
具体每一行的含义,怎么执行的,可以查看这个文档
后面还会有一个讲解虚拟机的文章,到那个时候在仔细说明
neo.compiler代码阅读指南
代码阅读还是很头痛的,所以做了两个脑图:
compiler执行脑图
compiler对象关系
对象关系
ILModule是对MSIL的一个映射,包含模块,类型,函数,字段,函数中又包含返回值,参数,函数体,可以点开脑图一层一层查看。
Mono.Cecil是使用来读取MSIL的,他也是对MSIL的一个映射,由于没有文档,只能看代码知道他的类结构了,这一部分在脑图中没有显示,不过没关系,compiler会把感兴趣的代码转成ILModule
ModuleConverter用来遍历ILModule,把里面的MSIL转成Neo.VM的代码,存贮在NeoModule
具体两边的指令如何对应,真是需要一个一个理解的,非常繁琐,两边都有很多的指令。可以看看这个代码
到此,关于"Neo的Compiler工作怎么实现"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!