上一篇区块链研究方案先整理一下Neo编译器的知识吧。项目链接Neo本身是开源的,在github搜索就可以拿到源码,我为了方便调试,把所有代码都放在一起。https://github.com/benhaben/n…Neo是C#开发的,大部分代码可以跨平台,但是也有不能再mac上运行的代码,比如改装后的leveldb的代码,所以最好还是用VisualStudio在windows上调试研究较好。本文档主要是总结自己所研究的东西,现在不太规范,主要考虑好理解,并不完善,后面也可以进一步规范化提交到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读取ILNeo编译器只关注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; }}MSILmain function IL codeIL_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的操作码或者是数值,为了更好理解,把汇编代码放出来PUSH4PUSH3RETPUSH3NEWARRAYTOTALSTACKFROMALSTACKDUPTOALTSTACKPUSH0PUSH2ROLLSETITEMFROMALSTACKDUPTOTALSTACKPUSH1PUSH2ROLLSETITEMNOPFROMALSTACKDUPTOTALSTACKPUSH0PICKITEMFROMALSTACKDUPTOTALSTACKPUSH1PICKITEMADDFROMALSTACKDUPTOTALSTACKPUSH2PUSH2ROLLSETITEMJMPFROMALSTACKDUPTOTALSTACKPUSH2PICKITEMNOPFROMALSTACKDROPretneo汇编的说明,可以查看这个文档我们可以发现如下情况:MSIL的代码很短,Neo.VM的代码很长,这是由于虚拟机的指令和能力不同造成的。我们只需要关注,汇编代码处理了局部变量的存贮获取,参数的传递,程序的退出,还有add指令。汇编代码和compiler的生成算法相关,需要我们去同时研究neo的编译器和虚拟机,才能明白具体的细节。具体每一行的含义,怎么执行的,可以查看这个文档后面还会有一个讲解虚拟机的文章,到那个时候在仔细说明neo.compiler代码阅读指南代码阅读还是很头痛的,所以做了两个脑图:compiler执行脑图compiler对象关系对象关系ILModule是对MSIL的一个映射,包含模块,类型,函数,字段,函数中又包含返回值,参数,函数体,可以点开脑图一层一层查看。Mono.Cecil是使用来读取MSIL的,他也是对MSIL的一个映射,由于没有文档,只能看代码知道他的类结构了,这一部分在脑图中没有显示,不过没关系,compiler会把感兴趣的代码转成ILModuleModuleConverter用来遍历ILModule,把里面的MSIL转成Neo.VM的代码,存贮在NeoModule具体两边的指令如何对应,真是需要一个一个理解的,非常繁琐,两边都有很多的指令。可以看看这个代码总结看完这个文章,并不能了解到具体的细节,具体的细节已经在代码中,这篇文章的主要目的是提供很多资料,提供大的框架,帮助对Neo.Compiler感兴趣的程序员加速阅读代码的速度。作者:沈寅原文链接:https://www.jianshu.com/p/646…
Neo编译器
December 27, 2018 · 1 min · jiezi