查看原文
其他

NEXT社区小课堂 | 第十二课:NEO编译器

NEONEXT 2023-07-20

NEXT社区 | 小课堂


由于近期NEXT社区加入很多新的小伙伴,有在校大学生,有对区块链感兴趣的传统企业从业者。为了更方便、更系统的让NEXT社区的伙伴们了解NEO的技术知识,因此我们开设了小课堂,每周3节,向大家普及NEO相关的知识要点!



NEXT社区小课堂 | 第十二课

NEO编译器




1项目链接


1、NEO本身是开源的,在github搜索就可以拿到源码,为了方便调试,把所有代码都放在一起。

https://github.com/benhaben/neo-compiler.git


2、NEO是C#开发的,大部分代码可以跨平台,但是也有不能再mac上运行的代码,比如改装后的leveldb的代码,所以最好还是用Visual Studio在windows上调试研究较好。


3、本文档现在不太规范,主要考虑好理解,并不完善,后面也可以进一步规范化提交到NEO项目中。



2主框架




大家可以看到Compiler所处的位置



3Compiler作用


1、在NEO区块链系统中,智能合约是一段代码,可以完成一定的逻辑,最后算出合约的结果。现在已经有很多具体的应用了,感兴趣的可以看一下基于NEO做的项目。


2、如果对比特币或者智能合约不了解,不知道为什么需要有这些代码,可以看一下比特币的白皮书。这里简单说一下,在比特币系统中,当一个“人”(可以看成一个公钥)需要和另一个“人”产生交易的时候,这段代码用来检查身份,分配比特币。具体的了解可以看一下普林斯顿的公开课。


3、下面进入到NEO compiler的介绍了,前面所需的基础知识本文不在关注。



4Compiler的框架


下面的图主要显示代码的主要流程:



1、NEO可以用各种语言写,不过现在主要是C#


2、NEO的编译器主要是一个翻译器


3、C#代码被C#编译器编译成MSIL,对MSIL的理解可以查看Standard ECMA-335 Common Language Infrastructure (CLI)


4、Neo compiler使用Mono.Cecil读取IL


5、NEO编译器只关注C#中的static function,所以只是C#语言的一个超级阉割版


6、NEO的编译器遍历IL,根据语义转成NEO虚拟机的opcode


7、至于MSIL向NEO.VM的opcode怎么转,需要仔细研究NEO.VM的opcode的设计



5Compiler工作一个具体事例


先看一段智能合约代码


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; }}



6MSIL


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的虚拟机也是堆栈虚拟机。



7neo.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


我们可以发现如下情况:


1、MSIL的代码很短,NEO.VM的代码很长,这是由于虚拟机的指令和能力不同造成的。我们只需要关注,汇编代码处理了局部变量的存贮获取,参数的传递,程序的退出,还有add指令


2、汇编代码和compiler的生成算法相关,需要我们去同时研究NEO的编译器和虚拟机,才能明白具体的细节


3、具体每一行的含义,怎么执行的,可以查看这个文档


4、后面还会有一个讲解虚拟机的文章,到那个时候在仔细说明



8neo.compiler代码阅读指南


代码阅读还是很头痛的,所以做了两个脑图:


1、compiler执行脑图

2、compiler对象关系





1、ILModule是对MSIL的一个映射,包含模块,类型,函数,字段,函数中又包含返回值,参数,函数体,可以点开脑图一层一层查看


2、Mono.Cecil是使用来读取MSIL的,他也是对MSIL的一个映射,由于没有文档,只能看代码知道他的类结构了,这一部分在脑图中没有显示,不过没关系,compiler会把感兴趣的代码转成ILModule


3、ModuleConverter用来遍历ILModule,把里面的MSIL转成NEO.VM的代码,存贮在NeoModule


4、具体两边的指令如何对应,真是需要一个一个理解的,非常繁琐,两边都有很多的指令。可以看看这个代码



9总结


看完这个文章,并不能了解到具体的细节,具体的细节已经在代码中,这篇文章的主要目的是提供很多资料,提供大的框架,帮助对NEO.Compiler感兴趣的程序员加速阅读代码的速度。



原文链接:https://www.jianshu.com/p/6461b4e18089



往期精彩内容

NEXT社区小课堂 | 第五课:NEO-共识算法dBFT源码解析

NEXT社区小课堂 | 第八课:如果往错误的NEO地址转账会发生什么

NEXT社区小课堂 | 第十课:如何正确理解NEO平台上的GAS(NeoGas)

NEXT社区小课堂 | 第十一课:NEO中数字的表达和运算




  联系我们  

微博:https://weibo.com/u/6724929880

官网:https://neonext.club/

QQ群:612334080

电报:https://t.me/neonextop

twitter:https://twitter.com/NE0NEXT


扫码关注NEO NEXT官方公众号

获取更多一手社区资讯

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存