关于区块链:虚拟机专栏智能合约执行引擎的前世今生

40次阅读

共计 3279 个字符,预计需要花费 9 分钟才能阅读完成。

Solidity 作为最早提出的智能合约语言,它的呈现为区块链的利用场景关上了新的大门。
—— 缘起 ——
智能合约(Smart Contract)这个术语最早于 1994 年由跨畛域法律学者尼克·萨博(NickSzabo)⾸次提出。他对智能合约的定义如下:

“一个智能合约是一套以数字模式定义的承诺(commitment),包含合约参与方能够在下面执行这些承诺的协定。”

所以简略来看,尼克·萨博认为智能合约是⼀套承诺。所谓承诺就是参加⽅批准的相互之间的权力和任务。因而智能合约的实质和⽬的即是承诺自身。⽐如⼀个简略的交易事件,卖家承诺供货,买家承诺⽀付,这两个承诺就能够造成⼀个智能合约。留神尼克·萨博对智能合约定义中提到的关键词:数字模式和协定。这两个关键词决定了智能合约不同于传统意义上的承诺,它在模式和性能上有着决定性的特色。

「智能合约」最开始由以太坊引入区块链。据以太坊白皮书,引入智能合约次要为了解决如下问题:

对于脚本语言,脚本是非图灵齐备(后文会介绍)的,难以实现简单的性能,比方椭圆曲线签名算法

脚本无奈对能够提取的金额进行细粒度管制

脚本不足状态保留,无奈实现更为简单的有状态合约

执行时能获取的数据不够丰盛,例如随机数、工夫戳和前一个区块哈希的获取

总之,脚本语言无奈满足更为丰盛的利用操作,所以以太坊设计了独特的智能合约语言 Solidity,同时,执行智能合约的智能合约执行引擎 EVM 也诞生了。

自此,区块链技术的利用场景,从繁多基于 UTXO 的数字货币交易,延长到图灵齐备的通用计算畛域。用户不再受限于仅能应用比特币脚本所反对的简略逻辑,而是能够自行设计任意简单的合约逻辑。

—— 总述 ——
以太坊设计智能合约有着如下设计特点:

▲ 执行的确定性

确定性是指程序对于给定的输出,不论在何时何地,执行多少次都有雷同的输入。因为区块链保护的是同一份账本,智能合约执行的确定性能够了解为不同的节点执行雷同的合约,必须有雷同的后果。

以太坊智能合约语言被设计的足够简略,为了保障执行的确定性,其不会实现随机数,不确定的(零碎)调用等性能,同时,智能合约的执行在一个环境被限度的虚拟机中进行,这样可能在底层更加保障其后果的确定性。

▲ 图灵齐备性

图灵齐备的语言,比拟官网的解释是“能够计算所有能够用一个算法计算的问题”的语言,包含有限循环。以太坊引入智能合约的目标就是为了实现图灵齐备,来反对更为丰盛的利用模式。

引入图灵齐备之后须要解决的一个问题就是停机问题:在个别状况下,没有方法判断给定的程序是否会停机。

为了防止图灵齐备带来的停机问题,以太坊引入 Gas 机制,来对相干的执行过程进行消耗计算。通过将各种操作费用以 gas(每个操作会对应特定的 gas 耗费即有一个 gas 耗费的对应表)为单位计算,并且设置每次执行的 gas 耗费下限,即 gasLimit,在合约执行消耗累计操作 gasLimit 下限后强制进行执行,从而达到停机的成果。Gas 机制的引入,使得用户对应用利用的复杂程度取决于其违心为其付出的代价,而不是平台物理上的限度。

当然,Gas 机制的引入也还有其余益处,不在此处过多介绍。

▲ 安全性

安全性作为以太坊的设计前提,也是智能合约须要保障的。以太坊智能合约的安全性在设计上次要体现在两个方面:

1)绝对简略的智能合约语言

Solidity 语言绝对于支流的图灵齐备语言而言,因为其专一于区块链场景,所以很多语言个性其没有必要去实现比方多线程,零碎调用,这就使得其能够设计得尽可能简化。不过这也是其晚期比拟难用的起因之一,尽管随着语言的逐步倒退,其性能也在一直的减少与欠缺。

2)智能合约的执行环境足够隔离

以太坊智能合约运行在以太坊虚拟机 EVM 中,EVM 中的运行不仅被沙盒化,而且实际上是齐全隔离的,这意味着在 EVM 中运行的代码无法访问网络、文件系统或其余过程。甚至智能合约中对其余智能合约的拜访也很无限。通过运行的隔离很大水平上保障了其可控平安。

