这是EVM系列文章的开篇-简化EVM世界启发你,欢迎订阅公众号“blockchain技术学堂”,这里不仅授人于鱼,还会授人于渔,一起成长,成为更好的自己。
blockchain技术学堂
看过不少EVM的文章总是给人一种难于理解或者是可以理解但是很容易忘记最终不知道到底掌握了没有这样的感觉,也许是结构过于混乱或者概念不清晰或者EVM知识点过多产生焦虑感,面对这样的事情做作为一个有抱负的智能合约开发者、区块链开发者一定要勇于面对它,解决它,让它成为自己的知识晶体沉淀于长时记忆中,未来可以随时、快速提取。
什么是EVM?
要了解EVM概念,我们得先了解什么是VM。
VM通常指的是虚拟机(Virtual Machine):它是一种特殊的软件,可以在计算机平台和终端用户之间创建一种环境,用户基于这个软件所创建的环境来操作软件。
这个定义还是有些抽象,可以用类比方式来理解。
比如我们使用的操作系统windows、macos、linux 本身是基于我们的硬件之上的一套操作系统(负责管理如CPU、内存等硬件资源和应用程序等软件资源),在这个操作系统环境里你可以安装其它应用软件如:ms vcode、word、excel;我们的VM就是 应用软件,只是这个应用软件有点特别,它模拟了操作系统的环境,你还可以在它之上再安装其它软件或者操作系统,比如VMware、VirtualBox、Microsoft Virtual PC就是这种VM应用软件。
一句话总结就是 模拟硬件操作系统环境的应用程序。
EVM就是Ethereum Virtual Machine 以太坊虚拟机的缩写,它的作用是用来部署和执行智能合约这样的一个计算引擎,用于解释执行智能合约字节码的堆栈结构环境。
以比特币为代表的货币区块链技术为1.0的话,以太坊为代表的智能合约区块链技术为2.0,智能合约在以太坊中具有非常重要的核心地位。所以理解智能合约在EVM的执行过程对于优化智能合约、使用方式有很大的帮助。
为什么EVM使用的是堆栈结构?
EVM的作用是用来部署和执行智能合约提供的一个运行环境,那么它的目的只是为智能合约服务的一个工具。
联合创始人加文·伍德博士(Gavin Wood)概述了处理账本状态和运行智能合约的以太坊虚拟机(EVM)的规范中并没有明确说明使用堆栈结构的原因,所以这里收集了 指令结构的分类:
1、堆栈结构
2、累加器结构
3、通用寄存器结构
寄存器是中央处理器(CPU)内部用来存放数据的一些小型存储区域,用于暂时存放参与运算的数据和运算结果。所以寄存器结构是需要真实硬件支撑的
在分布式网络中,由多种不同计算机组成,不同的计算机可能使用不同的操作系统,所以前提得兼容这些操作系统即与环境无关,所以堆栈结构很可能就是必选项了。
为了能更清楚看到EVM在整个以太坊协议体系中的位置,需要在更高的角度去理解,在这之前需要先了解几个概念:
区块链概念
1、交易
以太坊可以看作是基于交易的状态机,一个交易代表了状态的有效变化
有两种类型的交易,而且都是由外部账户(EOA) 发起,一种是创建创建合约交易,一种是消息调用交易
一笔交易包含了以下数据,交易账户的随机数(nonce)、交易单价(gasPrice)、gas费用上限、交易的to地址(如果是创建合约to地址为空,否则为交易对象地址)、交易的数量(value)、交易签名的值(v r s ),data(如果是创建合约交易data为非空)
2、消息
账户A与账户B之间进行转账就是消息传递
消息其实是交易的包装,有两种消息:一种是EOA账户A与EOA账户B的ETH转账,这种不需要EVM参考;另一种是EOA账户与合约账户CA的交易,这种需要EVM进行参与
EOA与CA之间形成四种消息调用方式
3、区块
一个区块包含了多笔交易
4、区块链
从状态的角度来看,区块链实际上就是状态链,因为每个区块中每笔交易都包含了最新的状态变化
从现实的角度来看,区块与区块之间形成的指向关系称为区块链
5、账本
从账本的角度来看,区块链就是一堆区块所包含的交易集合
6、世界状态
世界状态是地址与账户之间的映射关系,即一个地址代表了一个账户,账户下有很多状态属性
7、账户
账户是世界状态中的对象,一个账户通过与一个地址进行映射
账户中包含了随机数、账户余额、账户存储哈希、合约代码哈希几个状态数据
账户有两种类型:
一种是外部账户(EOA):通过私钥生成公钥,公钥经过哈希之后取前160位即20个字节作为账户地址
另一种是合约账户(OA):合约帐户是通过合约创建者的地址与交易随机数经过 RLP 和KEC 哈希后取最右的160位做为地址
8、去中心化账本
每个以太坊节点都会内置了一份账本数据,数据的传递通过P2P网络进行
首先,一个外部账户EOA通过WEB3API发起一笔通过私钥签名的消息调用(交易),最后修改了账户状态的过程(隐藏了EVM执行过程)
一笔交易一个原子交易,不能被删除和中断,要么交易成功,要么交易失败,没有第三种
交易必须要顺序执行且不能重复
不保证交易的排序过程,并不是先发的交易会优先处理
具有打包权的矿工先会从交易池中选择要打包成区块的交易,打包的交易由矿工来决定顺序
区块与区块之间的排序在2022年9月15日之前是POW算法,之前是通过节点竞争算力的方式来决定区块排序的,在2022年9月15号之后使用了POS共识算法,由验证者提名产生区块的打包权
EVM的组成结构
从以太坊区块链协议体系来看,EVM只是以太坊组成的一部分,是智能合约的运行环境,从第一性原理出发,应该从这个地方开始入手,给出一份字节码(是如何编译的),又是如何解释运行的,中间有一个操作码的连接。从这里扩散开始去理解EVM可能更合适
EVM的构成元素:
PC(程序计算器)、Gas、operations(操作码)、stack(堆栈)、memory(内存)、storage(存储)
上面的图感觉没有下面的图规整,所以还是以下面为例
下面从以太坊全局视角下看 EVM所在位置:一笔交易进来之后,先会检查交易字段的数据(比如发送者是否有充足的交易额等)
然后执行交易内容指令,最后更新账户的世界状态数据
EVM定义了 三种存储类型:
堆栈(Stack)、内存(Memory)、存储(Storage),其中 Stack和Memory是非永久性的,易变的;Storage是永久性
堆栈是一种后进先出(LIFO)数据结构,EVM规定了栈只能由1024个项,每个项为32个字节即256位,一次读写都是256位,可以访问的栈的深度为16个项。EVM定义的对栈的操作码有几个,比如:PUSH/POP/COPY/SWAP等
内存是按照字节数组的方式组织的数据结构,一个元素就是一个字节,每次读取256位即32个字节,每次可写入 256位或8位数据
操作码为MSTORE/MSTORE8/MLOAD
Storage存储是一种永久性存储,它是通过键-值对进行映射保存,每次读写都是256位进行,每个键存储的是256位,值也是256位,操作码为SSTORE/SLOAD
EVM 代码即是节点客户端执行的字节码。智能合约被编译成字节码之后的最终执行代码
EVM在执行交易时的具体流程:
总结:
了解EVM是什么,熟悉一下区块链的一些基础概念,EVM在以太坊协议体系中的位置及作用,EVM组成结构。
在下一篇中我们逐步了解组成结构的每个元素的详细介绍和执行过程,后续也会陆续进行实战系列的文章输出,欢迎订阅,如果理解不到位的地方请多多指教。
【参考1】ethereum_evm_illustrated
【参考2】以太坊白皮书 (中文版)
【参考3】指令集的结构分类