亦来Talk ▏亦来云NEO侧链虚拟机原理

2019年3月1日09:52:56 发表评论 2,363 views

张小宾,资深软件开发工程师、区块链开发工程师,DACA区块链公开课学员。2018年加入亦来云团队,参与了亦来云钱包SDK的开发,后又成功将Neo的智能合约虚拟机NeoVM移植到了亦来云侧链中,现已加入以太坊侧链的开发小组中。

上述这些构成亦来云平台的重要服务组件,是亦来云平台技术从概念原型走到技术落地的一个重要环节,也将标志着亦来云新一代互联网平台正式开始从工程开发阶段走向开放的运作和实施阶段。关于NEO侧链更多技术方面相关的专业知识,张小宾在分享中做了详细解读。

▼▼▼

NEO VM与智能合约
智能合约是20世纪90年代由尼克萨博提出的理念。智能合约是⼀套以数字形式定义的承诺,包括合约参与⽅可以在上⾯执⾏这些承诺的协议。NEO VM 是⼀个基于栈的虚拟机,是执⾏NEO智能合约代码的虚拟机。NEO智能合约开发者可以直接使⽤⼏乎任何他们擅长的⾼级语⾔来进⾏NEO智能合约的开发⼯作。NEO 提供了这些语⾔的编译器和插件,⽤于将⾼级语⾔编译成 NEO虚拟机所⽀持的指令集。

我叫张小宾,今天向大家分享下,我在移植虚拟机这块儿,对NEO VM的理解,分享的内容不多,比较底层,希望达到的效果就是大家对运行在区块链上的代码,也就是智能合约有一定的认识和了解。

现在大家可能已经知道了,智能合约就是运行在区块链系统上的一段代码,NEO VM就是执行这段代码的虚拟机,我们今天就了解下,NEO VM是如何识别这段代码并运行的。如果大家了解堆栈这个数据结构会对今天的分享比较容易理解,因为NEO VM就是基于堆栈的,包括以太坊虚拟机EVM也是基于堆栈实现的。

在这里,我总结了几个NEO VM的特点,给大家分享下:

亦来Talk ▏亦来云NEO侧链虚拟机原理

NEO合约的一个主要特点就是可以使用C#,Java进行编程。NEO 智能合约的开发工作。NEO 提供了这些语言的编译器和插件,用于将高级语言编译成 NEO 虚拟机所支持的指令集。

亦来Talk ▏亦来云NEO侧链虚拟机原理

现在我们看下这个虚拟机结构的图,图是NEO官方提供的,是理解NEO虚拟机最主要的一个图。首先上面的Compiler就是代码编译层,也就是我们平常写的代码,如Java会通过我们使用的编译器,如Visual Studio编译生成AVM。这个AVM就是我们在虚拟机内部要执行的代码,也就是OpCode。

中间Virtual Machine这一部分就是虚拟机,也就是在我们每个节点上运行的NEO VM虚拟机的结构,可以看到它分为执行引擎、堆栈、互操作层。执行引擎就是负责把我们读取OpCode和指令来放入堆栈中进行执行的执行器。通过上面的图可以看到,这里面有流程控制,有堆栈结构、有数组操作、逻辑处理算法等虚拟机内实现的功能,也就是在写合约的时候可以使用的一些数据结构和算法。

互操作层用于访问区块链系统的数据,如Block,Transaction等。还有另外一个考虑,就是可以访问外部数据,但是现在还没有实现。最下面的一层就是区块链系统Distributed Ledger,即分布式账本,有这三部分构成了整个智能合约的执行结构。

下面我们就看下AVM编译器,是如何生成OPCode这个过程的。

亦来Talk ▏亦来云NEO侧链虚拟机原理

上面这个图是我做的一个流程图。通过这个图可以看到,利用我们平常编程的编辑器,也就是Visual Studio把C#通过Mono把MSIL这个中间语言直接翻译成OpCode的过程。

只是有上面的流程图,可能还感觉有点儿不太了解。我现在就把通过上面的流程图的代码和实际的数据来给大家展示一下。

亦来Talk ▏亦来云NEO侧链虚拟机原理

