区块链知识系列 - 系统学习EVM(一)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
EVM有一个基于栈的架构在一个栈中保存了所有内存数值。EVM的数据处理单位被定义为256位的“字”这主要是为了方便处理哈希运算和椭圆曲线运算操作
这里所说的内存数值是指那些EVM字节码运行所需要的输入、输出参数数据和智能合约程序运行中所需要的局部变量等数据而不是指下文中所提到的“内存”数据下文中的“内存”是一个与栈共同存在的、独立的临时存储空间。
以太坊EVM的架构和执行上下文
虚拟机引擎
目前市面上比较主流的是BTC脚本引擎和以太坊虚拟机Ethereum Virtual Machine, EVM。
- BTC事务由一套脚本引擎Script处理Script是一种类Forth的、基于栈式模型的、无状态的、非图灵完备的语言。
- EVM基于Account模型将智能合约代码以对外完全隔离的方式内部运行实现了图灵完备的智能合约体系。
- EVM类似于Java虚拟机JVM编译后基于字节码运行开发时则可以使用高级语言实现编译器会自动转化为字节码。
- EVM。以太坊虚拟机是以太坊中智能合约的运行环境并且是一个沙盒与外界隔离。
- 智能合约代码在EVM内部运行时是不能进行网络操作、文件I/O或执行其他进程的。智能合约之间也只能进行有限的调用这样保证了合约运行的独立性并尽可能提高了运行时的安全性。
图灵完备
图灵完备的计算环境——以太坊虚拟机EVM。这就意味着在EVM上可以做所有的能想得到计算包括无限循环。EVM指令包括一个JUMP的跳转指令可让程序跳回前面的程序代码也可以像条件判断语句那样做条件跳转当满足一定条件时将程序跳转到另一个地方执行。另外一个合约可以调用其他合约这提供了潜在的递归调用的功能。
以太坊虚拟机
EVM模块主要分为三大模块编译合约模块、Ledger模块和EVM执行模块。
- 编译合约模块
- 主要是对底层Solc编译器进行一层封装提供RPC接口给外部服务对用Solidity编写的智能合约进行编译。编译后将会返回二进制码和相应的合约ABI, ABI可以理解为合约的手册
- Ledger模块
- Ledger模块主要是对区块链Account系统进行修改和更新Account一共分为两种分别是普通Account(EOA)和智能合约Account调用方如果知道合约Account地址则可以调用该合约Account的每一次修改都会被持久化到区块链中。
- EVM执行模块
- EVM执行模块作为核心模块主要功能是对事务中的智能合约代码进行解析和执行一般分为创建合约和调用合约两部分。
- 支持普通的字节码执行和JIT模式的指令执行
指令集
EVM指令由很多标准机器码指令组成包含
- 算术和位运算逻辑操作
- 执行上下文查询
- 栈、内存和存储访问
- 处理流程操作
- 日志、跳转和其他操作
EVM模块执行流程
EVM执行事务的流程如图所示
(1) EVM接收到Transaction信息然后判断Transaction类型是部署合约还是执行合约。如果是部署合约执行指令集来存储合约地址和编译后的代码如果是执行合约或是调用合约则使用EVM来执行输入指令集。
(2) 执行上一条指令集之后判断EVM是否停机如果停机则判断是否正常停机正常停机则更新合约状态到区块链否则回滚合约状态。如果不停机则回到上一步(1)进行判断。
(3) 执行完的合约会返回一个执行结果EVM会将结果存储在Receipt回执中调用者可以通过Transaction的哈希来查询结果。
EVM代码的正式执行模型
每轮执行时通过调出代码的第pc程序计数器个字节每个指令如何影响元组都有定义。例如ADD将两个元素出栈并将它们的和入栈将Gas减1并将pc加1; stack将顶部的两个元素出栈并将第2个元素插入由第1个元素定义的合约存储位置同样减少最多200的Gas值并将pc加1。虽然有许多方法通过即时编译去优化以太坊但以太坊的基础性的实施可以用几百行代码实现。
EVM是基于栈的虚拟机
以太坊合约的代码是使用低级的基于堆栈的字节码的语言写成的被称为“以太坊虚拟机代码”或者“EVM代码”。代码由一系列字节构成每一个字节代表一种操作。一般而言代码执行是无限循环程序计数器每增加一初始值为零就执行一次操作直到代码执行完毕或者遇到错误、STOP或者RETURN指令。
EVM不是基于寄存器的而是基于栈的虚拟机。因此所有的计算都在一个称为栈的区域内执行。栈最大有1024个元素每个元素有256位。对栈的访问只限于其顶端允许复制最顶端的16个元素中的一个到栈顶或者是交换栈顶元素和下面16个元素中的一个。所有其他操作都只能取最顶的一个或几个元素并把结果压在栈顶。当然可以把栈里的元素放到存储或者主存中。但是无法只访问栈里指定深度的那个元素在那之前必须把指定深度之上的所有元素都从栈中移除才行。
EVM的指令集被刻意保持在最小规模以尽可能避免可能导致共识问题的错误。所有的指令都是针对256位这个基本的数据单位进行的操作具备常用的算术、位、逻辑和比较操作也可以进行条件和无条件跳转。
执行指令部分的Gas
虚拟机EVM执行指令部分的Gas计算是最为复杂的。虚拟机EVM事务执行期间的所有操作包括数据库读写、消息发送以及虚拟机采取的每个计算步骤都要消耗一定量的燃料并且在不同参数和缓存影响的情况下都会对应有不同的燃料标价。图2-15是取自以太坊官方黄皮书中的非指令部分的燃料标价示例图。
黄皮书链接https://ethereum.github.io/yellowpaper/paper.pdf
高级语言
以太坊的高级语言最后会编译成在EVM中执行的EVM字节码bytecode部署在以太坊区块链上。以太坊提供3种编程语言Solidity、Serpent和LLL。