跳到主要内容
区块链Mar 28, 2026

Deep EVM #1:EVM如何执行你的代码——操作码、栈和Gas

OS
Open Soft Team

Engineering Team

EVM是一台栈机器

以太坊虚拟机不像你笔记本电脑中的x86处理器。它没有寄存器。相反,它是一台栈机器——每次计算都从一个1024元素的栈中推入或弹出,每个元素是一个256位(32字节)的字。

当你调用智能合约时,EVM接收合约的字节码——一个扁平的单字节操作码序列——并从字节0开始执行。没有函数表,没有ELF头,没有链接步骤。字节码就是程序。

// Solidity:
// uint256 result = 2 + 3;

// 编译为字节码:
// PUSH1 0x02  PUSH1 0x03  ADD

// 栈追踪:
// []           -> PUSH1 0x02 -> [2]
// [2]          -> PUSH1 0x03 -> [2, 3]
// [2, 3]       -> ADD        -> [5]

每个操作码从栈顶消费其操作数并将结果推回。ADD操作码弹出两个值,将它们相加,并推入总和。这与基于寄存器的架构有根本性的不同。

操作码分类

EVM定义了大约140个操作码,按功能分组:

算术和比较

  • ADD、SUB、MUL、DIV、MOD — 基本256位整数算术。全部消耗3 gas(G_verylow级别)。
  • SDIV、SMOD — 使用二进制补码的有符号除法和取模。
  • ADDMOD、MULMOD — 模运算:单个操作码中的(a + b) % N(a * b) % N。对椭圆曲线运算至关重要,消耗8 gas。
  • EXP — 指数运算。消耗10 gas + 指数中每字节50 gas。
  • LT、GT、SLT、SGT、EQ、ISZERO — 比较操作码,推入1(真)或0(假)。

位运算

  • AND、OR、XOR、NOT — 位逻辑,每个3 gas。
  • SHL、SHR、SAR — 左移、逻辑右移、算术右移(Constantinople升级中添加,EIP-145)。
  • BYTE — 从32字节字中提取单个字节。

栈操作

  • POP — 丢弃栈顶元素。
  • PUSH1到PUSH32 — 将1到32字节的立即数推入栈。
  • DUP1到DUP16 — 复制第N个栈元素到栈顶。
  • SWAP1到SWAP16 — 将栈顶元素与其下方第N个元素交换。

环境和区块信息

  • CALLER(msg.sender)、CALLVALUE(msg.value)、CALLDATALOADCALLDATASIZECALLDATACOPY — 访问交易上下文。
  • NUMBERTIMESTAMPBASEFEECHAINID — 区块级信息。
  • BALANCEEXTCODESIZEEXTCODECOPY — 查询其他账户。

Gas计费表

每个操作码都有gas成本。Gas服务于两个目的:防止无限循环(停机问题)和公平定价计算资源。

级别Gas示例
0STOP、RETURN、REVERT
基础2ADDRESS、ORIGIN、CALLER
极低3ADD、SUB、LT、GT、AND、OR、POP
5MUL、DIV、MOD
8ADDMOD、MULMOD、JUMP
10JUMPI
特殊可变SLOAD、SSTORE、CALL、CREATE

冷访问与热访问(EIP-2929)

EIP-2929(Berlin升级,2021年4月)引入了访问列表的概念——每笔交易中被访问过的地址和存储槽的集合。

在交易中首次访问存储槽或外部地址时,它是“冷“的,需要支付额外gas。后续访问是“热“的,比较便宜。

交易执行流程

当你发送调用合约的交易时,完整的执行序列如下:

  1. 交易验证 — Nonce检查、余额检查、签名验证
  2. 固有Gas扣除 — 交易本身21000 gas,加上每非零calldata字节16 gas和每零字节4 gas
  3. 上下文设置 — EVM创建执行上下文:代码、calldata、调用者、值、剩余gas
  4. 程序计数器从0开始 — EVM读取位置0处的操作码并执行
  5. 顺序执行 — 每个操作码被执行,gas被扣除。JUMP和JUMPI允许非线性控制流
  6. 终止 — 执行以STOP、RETURN、REVERT或Gas耗尽结束
  7. 状态提交或回滚 — 成功时提交所有状态变更,回滚时撤销所有变更

对MEV的实际影响

如果你在构建MEV机器人,在操作码级别理解EVM不是可选的——而是竞争必备。节省的每一单位gas都是利润空间。

总结

EVM的简洁性体现了它的优雅:一台使用256位字的栈机器、扁平的字节码格式,以及为每个操作定价的Gas计量系统。理解这个基础——操作码、栈和Gas——是本系列后续内容的前提。