当我看到这张图的时候有一种恍然大悟的感觉,第一部分就是我们平常的C#代码然后通过编译器,它会生成MSIL,通过这个MSIL,其实可以看出来,它其实也是一个基于堆栈的一个操作指令码,是微软中间语言,它是一种介于高级语言和基于Intel的汇编语言的伪汇编语言。

然后通过C#编译工具,也可以直接把MSIL这个中间语言翻译成我们NEO VM对应的OpCode,拿微软堆栈OpCode和NEO VM的 OpCode做了一个转换,也就是中间的16进制值。这一部分16进制值其实就是对应了一个OpCode的操作指令,每一个操作指令对应着一个堆栈的操作方法。

下面,是里面最核心的部分。现在看一下C#代码简单的一个加法合约,在堆栈内是怎样运行的,来做一个展示。

亦来Talk ▏亦来云NEO侧链虚拟机原理

上面这张图就是通过C#代码写的一个加法合约。

亦来Talk ▏亦来云NEO侧链虚拟机原理

接着通过微软的编译器Visual Studio可以把这一部分C#代码翻译成MSIL微软中间语言。

亦来Talk ▏亦来云NEO侧链虚拟机原理

然后通过Mono.Ceil,可以再把中间语言翻译成了对应的OpCode的16进制值。

亦来Talk ▏亦来云NEO侧链虚拟机原理然后上面的16进制值对应着上面截的图,虚拟机操作指令。

下面会展示上面这些指令在堆栈内的运行过程,内容有些多,大家可以先看一下。

亦来Talk ▏亦来云NEO侧链虚拟机原理
堆栈操作过程
亦来Talk ▏亦来云NEO侧链虚拟机原理 亦来Talk ▏亦来云NEO侧链虚拟机原理 亦来Talk ▏亦来云NEO侧链虚拟机原理 亦来Talk ▏亦来云NEO侧链虚拟机原理 亦来Talk ▏亦来云NEO侧链虚拟机原理 亦来Talk ▏亦来云NEO侧链虚拟机原理

上面这些图其实就是计算3+4加法这个堆栈操作过程,咱们可以直接看最后一张图,就是栈顶是7。

下面会对加法合约有一个简单的图的介绍。

亦来Talk ▏亦来云NEO侧链虚拟机原理

通过上面这这张图大家应该很简单明了了。这个图就是简化版来的加法的堆栈操作过程。这样大家可以了解到,其实NEO的编译器还有很大的改进空间。

现在和大家介绍一下在堆栈内部是如何实现循环的。

其实在堆栈实现循环,也就是实现一个跳转指令JMP,就是如果当前运行指令是JMP指令,则根据栈顶数据找出需要跳到的堆栈地址,接着从当前堆栈位置继续执行,直到再碰到JMP指令,这样就会循环执行堆栈内部的一部分代码。

亦来Talk ▏亦来云NEO侧链虚拟机原理

上面就是在虚拟机内部实现了的数结构和算法的控制,包括对堆栈的操作,出栈、入栈,交换一些流程控制,就刚才说的跳转甚至IF也是通过跳转来实现的。还有基本的算术指令,加密指令,还有其他的一些基于流的操作。

在合约内部,大家应该还会对和是如何消耗GAS的应该也有所兴趣,现在就把这部分代码给大家看一下。

亦来Talk ▏亦来云NEO侧链虚拟机原理

在NEO VM里面执行合约也就是在执行指令,每一个指令都是消耗GAS的,通过上面这个代码可以看到,它默认每个指令都消耗1GAS,,对于其他的指令会有不同的定价。这样就保证了,大家在合约内部写不出来死循环了,总有GAS消耗尽的一天。

亦来Talk ▏亦来云NEO侧链虚拟机原理

其实现在大家对NEO VM,应该就感觉很有所了解了。现在我就做一下总结,其实就是介绍了这三部分的内容,智能合约就是运行在区块链上的一段代码,代码实现了跳转就是图灵完备的,然后所需要的技术模块就包含编译器、执行器也就是虚拟机、区块链。其中区块链是实现智能合约的基本条件。

NEO VM也就是执行NEO 智能合约的虚拟机,它实现了一套基于堆栈的OpCode以及对应的执行器的一段程序。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: