5月,NEO与ONT签署了“技术战略协作备忘录”,随后成立了联合工作组。其中一项合作共识是:
“双方共享智能合约生态,全力支持NeoVM和NeoContract发展,打造智能合约开放标准。”
NeoContract与NeoVM(NEO虚拟机)一直以来都是NEO技术生态的重要组成部分,也是深受开发者青睐的重要原因。早在NEO首届开发者大会上,NEO创始人张铮文为开发者详细解读了NeoContract与NeoVM。
NeoContract智能合约与NeoVM的技术细节
NeoContract是NEO上的智能合约系统,你可以用它来验证交易、发行数字资产、以及创建去中心化的应用程序。NeoContract主要由三个部分组成:NeoVM、NeoContract APIs、开发工具包。
NeoVM是NEO的分布式虚拟机,用于执行智能合约。由于它低耦合的架构设计,NeoVM不但可以用于区块链系统,还能单独用在一些非区块链的应用场景下。
NeoContract APIs是智能合约的一组接口,它们能为智能合约带来大量实用且功能强大的功能。
开发工具包是提供给智能合约的一组应用程序和插件,使得基于NEO进行智能合约开发变得非常便利。
以下为详细内容
一、NeoVM
NeoVM由三个重要的部件组成,分别是执行引擎、栈和互操作服务。
1、执行引擎:这套指令集包含:常数指令、控制指令、栈操作指令、字符串操作指令、逻辑运算指令、算术运算指令、密码学指令、数据结构指令、异常处理指令。 有了这套指令集,开发者可以很方便地编写出具有复杂业务逻辑的智能合约代码,例如在程序中使用复杂数据结构、进行密码学操作、对程序的异常进行处理等。
此外,执行引擎中还内置了调试器的功能,可以对代码设置断点,或者进行单步执行,对智能合约进行调试。指令集中有一部分指令是栈操作指令,说明实际上NeoVM是一个基于栈的虚拟机。
2、栈:NeoVM具有三个可以被使用的栈,分别是调用栈、计算栈和备用栈。
调用栈用于记录函数调用时的程序运行状态,以便当函数返回时程序可以在当前上下文中继续执行。
计算栈的作用是对操作数进行计算,是合约代码可以直接访问的临时存储区域。当程序需要执行加法运算的时候,就需要将加法的两个操作数压入计算栈,然后执行加法指令,此时执行引擎就会从计算栈的栈顶将两个操作数读取出来然后相加,最后将把相加结果压回栈顶,就可以从栈顶去使用这个结果了。
而备用栈的作用实际上是一个临时存放的区域,可以放一些计算栈上暂时不用的数据。
3、互操作服务:如果把执行引擎看成是计算机系统中的CPU,那么栈就是内存,而互操作服务就是系统总线。它将执行引擎、栈以及外部服务连接在一起,使得智能合约可以访问到NeoContract提供的各种API,例如时间戳服务、持久化存储等,这样智能合约可以实现的功能就大大增强了。
这种低耦合的设计方式,使得NeoVM可以被很方便地移植到其它区块链上,与非区块链的应用场景中去,只需要在不同的场景中为互操作服务提供不同的API即可。
二、NeoContract APIs
NeoContract提供了很多功能强大的API,智能合约可以通过NeoVM的互操作服务来访问它们,从而完成更多更复杂的任务。这些API包括:运行时信息、账本数据、持久化存储、智能合约管理、数字资产。
1、运行时信息,是指与合约当前运行的状态有关的信息。其中之一是触发器,它的规范在NEP-7中定义。在NEO中,智能合约需要被触发才能执行,目前定义了四种不同的触发器,用于满足不同的应用场景。
当节点正在验证一笔交易的有效性时,就会使用验证触发器来启动相关联的智能合约;当用户通过一笔交易来启动一个分布式应用的时候,就会触发应用触发器;当一个智能合约收到一笔转账时,会触发收款触发器,它可以允许合约在交易验证阶段就拒绝本次转账,或者在收款后进行额外的处理;另一个非常重要的功能就是时间戳服务器,它使得智能合约可以在运行时获取到当前的时间。
由于区块链是一个分布式系统,必须有一个统一的接口来确保所有的节点对时间达成共识。为了达到这个目的,使用区块的时间戳作为这个服务的数据源。最后,通知和日志可以帮助智能合约在运行时与节点程序进行通信,让节点程序可以对智能合约的执行状态进行追踪。
2、账本数据,有时智能合约需要读取区块链中的区块、交易或者用户的账户余额等数据来进行逻辑判断,所以需要大量的API,让智能合约可以读取到每一笔交易的每一个字段。通过这种方式,也可以通过交易,将外部数据发送到链上,从而实现外部数据的读取。只要有通过某种机制来保证发送到链上的数据的可靠性,就可以实现一个去中心化的预言机。
3、持久化存储,NEO提供了一组基于键值对的数据存取接口,合约可以通过键来读取、写入、删除数据记录。此外,它还可以取得自己的存储上下文,并将它传给其它的合约,这样就可以委托其它的合约来管理自己的存储区。
基于这样的一种机制,我们可以编写一个专门的合约,使它对系统底层的键值对存储功能进行封装,并对外提供高级的数据库管理功能。
4、智能合约管理,使合约可以在运行时对链上部署的智能合约进行管理,主要有三个功能:创建并部署新的合约、升级并迁移现有的合约、销毁已部署的合约。当发生合约销毁时,旧合约的存储区会和合约一起被销毁,如果是合约迁移,那么旧存储区的内容会被复制到新合约的存储区中。
5、数字资产,NEO中的数字资产分为两类:全局资产和合约资产。
NEO和GAS属于全局资产,也可以通过API来创建新的全局资产。所有的全局资产都是基于UTXO模型的,并且可以通过NeoID的功能来映射实体信用。
另一种类型的资产就是合约资产,它是通过NeoContract提供的存储功能来实现的,整个资产的账本数据都保存在智能合约的存储区中,并由合约来管理所有的账户。关于合约资产,它的token标准是NEP-5,如果开发的合约支持NEP-5,那么它的token就可以被绝大多数的NEO钱包软件支持。
三、开发工具包
要在NEO上进行智能合约的开发,首先需要使用你最熟悉的高级语言来编程,目前NEO支持的语言有:.NET系列的语言(C#、VB.NET、F#)、Java系列语言(Java、Kotlin)、Python、JavaScript,未来我们还会支持更多的高级语言,例如Go语言。
选择好你的语言,接下来就是IDE,可以使用Visual Studio来进行开发、编译和调试,Java的Eclipse也是很好的选择。如果选择了其它语言来进行智能合约的开发,你可以使用任意的编辑器来编程,然后通过一个NEO的编译器来将高级语言转换为NeoVM的字节码。
NEO编译器可以将高级语言的源代码编译成可在NeoVM上运行的字节码,同时,还会生成符合NEP-3标准的ABI文件。将字节码部署到NEO的区块链上,就可以获得链上的存储区,或被其它合约调用;也可以将字节码包含在一笔交易中,直接执行这段程序。
直接执行时,合约将不会被部署,也不会产生部署费用。编译器生成的ABI文件可用于合约调用,它描述了智能合约公开的函数和事件列表,从而让节点程序和用户知道应该如何使用这个合约的功能。
未来升级计划
在对智能合约与虚拟机进行了深度的解读之后,张铮文谈到了NeoContract未来的升级计划
1、序列化和反序列化,在合约中会用到一些复杂的数据结构,我们将会在NeoContract中添加一组API,用于将数据序列化为字节数组,或者将字节数组还原为原来的数据结构,这样就可以在存储区中存取任意数据了。
2、存储迭代器,现在合约的存储功能只能读取一条确切的记录,除非知道这条记录的键,否则不可能访问到它。有了存储迭代器,可以通过条件来搜索数据记录,并读取、修改或删除它们中的某些记录。
3、栈隔离,NeoVM中有三个栈可供智能合约来使用,分别是调用栈、计算栈和备用栈。调用栈无法被合约直接修改,只能通过流程控制指令来进行操作,所以很安全;计算栈和备用栈,可以直接通过合约代码来进行修改,所以在合约相互调用的场景下,有可能会发生被调用者修改调用者的计算栈的情况。这种情况在静态调用的场景下并没有什么危害,因为被调用的目标是确定的,它的行为也是确定的。但是,由于NEP-4已经提出合约的动态调用机制,未来在动态调用的场景下,上述所说的情况将会危害调用者合约的数据安全。所以要将计算栈和备用栈进行隔离,使得调用链上的每一帧都有自己独立的栈空间。
4、异常处理,是我们将要增强的一项功能。我们将要实施的一项改进是,为NeoVM添加新的异常处理指令,让合约可以捕获到异常,并有机会尝试从异常中恢复。这项功能的实现也会需要隔离的计算栈。
5、动态分片,NEO的系统架构非常优秀,目前可以支持大约1000tps的负载。但是随着应用数量的上升,未来总有一天会出现拥堵的情况,所以必须提前设计好扩容方案。分片技术是提升系统吞吐量的一种方法,我们计划实施一种叫做动态分片的方案,它可以根据合约的调用关系,动态地将无关的合约放进不同的分片中,而相关的合约放进同一个分片中,从而使得合约可以在一定程度上并发执行。由于每次合约之间的调用关系都会发生变化,所以分片的规则也会自动调整,以使得系统始终处于最优化的状态。这种方法将会比静态的分片方案在提升吞吐量方面更加有效。
6、NeoX,NeoX是一项跨链解决方案,包含跨链资产交换协议和跨链分布式事务协议。在NeoX中有一项技术,可以允许智能合约跨越不同的区块链来执行,简单的说,一次智能合约的执行可能会包含很多的步骤,这些步骤要么全部执行成功,要么全部执行失败,如果这些步骤在同一个链上执行,没有问题;但是如果这些步骤分布在不同的链上执行,那么要保证它们的一致性就会变得很困难。
NeoX正是用于解决这个问题的,而要实现这一项技术,需要对NeoVM进行改进,允许它对状态进行锁定和回滚。一旦这项技术被实施,未来智能合约就可以在不同的链上执行,并保证它的一致性不被破坏,前提是这些区块链都使用NeoVM,或者使用了和NeoVM相同的技术。