跳转至主要内容
Change page

以太坊虚拟机的操作码

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

概述

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

在寻找交互式参考? 查看 evm.codesopens in a new tab

有关具有动态燃料费用的操作,请参阅 gas.mdopens 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
0AEXPA1opens in a new taba, 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无效
20KECCAK256A2opens in a new tabost, lenkeccak256(mem[ost:ost+len-1])keccak256
21-2F无效
30ADDRESS2.address(this)执行合约的地址
31BALANCEA5opens in a new tabaddraddr.balance余额,以 wei 为单位
32ORIGIN2.tx.origin发起交易的地址
33CALLER2.发送者消息发送者的地址
34CALLVALUE2.msg.value消息值,以 wei 为单位
35CALLDATALOAD3idxmsg.data[idx:idx+32]从索引 idx 处的消息数据中读取字
36CALLDATASIZE2.len(msg.data)消息数据的长度,以字节为单位
37CALLDATACOPYA3opens in a new tabdstOst, ost, len.mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1]复制消息数据
38CODESIZE2.len(this.code)执行合约代码的长度,以字节为单位
39CODECOPYA3opens in a new tabdstOst, ost, len.mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1]复制执行合约的字节码
3AGASPRICE2.tx.gasprice交易的燃料价格,以 wei/单位燃料计 **opens in a new tab
3BEXTCODESIZEA5opens in a new tabaddrlen(addr.code)地址处代码的大小,以字节为单位
3CEXTCODECOPYA4opens in a new tabaddr, dstOst, ost, len.mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1]addr 复制代码
3DRETURNDATASIZE2.size上次外部调用的返回数据的大小,以字节为单位
3ERETURNDATACOPYA3opens in a new tabdstOst, ost, len.mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1]复制上次外部调用的返回数据
3FEXTCODEHASHA5opens in a new tabaddr哈希哈希 = addr.exists ? keccak256(addr.code) : 0
40BLOCKHASH20blockNumblockHash(blockNum)
41COINBASE2.block.coinbase当前区块提议者地址
42TIMESTAMP2.区块时间戳当前区块的时间戳
43NUMBER2.block.number当前区块的编号
44PREVRANDAO2.randomness beacon随机信标
45GASLIMIT2.block.gaslimit当前区块的燃料限制
46CHAINID2.chain_id将当前链 idopens in a new tab 推入堆栈
47SELFBALANCE5.address(this).balance执行合约的余额,以 wei 为单位
48BASEFEE2.block.basefee当前区块的基本费用
49BLOBHASH3idxtx.blob_versioned_hashes[idx]EIP-4844opens in a new tab
4ABLOBBASEFEE2.block.blobbasefee当前区块的 blob 基本费用 (EIP-7516opens in a new tab)
4B-4F无效
50POP2_anon.从堆栈顶部移除一项并丢弃
51MLOAD3*opens in a new tabostmem[ost:ost+32]从内存偏移量 ost 处读取字
52MSTORE3*opens in a new tabost, val.mem[ost:ost+32] := val向内存写入一个字
53MSTORE83*opens in a new tabost, val.mem[ost] := val && 0xFF向内存写入单个字节
54SLOADA6opens in a new tabkeystorage[key]从存储中读取字
55SSTOREA7opens in a new tabkey, 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-1153opens in a new tab)
5DTSTORE100key, val.tstorage[key] := val向瞬时存储中写入字 (EIP-1153opens in a new tab)
5EMCOPY3+3*words+A0opens in a new tabdstOst, ost, len.mem[dstOst] := mem[ost:ost+len]将内存从一个区域复制到另一个区域 (EIP-5656opens 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
A0LOG0A8opens in a new tabost, len.LOG0(memory[ost:ost+len-1])
A1LOG1A8opens in a new tabost, len, topic0.LOG1(memory[ost:ost+len-1], topic0)
A2LOG2A8opens in a new tabost, len, topic0, topic1.LOG2(memory[ost:ost+len-1], topic0, topic1)
A3LOG3A8opens in a new tabost, len, topic0, topic1, topic2.LOG3(memory[ost:ost+len-1], topic0, topic1, topic2)
A4LOG4A8opens in a new tabost, len, topic0, topic1, topic2, topic3.LOG4(memory[ost:ost+len-1], topic0, topic1, topic2, topic3)
A5-EF无效
F0CREATEA9opens in a new tabval, ost, lenaddraddr = keccak256(rlp([address(this), this.nonce]))
F1CALLAAopens in a new tab燃料, addr, val, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
F2CALLCODEAAopens 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 tabost, len.return mem[ost:ost+len-1]
F4DELEGATECALLAAopens in a new tab燃料, addr, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
F5CREATE2A9opens in a new tabval, ost, len, saltaddraddr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:]
F6-F9无效
FASTATICCALLAAopens in a new tab燃料, addr, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
FB-FC无效
FDREVERT0*opens in a new tabost, len.revert(mem[ost:ost+len-1])
FEINVALIDAFopens in a new tab指定的无效操作码 - EIP-141opens in a new tab
FFSELFDESTRUCTABopens in a new tabaddr.将所有 ETH 发送到 addr;如果在创建合约的同一交易中执行,它会销毁该合约

本文对你有帮助吗?