区块链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)、CALLDATALOAD、CALLDATASIZE、CALLDATACOPY — 访问交易上下文。
- NUMBER、TIMESTAMP、BASEFEE、CHAINID — 区块级信息。
- BALANCE、EXTCODESIZE、EXTCODECOPY — 查询其他账户。
Gas计费表
每个操作码都有gas成本。Gas服务于两个目的:防止无限循环(停机问题)和公平定价计算资源。
| 级别 | Gas | 示例 |
|---|---|---|
| 零 | 0 | STOP、RETURN、REVERT |
| 基础 | 2 | ADDRESS、ORIGIN、CALLER |
| 极低 | 3 | ADD、SUB、LT、GT、AND、OR、POP |
| 低 | 5 | MUL、DIV、MOD |
| 中 | 8 | ADDMOD、MULMOD、JUMP |
| 高 | 10 | JUMPI |
| 特殊 | 可变 | SLOAD、SSTORE、CALL、CREATE |
冷访问与热访问(EIP-2929)
EIP-2929(Berlin升级,2021年4月)引入了访问列表的概念——每笔交易中被访问过的地址和存储槽的集合。
在交易中首次访问存储槽或外部地址时,它是“冷“的,需要支付额外gas。后续访问是“热“的,比较便宜。
交易执行流程
当你发送调用合约的交易时,完整的执行序列如下:
- 交易验证 — Nonce检查、余额检查、签名验证
- 固有Gas扣除 — 交易本身21000 gas,加上每非零calldata字节16 gas和每零字节4 gas
- 上下文设置 — EVM创建执行上下文:代码、calldata、调用者、值、剩余gas
- 程序计数器从0开始 — EVM读取位置0处的操作码并执行
- 顺序执行 — 每个操作码被执行,gas被扣除。JUMP和JUMPI允许非线性控制流
- 终止 — 执行以STOP、RETURN、REVERT或Gas耗尽结束
- 状态提交或回滚 — 成功时提交所有状态变更,回滚时撤销所有变更
对MEV的实际影响
如果你在构建MEV机器人,在操作码级别理解EVM不是可选的——而是竞争必备。节省的每一单位gas都是利润空间。
总结
EVM的简洁性体现了它的优雅:一台使用256位字的栈机器、扁平的字节码格式,以及为每个操作定价的Gas计量系统。理解这个基础——操作码、栈和Gas——是本系列后续内容的前提。