然而,不可否认以太坊智能合约依然存在许多平安上的问题,如驰名的“可重入攻打”等。

—— 详解 ——
上面,让咱们深刻 Solidity 合约的执行引擎 — EVM。
EVM 被定义为一种栈式虚拟机,其应用一个字节作为指令。栈式虚拟机的特点是执行运算时都是依附与操作数栈(operand stack)进行交互。
Solidity 合约源码通过编译后是用一种低级的、基于堆栈的字节码,所以咱们真正部署在以太坊上并且在 EVM 中执行的其实是一串字节码。代码由一系列字节组成,其中每个字节代表一个操作。字节码执行时从第一个字节码开始依据字节码的操作含意顺次执行,直到达到代码开端或呈现谬误(如遇到 REVERT、STOP 或 RETURN 操作码)。这些操作能够拜访三种类型的空间来存储数据:

栈: 后进先出容器,其值能够被压入和弹出;

Memory: 一个有限可扩大的字节数组;

Storage: 合约的长期存储,为键 / 值对存储。与计算完结后重置的堆栈和 Memory 不同,存储会长期存在,这部分也就是常说的“世界状态”的一部分。

智能合约的执行过程其实就是根据操作码定义的行为对三种类型存储空间的操作过程,咱们以上面的例子进行简略的展现:

下图展现局部合约片段:右边是合约字节码,左边是字节码代表的操作含意

各个操作码的简略含意如下:

PUSH1:字节码 16 进制为 60,操作含意是将紧跟着的一个字节推入栈中

ADD:字节码 16 进制为 01,操作含意是将栈上的两个元素弹出相加,而后将后果放回栈中

MSTORE:字节码 16 进制为 52,操作含意是将栈中弹出的第二个值存入 Memory 中,存入的索引值为栈中弹出的第一个元素

RET:字节码 16 进制为 f3,操作含意是执行完结,返回后果,后果在 Memory 中,起始索引为栈中弹出的第一个值,长度为栈中弹出的第二个值

将这段字节码放入 EVM 中执行,其执行过程如下所示:

其中,PC 代表以后执行操作码的地位,合约片段执行的最初(即:RET 操作码)会从 Memory 中的 60 起始处,取出 5 个字节的数据进去,由此,合约片段执行结束,最终的后果会被返回给调用者!

仔细的同学会发现,图中相干的指令没有和 Storage 相干的操作,其实是因为为了简化没有在示例代码中选取相干的指令如 SStore,其执行原理和上述的表述相似。

“那么,为什么 EVM 会被设计成这个样子?为什么通过这些栈的进进出出,内存的复制来复制去,以及对 Storage 的操作,就可能解决计算问题,实现对合约状态的获取以及批改呢?”

这就波及到编程语言的设计了。实践上,在计算理论体系中,指令集架构是一个计算机的形象模型,指令集蕴含的指令类型丰盛水平间接影响着程序表白的丰盛水平。比方,指令集中能够蕴含算数和逻辑运算类指令如加减乘除,管制类指令如跳转,数据处理指令如读取内存等。而作为虚拟机,能够依据须要选取或者增加指令构建一个指令集,来表白本人冀望的性能。比方 EVM 中没有针对与浮点数的相干操作,减少了 Storage 相干的指令,所以这就从指令层面解释了 Solidity 语言不反对浮点数的运算。而在指令确定之后借助古代程序设计的一些工具,即可设计出特定的语言。所以,在某种程度上,如果须要,咱们也能够实现本人的语言以及对应的执行引擎。

—— 倒退 ——
EVM 的实质是通过可编程的语言来操作“世界状态”,也就是咱们所说得区块链账本,因而,如何更好、更快的来操作是智能合约虚拟机的一大谋求。

随着一直的倒退,行业内已领有多种智能合约执行引擎,同时也不乏新的摸索。

EVM:兼容以太坊 EVM,并进行了性能优化与功能丰富

HVM:趣链独创反对 Java 语言编写智能合约的高效、易用、齐备的智能合约执行引擎

FVM:反对 Rust 等语言编写智能合约的平安,多样,高效的智能合约执行引擎

KVSQL:反对在区块链上执行 SQL 语句的新型执行引擎

本文作为【虚拟机】专栏的开篇,介绍智能合约的起源以及以太坊智能合约,接下来系列文章将会对其余执行引擎进行具体介绍,敬请期待!

作者简介
何奇
趣链科技根底平台部区块链虚拟机钻研小组
参考文献
[1] 智能合约百度百科

[2] 以太坊黄皮书

[3] 以太坊白皮书

正文完
 0