EVM是以太坊的心脏,是一种基于栈的图灵完备的虚拟机,用于执行合约代码。每个节点都运行它来验证交易、状态变更是否一致。它接受的输入是字节码(从Solidity编译而来),执行时会按照opcode指令逐条运行,并维护一套完整的执行环境(栈、内存、存储、Gas、程序计数器)EVM的执行结构(图
EVM是以太坊的心脏,是一种基于栈的图灵完备的虚拟机,用于执行合约代码。每个节点都运行它来验证交易、状态变更是否一致。
它接受的输入是字节码(从 Solidity 编译而来),执行时会按照opcode指令
逐条运行,并维护一套完整的执行环境(栈、内存、存储、Gas、程序计数器)
EVM 的执行结构(图解)
用图来表达通常会展示以下核心组件:
+--------------------+
| Contract Bytecode | ← 程序代码区 (不可变)
+--------------------+
↓
+--------------------+
| Program Counter | ← 当前执行指令的位置
+--------------------+
↓
+--------------------+
| Operand Stack | ← 最多1024层,执行用的临时栈
+--------------------+
↓
+--------------------+
| Memory (RAM-like) | ← 执行时的临时内存(可扩展)
+--------------------+
↓
+--------------------+
| Storage (永久存储) | ← 账户永久状态映射(key-value)
+--------------------+
↓
+--------------------+
| Gas Counter | ← 每执行一步都会消耗 Gas
+--------------------+
-
每执行一条指令:
- PC 变化;
- 栈发生入栈/出栈变化;
- 内存可能写入;
- Storage(SLOAD / SSTORE)可能触发状态变化;
- 消耗 Gas
Gas 模拟器 / 计费机制
为什么需要 Gas?
- 防止死循环;
- 资源计价机制(每个操作都定价);
- 经济激励系统的一部分。
常见的指令及其 Gas 消耗:
指令 |
含义 |
Gas (估值) |
ADD |
加法 |
3 gas |
MSTORE |
存入内存 |
3 gas |
SLOAD |
读取存储 |
2100 gas |
SSTORE |
写入存储 |
20_000 / 5000 |
CALL |
合约调用 |
≥700 gas + 内存成本 |
CREATE |
部署合约 |
32_000+ |
Opcode
EVM运行智能合约的核心就是执行字节码指令(Opcode)
,这些是低级指令,被 Solidity 编译器翻译后在链上运行
🧮 算术运算指令(Arithmetic
Opcode |
名称 |
含义说明 |
ADD |
加法 |
a + b |
SUB |
减法 |
a - b |
MUL |
乘法 |
a * b |
DIV |
除法 |
a / b |
MOD |
取模 |
a % b |
EXP |
幂运算 |
a ** b |
🔢 逻辑运算 & 位运算(Logic / Bitwise)
Opcode |
名称 |
含义说明 |
AND |
与 |
a & b |
OR |
或 |
a | |
XOR |
异或 |
a ^ b |
NOT |
取反 |
~a |
SHL |
左移 |
a << b |
SHR |
右移 |
a >> b |
🧪 比较运算(Comparison)
Opcode |
名称 |
含义说明 |
EQ |
等于 |
判断是否相等 |
LT |
小于 |
是否小于 |
GT |
大于 |
是否大于 |
ISZERO |
是否为 0 |
用于条件跳转 |
🧱 堆栈操作(Stack)
Opcode |
名称 |
含义说明 |
PUSHn |
压栈 |
推入 n 字节的值(如 PUSH1~PUSH32) |
POP |
弹栈 |
弹出栈顶一个元素 |
DUPn |
复制第 n 个 |
把第 n 个元素复制到栈顶 |
SWAPn |
交换 |
交换栈顶和第 n 个元素 |
🗃️ 存储 & 内存(Memory & Storage)
Opcode |
名称 |
含义说明 |
MLOAD |
读内存 |
从内存中读取 32 字节 |
MSTORE |
写内存 |
向内存中写入 32 字节 |
SLOAD |
读存储 |
从合约存储中读取 32 字节 |
SSTORE |
写存储 |
向合约存储中写入 32 字节 |
🔁 流程控制(Control Flow)
Opcode |
名称 |
含义说明 |
JUMP |
跳转 |
跳转到某个程序位置 |
JUMPI |
条件跳转 |
如果条件为 true,则跳转 |
JUMPDEST |
跳转目标 |
可跳转的有效目标位置 |
STOP |
停止执行 |
合约逻辑结束 |
REVERT |
回滚交易 |
回退状态改变,返回 error data |
📬 调用类指令(External Calls)
Opcode |
名称 |
含义说明 |
CALL |
调用合约 |
通用跨合约调用 |
CALLCODE |
旧版调用 |
类似 CALL,但上下文不同(不推荐使用) |
DELEGATECALL |
委托调用 |
保持调用者上下文(用于代理合约) |
STATICCALL |
静态调用 |
禁止修改状态,适合 view/pure 函数 |
CREATE |
创建合约 |
部署合约 |
CREATE2 |
确定地址创建 |
可预测合约地址(与盐值有关) |
⛽ Gas 操作
Opcode |
名称 |
含义说明 |
GAS |
查询剩余 gas |
获取当前执行剩余的 gas 值 |
GASPRICE |
gas 价格 |
当前交易的 gas price |
BASEFEE |
基础费 |
当前区块的 baseFee(EIP-1559) |
🧾 区块信息 / 上下文信息
Opcode |
名称 |
含义说明 |
ADDRESS |
当前合约地址 |
msg.sender 在合约自身的地址 |
CALLER |
调用者地址 |
msg.sender |
ORIGIN |
交易发起人 |
tx.origin |
CALLVALUE |
调用携带ETH |
msg.value |
BALANCE |
获取地址余额 |
查询任意地址的 ETH 余额 |
BLOCKHASH |
某区块 hash |
用于随机性(仅最近 256 个区块有效) |
TIMESTAMP |
区块时间戳 |
block.timestamp |
NUMBER |
当前区块高度 |
block.number |
-
原创
- 学分: 4
- 分类: 以太坊
- 标签:
EVM
OpCode