以太坊虚拟机原理简析

mac2025-09-02  23

以太坊虚拟机原理简析

以太坊虚拟机(EVM)是以太坊区块链中的重要概念,也是其智能合约实现的重要组成模块。学习EVM有助于开发者加深对智能合约实现的理解,也有助于开发者学习使用汇编语言(Assembly)来对智能合约进行更精细和更复杂的操作,甚至实现Solidity语言原本无法实现的功能。本篇文章将简要概述用Solidity编写的智能合约如何被编译成字节码以及EVM如何对字节码进行执行和运算。

以太坊虚拟机(EVM)是智能合约的执行时环境,它是完全孤立的沙盒:运行在EVM中的代码无法访问网络、文件系统或其他进程。

创建智能合约

智能合约通常使用高级语言Solidity来进行编写,其代码风格类似JavaScript与C++。

/** * Constructor function * * Initializes contract with initial supply and designate ownership */ constructor() public { owner = msg.sneder; balanceOf[owner] = totalSupply; emit Transfer(address(0),owner,totalSupply); }

其他语言例如Vyper和Bamboo也可以用来编写智能合约。当创建一个智能合约时,包含数据信息(payload)的交易被发送至空地址时,其数据信息将作为输入在EVM中执行,其输出将作为代码永久地保存在合约地址中。需要注意的是:Solidity这样的高级语言是无法在EVM中被直接执行的,代码会被编译成更加接近机器的低级语言—操作码(opcode)来执行。

EVM与操作码(Opcode)

EVM是基于栈的虚拟机,为了方便计算,EVM定义了以32个字节为一个词(word)进行操作,栈中最多存储1024个词。

function add(uint a, uint b){ uint sum = a + b; }

在执行上图的加法运算时,EVM的实际流程是:

PUSH b, 将b推入栈PUSH a, 将a推入栈ADD, 栈顶两列相加

上述的PUSH,ADD称为操作码(opcode),是虚拟机可以直接执行的指令,目前EVM定义了大约140个操作码,几乎可以完成所有的计算(图灵完备)。操作码可以简单地分为以下几类:

栈操作码(POP, PUSH, DUP, SWAP)算术/比较/位运算操作码(ADD, SUB, GT, LT, AND, OR)环境操作码(CALLER, CALLVALUE, NUMBER)内存操作码(MLOAD, MSTORE)硬盘操作码(SLOAD, SSTORE)终止操作码(STOP, RETURN, REVERT, INVALID. SELEFDESTRUCT)

字节码(Bytecode)

为了方便存储操作码,EVM采用字节码(Bytecode)来对操作码进行标记。一个字节等于两位16进制数,因此最多存储256个操作码。 EVM执行时,字节码将按照字节(即每两位16进制数)划分执行。字节0x60-0x7f(PUSH1 – PUSH32)是特殊的字节,该字节后的字节数将作为输入压入栈中。 下面来看一组字节码的实际执行步骤:

0x6002600101

0x60是特殊的字节码(PUSH1),它取之后的一个字节0x02作为输入。 因此0x6002在EVM中是PUSH1 0x02同理0x60是特殊的字节码(PUSH1),它取之后的一个字节0x01作为输入。 因此0x6001在EVM中是PUSH1 0x010x01对应直接码ADD

因此,上述的字节码在EVM中是对2和1进行求和运算,它先后将0x02和0x01压入栈中,再将栈顶的2个数字弹出栈进行相加,最后将结果0x03压入栈中。

总结

本文简单介绍了EVM的执行原理:以Solidity编写的智能合约将被编译成字节码在EVM中执行,在下一节我们将对智能合约的存储结构和字节码进行更加详细地解析。

最新回复(0)