跳转至主要内容
Change page

以太坊虚拟机的操作码

页面最后更新: 2025年9月11日

概述

这是 wolflo/evm-opcodes (opens in a new tab) 上的 EVM 参考页面的更新版本。 内容也源自《黄皮书》 (opens in a new tab)《Jello Paper》 (opens in a new tab)geth (opens in a new tab) 实现。 本文旨在作为一份易于理解的参考资料,但并不十分严谨。 如果想确保正确性并了解每种边缘情况,建议使用 Jello Paper 或客户端实现。

在寻找交互式参考? 查看 evm.codes (opens in a new tab)

有关具有动态燃料费用的操作,请参阅 gas.md (opens in a new tab)

💡 快速提示:要在桌面设备上查看整行,请使用 [shift] + scroll 水平滚动。

堆栈名称燃料起始堆栈最终堆栈内存 / 存储注释
00STOP0中止执行
01ADD3a, ba + b(u)int256 加法,模 2**256
02MUL5a, ba * b(u)int256 乘法,模 2**256
03SUB3a, ba - b(u)int256 减法,模 2**256
04DIV5a, ba // buint256 除法
05SDIV5a, ba // bint256 除法
06MOD5a, ba % buint256 模数
07SMOD5a, ba % bint256 模数
08ADDMOD8a, b, N(a + b) % N(u)int256 加法,模 N
09MULMOD8a, b, N(a * b) % N(u)int256 乘法,模 N
0AEXPA1 (opens in a new tab)a, ba ** buint256 乘方,模 2**256
0BSIGNEXTEND5b, xSIGNEXTEND(x, b)x(b+1) 字节符号扩展 (opens in a new tab)到 32 字节
0C-0F无效
10LT3a, ba < buint256 小于
11GT3a, ba > buint256 大于
12SLT3a, ba < bint256 小于
13SGT3a, ba > bint256 大于
14EQ3a, ba == b(u)int256 相等
15ISZERO3aa == 0(u)int256 是否为零
16AND3a, ba && b按位与
17OR3a, b`a \\b`
18XOR3a, ba ^ b按位异或
19NOT3a~a按位非
1ABYTE3i, x(x >> (248 - i * 8)) && 0xFF从左起,(u)int256 x 的第 i 个字节
1BSHL3shift, valval << shift左移
1CSHR3shift, valval >> shift逻辑右移
1DSAR3shift, valval >> shift算术右移
1E-1F无效
20KECCAK256A2 (opens in a new tab)ost, lenkeccak256(mem[ost:ost+len-1])keccak256
21-2F无效
30ADDRESS2.address(this)执行合约的地址
31BALANCEA5 (opens in a new tab)addraddr.balance余额,以 wei 为单位
32ORIGIN2.tx.origin发起交易的地址
33CALLER2.发送者消息发送者的地址
34CALLVALUE2.msg.value消息值,以 wei 为单位
35CALLDATALOAD3idxmsg.data[idx:idx+32]从索引 idx 处的消息数据中读取字
36CALLDATASIZE2.len(msg.data)消息数据的长度,以字节为单位
37CALLDATACOPYA3 (opens in a new tab)dstOst, ost, len.mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1]复制消息数据
38CODESIZE2.len(this.code)执行合约代码的长度,以字节为单位
39CODECOPYA3 (opens in a new tab)dstOst, ost, len.mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1]复制执行合约的字节码
3AGASPRICE2.tx.gasprice交易的燃料价格,以 wei/单位燃料计 ** (opens in a new tab)
3BEXTCODESIZEA5 (opens in a new tab)addrlen(addr.code)地址处代码的大小,以字节为单位
3CEXTCODECOPYA4 (opens in a new tab)addr, dstOst, ost, len.mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1]addr 复制代码
3DRETURNDATASIZE2.size上次外部调用的返回数据的大小,以字节为单位
3ERETURNDATACOPYA3 (opens in a new tab)dstOst, ost, len.mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1]复制上次外部调用的返回数据
3FEXTCODEHASHA5 (opens in a new tab)addr哈希哈希 = addr.exists ? keccak256(addr.code) : 0
40BLOCKHASH20blockNumblockHash(blockNum)
41COINBASE2.block.coinbase当前区块提议者地址
42TIMESTAMP2.区块时间戳当前区块的时间戳
43NUMBER2.block.number当前区块的编号
44PREVRANDAO2.randomness beacon随机信标
45GASLIMIT2.block.gaslimit当前区块的燃料限制
46CHAINID2.chain_id将当前链 id (opens in a new tab) 推入堆栈
47SELFBALANCE5.address(this).balance执行合约的余额,以 wei 为单位
48BASEFEE2.block.basefee当前区块的基本费用
49BLOBHASH3idxtx.blob_versioned_hashes[idx]EIP-4844 (opens in a new tab)
4ABLOBBASEFEE2.block.blobbasefee当前区块的 blob 基本费用 (EIP-7516 (opens in a new tab))
4B-4F无效
50POP2_anon.从堆栈顶部移除一项并丢弃
51MLOAD3* (opens in a new tab)ostmem[ost:ost+32]从内存偏移量 ost 处读取字
52MSTORE3* (opens in a new tab)ost, val.mem[ost:ost+32] := val向内存写入一个字
53MSTORE83* (opens in a new tab)ost, val.mem[ost] := val && 0xFF向内存写入单个字节
54SLOADA6 (opens in a new tab)keystorage[key]从存储中读取字
55SSTOREA7 (opens in a new tab)key, val.storage[key] := val向存储中写入字
56JUMP8dst.$pc := dst 标记 pc 仅在 dst 是一个有效的 jumpdest 时才被赋值。
57JUMPI10dst, condition.$pc := condition ? dst : $pc + 1`
58PC2.$pc程序计数器
59MSIZE2.len(mem)当前执行上下文中内存的大小,以字节为单位
5AGAS2.gasRemaining
5BJUMPDEST1标记有效的跳转目标一个有效的跳转目标,例如一个不在推送数据内的跳转目标
5CTLOAD100keytstorage[key]从瞬时存储中读取字 (EIP-1153 (opens in a new tab))
5DTSTORE100key, val.tstorage[key] := val向瞬时存储中写入字 (EIP-1153 (opens in a new tab))
5EMCOPY3+3*words+A0 (opens in a new tab)dstOst, ost, len.mem[dstOst] := mem[ost:ost+len]将内存从一个区域复制到另一个区域 (EIP-5656 (opens in a new tab))
5FPUSH02.uint8push the constant value 0 onto stack
60PUSH13.uint8将 1 字节值推入堆栈
61PUSH23.uint16将 2 字节值推入堆栈
62PUSH33.uint24将 3 字节值推入堆栈
63PUSH43.uint32将 4 字节值推入堆栈
64PUSH53.uint40将 5 字节值推入堆栈
65PUSH63.uint48将 6 字节值推入堆栈
66PUSH73.uint56将 7 字节值推入堆栈
67PUSH83.uint64将 8 字节值推入堆栈
68PUSH93.uint72将 9 字节值推入堆栈
69PUSH103.uint80将 10 字节值推入堆栈
6APUSH113.uint88将 11 字节值推入堆栈
6BPUSH123.uint96将 12 字节值推入堆栈
6CPUSH133.uint104将 13 字节值推入堆栈
6DPUSH143.uint112将 14 字节值推入堆栈
6EPUSH153.uint120将 15 字节值推入堆栈
6FPUSH163.uint128将 16 字节值推入堆栈
70PUSH173.uint136将 17 字节值推入堆栈
71PUSH183.uint144将 18 字节值推入堆栈
72PUSH193.uint152将 19 字节值推入堆栈
73PUSH203.uint160将 20 字节值推入堆栈
74PUSH213.uint168将 21 字节值推入堆栈
75PUSH223.uint176将 22 字节值推入堆栈
76PUSH233.uint184将 23 字节值推入堆栈
77PUSH243.uint192将 24 字节值推入堆栈
78PUSH253.uint200将 25 字节值推入堆栈
79PUSH263.uint208将 26 字节值推入堆栈
7APUSH273.uint216将 27 字节值推入堆栈
7BPUSH283.uint224将 28 字节值推入堆栈
7CPUSH293.uint232将 29 字节值推入堆栈
7DPUSH303.uint240将 30 字节值推入堆栈
7EPUSH313.uint248将 31 字节值推入堆栈
7FPUSH323.uint256将 32 字节值推入堆栈
80DUP13aa, a克隆堆栈上的第 1 个值
81DUP23_, aa, _, a克隆堆栈上的第 2 个值
82DUP33_, _, aa, _, _, a克隆堆栈上的第 3 个值
83DUP43_, _, _, aa, _, _, _, a克隆堆栈上的第 4 个值
84DUP53..., aa, ..., a克隆堆栈上的第 5 个值
85DUP63..., aa, ..., a克隆堆栈上的第 6 个值
86DUP73..., aa, ..., a克隆堆栈上的第 7 个值
87DUP83..., aa, ..., a克隆堆栈上的第 8 个值
88DUP93..., aa, ..., a克隆堆栈上的第 9 个值
89DUP103..., aa, ..., a克隆堆栈上的第 10 个值
8ADUP113..., aa, ..., a克隆堆栈上的第 11 个值
8BDUP123..., aa, ..., a克隆堆栈上的第 12 个值
8CDUP133..., aa, ..., a克隆堆栈上的第 13 个值
8DDUP143..., aa, ..., a克隆堆栈上的第 14 个值
8EDUP153..., aa, ..., a克隆堆栈上的第 15 个值
8FDUP163..., aa, ..., a克隆堆栈上的第 16 个值
90SWAP13a, bb, a
91SWAP23a, _, bb, _, a
92SWAP33a, _, _, bb, _, _, a
93SWAP43a, _, _, _, bb, _, _, _, a
94SWAP53a, ..., bb, ..., a
95SWAP63a, ..., bb, ..., a
96SWAP73a, ..., bb, ..., a
97SWAP83a, ..., bb, ..., a
98SWAP93a, ..., bb, ..., a
99SWAP103a, ..., bb, ..., a
9ASWAP113a, ..., bb, ..., a
9BSWAP123a, ..., bb, ..., a
9CSWAP133a, ..., bb, ..., a
9DSWAP143a, ..., bb, ..., a
9ESWAP153a, ..., bb, ..., a
9FSWAP163a, ..., bb, ..., a
A0LOG0A8 (opens in a new tab)ost, len.LOG0(memory[ost:ost+len-1])
A1LOG1A8 (opens in a new tab)ost, len, topic0.LOG1(memory[ost:ost+len-1], topic0)
A2LOG2A8 (opens in a new tab)ost, len, topic0, topic1.LOG2(memory[ost:ost+len-1], topic0, topic1)
A3LOG3A8 (opens in a new tab)ost, len, topic0, topic1, topic2.LOG3(memory[ost:ost+len-1], topic0, topic1, topic2)
A4LOG4A8 (opens in a new tab)ost, len, topic0, topic1, topic2, topic3.LOG4(memory[ost:ost+len-1], topic0, topic1, topic2, topic3)
A5-EF无效
F0CREATEA9 (opens in a new tab)val, ost, lenaddraddr = keccak256(rlp([address(this), this.nonce]))
F1CALLAA (opens in a new tab)燃料, addr, val, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
F2CALLCODEAA (opens in a new tab)燃料, addr, val, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] = returndata与 DELEGATECALL 相同,但不传播原始的 msg.sender 和 msg.value
F3RETURN0* (opens in a new tab)ost, len.return mem[ost:ost+len-1]
F4DELEGATECALLAA (opens in a new tab)燃料, addr, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
F5CREATE2A9 (opens in a new tab)val, ost, len, saltaddraddr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:]
F6-F9无效
FASTATICCALLAA (opens in a new tab)燃料, addr, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
FB-FC无效
FDREVERT0* (opens in a new tab)ost, len.revert(mem[ost:ost+len-1])
FEINVALIDAF (opens in a new tab)指定的无效操作码 - EIP-141 (opens in a new tab)
FFSELFDESTRUCTAB (opens in a new tab)addr.将所有 ETH 发送到 addr;如果在创建合约的同一交易中执行,它会销毁该合约

本文对你有帮助吗?