孙 炜 三六零科技有限公司区块链平台部核心工程师
目前,已经进入了以智能合约为标志的区块链2.0时代,突出的代表就是以太坊。作为第一个也是目前全球最活跃的区块链2.0公有链,它的出现将我们带入了区块链的智能合约时代,作为智能合约执行的实体,区块链虚拟机技术逐渐成为区块链核心技术里不可缺少的一员。区块链中的虚拟机目前扮演着智能合约的执行者,未来随着技术的发展,对区块链应用技术的诉求,虚拟机将承担更加重要的角色,会成为链与人沟通的一座桥梁。
从比特币为主要应用代表的区块链1.0到以以太坊为代表的区块链2.0,再到目前以EOS技术为代表的区块链3.0时代,虚拟机的概念一直贯穿其中,并不断进行完善。
(1)区块链1.0中的虚拟机
以比特币为主要应用代表的区块链1.0时代,交易是驱动比特币不断向下发展的核心元素,作为P2P网络数字经济生态的承载,比特币在网络设计上就要考虑提供针对不同交易活动需求的内部支持,这个在设计和实现上在比特币中被称为脚本。脚本作为比特币交易中不可缺少的一部分,不仅扩充了交易的类型,也保证了交易的合法和安全。从另一个角度来讲,比特币中的脚本提供给用户一种可以编程的简要接口。脚本可以看作是最原始的智能合约,而脚本的执行和解释程序可以看作是最原始的虚拟机。
比特币虚拟机本质上是一个非图灵完备的脚本的解释器。比特币上的脚本可以看作是运行在其上的智能合约。脚本在比特币中主要分为两类,两者结合来完成对交易的验证,其分别是锁定脚本和解锁脚本(见图1)。比特币的虚拟机实现上是一个基于栈的脚本解释器。虚拟机(脚本解释器)的执行过程就是通过利用栈运行脚本中作用在数值(例如签名)上的操作码,最后通过运行结果来判断交易的有效性和合法性。
图1 比特币的锁定和解锁脚本
解锁和锁定脚本可以看作是以太坊智能合约的雏形。比特币中的没有被花费出去的交易(UTXO,可以看作是余额)中加入锁定脚本,锁定脚本就像是把锁在这笔比特币上的智能锁一样,只有拿到解锁的钥匙才可以使用这笔比特币。比特币中的脚本解释器正是扮演着一个开锁人的角色,也就是作为比特币持有者和接收者中间的保证人,用来保证通过严格的执行约定(合约),也就是脚本操作语义,来保证交易的合法性。当然,也可以不把比特币中脚本解释器看作是虚拟机,但是它的简单实现确确实实加强了比特币交易的灵活性(如多重签名的应用),同时也加强了比特币的安全性。
为了直观地了解比特币虚拟机的执行逻辑,举例来说明比特币脚本的解析过程,脚本如下:
23OP_ADD5OP_EQUAL脚本的语义是验证2加上3是否等于5。在比特币中脚本的具体解析过程如图2所示。在区块链2.0时代中,目前以太坊虚拟机(EVM)依旧采用这种经典的栈式方法来对只能合约进行解释执行。
图2 比特币脚本解释示例图解
以上便是区块链1.0中虚拟机和智能合约的代表,虽然只是雏形,但是已经看到了它的生命力。
(2)区块链2.0中的虚拟机
作为区块链2.0的技术代表以太坊为用户提供了一套完整的合约运行环境,这包括完整的智能合约描述语言以及图灵完备的虚拟机。以太坊智能合约官方语言为Solidity,在利用Solidity实现智能合约逻辑后,通过编译器编译成元数据(字节码)最后发布到以太坊上。以太坊虚拟机(EVM)本质上是一个堆栈机器,设计上除了满足基本的执行需求外,还要考虑空间节省、安全保证和优化等方面需求。
以太坊虚拟机设计体现了一个精简标准的虚拟机模型。首先在存取系统上固定机器位宽为256位,这就标明EVM设计上将考虑一套自己的关于操作、数据、逻辑控制的指令编码。256位宽度的选择虽然不会使计算速度加快,但是它的设计却适合进行密码学的计算,这点在以太坊虚拟机中预编译智能合约中就有所体现。同时,固定的位宽使需要支持的操作数减少,简单可控;另一方面,从以太坊上的经济学来讲,操作数的减少意味着以太坊中智能合约执行所消耗的Gas数量的减少,成本一定程度上降低。
EVM中数据可以在3个地方进行存储,分别是栈、临时存储、永久存储。不同存储对应不同的花费。由于EVM是基于栈的虚拟机,因此基本上所有操作都是在栈上进行,并且EVM中没有寄存器的概念,这样EVM对栈的依赖就更大,虽然这样的设计使实现比较简单且易于理解,但带来的问题就是需要更多数据的栈操作。在EVM中栈是唯一的免费(几乎是)存放数据的地方,栈自然有深度的限制,目前的限制是1024,因为栈的限制,栈上的临时变量的使用会受限制。临时内存存储在每个VM实例中,并在合约执行完后消失。永久内存存储在区块链的状态层。
作为智能合约的使用者,更加关心智能合约存储在哪里。以太坊中的智能合约代码存储在一种特殊的账户中,也就是合约账户中。以太坊中主要有两类账户,一种是外部账户,另一种则是承载智能合约的合约账户。图3为以太坊中合约被调用的基本流程,外部账户通过发送交易到合约账户,存储在合约账户里的智能合约代码将会被执行。如果合约里引用另一个合约的地址,同样也会执行另外一个合约的代码。
综上,以太坊为代表的区块链2.0中EVM的实现不仅提供了完善的合约语言,还在比特币脚本解释器上扩充了相关的操作,从图灵不完备到图灵完备,此时的虚拟机已经告别原始的阶段。
(3)区块链3.0中的虚拟机
图3 以太坊智能合约调用
以EOS技术为代表的区块链3.0提供了更加强大的虚拟机,虚拟机开始从多语言支持、JIT支持、安全防护上等多方面为智能合约保驾护航,EOS在技术白皮书中并没有给虚拟机下一个确切的定义和明确的实现,书中提到只要能满足沙河运行的虚拟机都可以嫁接到EOS生态中去,这为虚拟机的发展打开了一个大门,自然同时也面临诸多例如安全等方面的挑战。
新的虚拟机架构多以WebAssembly技术为基础,EOS开源代码中给出了一个具体的实现。采用WebAssembly不仅因为WASM有强大的社区支持,另外一个层面是因为层次化的设计保证了该技术的解决方案有横向的扩展性。EOS定义智能合约的语言不仅限于传统的解释型语言,还包括C、C++这种预编译语言,借助LLVM-JIT技术,EOS虚拟机实现了高速的运行。WASM智能合约格式由于采用Clang、LLVM、Binaryen工具链,这种技术选型打开了智能合约实现语言的大门。在上述工具链下,可以用来编写只能合约的语言增多,工具链支持丰富,同时也间接催生了调试环境、集成开发环境等其他生态的崛起。但是有利有弊,多语言的支持,对链上智能合约的审计、安全等方面都提出了巨大的挑战,由于智能合约在区块链经济以及后续应用中的重要地位和作用,虚拟机安全也将成为一个热门的话题。
从以比特币为代表的区块链1.0到以EOS为代表的区块链3.0,虚拟机从最简单的脚本解释器到完备的运行时环境,这是架构上的发展和改变,也是对区块链需求催生的技术发展。目前,虚拟机服务的对象为智能合约,未来随着对区块链技术应用诉求的增多,虚拟机将承担更多的智能或者智慧的工作,运行在虚拟机上的不仅仅是智能合约还有智能。