Mã lệnh cho EVM
Lần cập nhật trang lần cuối: 11 tháng 9, 2025
Tổng quan
Đây là phiên bản cập nhật của trang tham khảo EVM tại wolflo/evm-opcodes (opens in a new tab). Cũng được lấy từ Sách Vàng (opens in a new tab), Sách Jello (opens in a new tab), và bản triển khai geth (opens in a new tab). Điều này được tạo ra với mục đích trở thành một tài liệu tham khảo dễ tiếp cận, nhưng nó không quá chặt chẽ. Nếu bạn muốn đảm bảo tính chính xác và hiểu rõ mọi trường hợp đặc biệt, thì nên tham khảo sách Jello hoặc trực tiếp xem cách Client được triển khai.
Bạn đang tìm một bản tham khảo có tương tác? Xem tại evm.codes (opens in a new tab).
Về các hoạt động với chi phí gas động, xem gas.md (opens in a new tab).
💡 Mẹo nhanh: Để xem toàn bộ các dòng, hãy sử dụng [shift] + scroll để cuộn ngang trên máy tính.
| Stack | Họ tên | Gas | Stack ban đầu | Kết quả Stack | Bộ nhớ/ lưu trữ | Lưu ý | |
|---|---|---|---|---|---|---|---|
| 00 | STOP | 0 | dừng thực thi | ||||
| 01 | ADD | 3 | a, b | a + b | phép cộng (u)int256 modulo 2**256 | ||
| 02 | MUL | 5 | a, b | a * b | phép nhân (u)int256 modulo 2**256 | ||
| 03 | SUB | 3 | a, b | a - b | phép trừ (u)int256 modulo 2**256 | ||
| 04 | DIV | 5 | a, b | a // b | phép chia uint256 | ||
| 05 | SDIV | 5 | a, b | a // b | phép chia int256 | ||
| 06 | MOD | 5 | a, b | a % b | uint256 modulo | ||
| 07 | SMOD | 5 | a, b | a % b | int256 modulo | ||
| 08 | ADDMOD | 8 | a, b, N | (a + b) % N | phép cộng (u)int256 modulo N | ||
| 09 | MULMOD | 8 | a, b, N | (a * b) % N | phép nhân (u)int256 modulo N | ||
| 0A | EXP | A1 (opens in a new tab) | a, b | a ** b | phép lũy thừa uint256 modulo 2**256 | ||
| 0B | SIGNEXTEND | 5 | b, x | SIGNEXTEND(x, b) | mở rộng dấu (opens in a new tab) x từ (b+1) byte lên 32 byte | ||
| 0C-0F | không hợp lệ | ||||||
| 10 | LT | 3 | a, b | a < b | uint256 nhỏ hơn | ||
| 11 | GT | 3 | a, b | a > b | uint256 lớn hơn | ||
| 12 | SLT | 3 | a, b | a < b | int256 nhỏ hơn | ||
| 13 | SGT | 3 | a, b | a > b | int256 lớn hơn | ||
| 14 | EQ | 3 | a, b | a == b | (u)int256 bằng nhau | ||
| 15 | ISZERO | 3 | a | a == 0 | (u)int256 bằng không | ||
| 16 | AND | 3 | a, b | a && b | phép AND bit | ||
| 17 | OR | 3 | a, b | `a \ | \ | b` | |
| 18 | XOR | 3 | a, b | a ^ b | phép XOR bit | ||
| 19 | NOT | 3 | a | ~a | phép NOT bit | ||
| 1A | BYTE | 3 | i, x | (x >> (248 - i * 8)) && 0xFF | byte thứ i của (u)int256 x, từ bên trái | ||
| 1B | SHL | 3 | shift, val | val << shift | dịch trái | ||
| 1C | SHR | 3 | shift, val | val >> shift | dịch phải logic | ||
| 1D | DUP5 | 3 | shift, val | val >> shift | dịch phải số học | ||
| 1E-1F | không hợp lệ | ||||||
| 20 | KECCAK256 | A2 (opens in a new tab) | ost, len | keccak256(mem[ost:ost+len-1]) | keccak256 | ||
| 21-2F | không hợp lệ | ||||||
| 30 | ADDRESS | 2 | . | address(this) | địa chỉ của hợp đồng đang thực thi | ||
| 31 | BALANCE | A5 (opens in a new tab) | addr | addr.balance | số dư, tính bằng wei | ||
| 32 | ORIGIN | 2 | . | tx.origin | địa chỉ đã khởi tạo tx | ||
| 33 | CALLER | 2 | . | msg.sender | địa chỉ của người gửi msg | ||
| 34 | CALLVALUE | 2 | . | msg.value | giá trị msg, tính bằng wei | ||
| 35 | CALLDATALOAD | 3 | idx | msg.data[idx:idx+32] | đọc một từ từ dữ liệu msg tại chỉ mục idx | ||
| 36 | CALLDATASIZE | 2 | . | len(msg.data) | độ dài dữ liệu msg, tính bằng byte | ||
| 37 | CALLDATACOPY | A3 (opens in a new tab) | dstOst, ost, len | . | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | sao chép dữ liệu msg | |
| 38 | CODESIZE | 2 | . | len(this.code) | độ dài mã của hợp đồng đang thực thi, tính bằng byte | ||
| 39 | CODECOPY | A3 (opens in a new tab) | dstOst, ost, len | . | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | sao chép chỉ thị biên dịch của hợp đồng đang thực thi | |
| 3A | GASPRICE | 2 | . | tx.gasprice | giá gas của tx, tính bằng wei trên mỗi đơn vị gas ** (opens in a new tab) | ||
| 3B | EXTCODESIZE | A5 (opens in a new tab) | addr | len(addr.code) | kích thước mã tại addr, tính bằng byte | ||
| 3C | EXTCODECOPY | A4 (opens in a new tab) | addr, dstOst, ost, len | . | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | sao chép mã từ addr | |
| 3D | RETURNDATASIZE | 2 | . | size | kích thước dữ liệu trả về từ lệnh gọi bên ngoài cuối cùng, tính bằng byte | ||
| 3E | RETURNDATACOPY | A3 (opens in a new tab) | dstOst, ost, len | . | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | sao chép dữ liệu trả về từ lệnh gọi bên ngoài cuối cùng | |
| 3F | EXTCODEHASH | A5 (opens in a new tab) | addr | hash | hash = addr.exists ? keccak256(addr.code) : 0 | ||
| 40 | BLOCKHASH | 20 | blockNum | blockHash(blockNum) | |||
| 41 | COINBASE | 2 | . | block.coinbase | địa chỉ của người đề xuất khối hiện tại | ||
| 42 | TIMESTAMP | 2 | . | block.timestamp | dấu thời gian của khối hiện tại | ||
| 43 | NUMBER | 2 | . | block.number | số của khối hiện tại | ||
| 44 | PREVRANDAO | 2 | . | randomness beacon | mốc báo hiệu ngẫu nhiên | ||
| 45 | GASLIMIT | 2 | . | block.gaslimit | giới hạn gas của khối hiện tại | ||
| 46 | CHAINID | 2 | . | chain_id | đẩy ID chuỗi (opens in a new tab) hiện tại vào ngăn xếp | ||
| 47 | SELFBALANCE | 5 | . | address(this).balance | số dư của hợp đồng đang thực thi, tính bằng wei | ||
| 48 | BASEFEE | 2 | . | block.basefee | phí cơ bản của khối hiện tại | ||
| 49 | BLOBHASH | 3 | idx | tx.blob_versioned_hashes[idx] | EIP-4844 (opens in a new tab) | ||
| 4A | BLOBBASEFEE | 2 | . | block.blobbasefee | phí cơ bản của blob của khối hiện tại (EIP-7516 (opens in a new tab)) | ||
| 4B-4F | không hợp lệ | ||||||
| 50 | POP | 2 | _anon | . | xóa mục khỏi đầu ngăn xếp và loại bỏ nó | ||
| 51 | MLOAD | 3* (opens in a new tab) | ost | mem[ost:ost+32] | đọc một từ từ bộ nhớ tại độ lệch ost | ||
| 52 | MSTORE | 3* (opens in a new tab) | ost, val | . | mem[ost:ost+32] := val | ghi một từ vào bộ nhớ | |
| 53 | MSTORE8 | 3* (opens in a new tab) | ost, val | . | mem[ost] := val && 0xFF | ghi một byte vào bộ nhớ | |
| 54 | SLOAD | A6 (opens in a new tab) | key | storage[key] | đọc một từ từ bộ nhớ lưu trữ | ||
| 55 | SSTORE | A7 (opens in a new tab) | key, val | . | storage[key] := val | ghi một từ vào bộ nhớ lưu trữ | |
| 56 | JUMP | 8 | dst | . | $pc := dst đánh dấu rằng pc chỉ được gán nếu dst là một jumpdest hợp lệ | ||
| 57 | JUMPI | 10 | dst, condition | . | $pc := condition ? dst : $pc + 1` | ||
| 58 | PC | 2 | . | $pc | bộ đếm chương trình | ||
| 59 | MSIZE | 2 | . | len(mem) | kích thước bộ nhớ trong ngữ cảnh thực thi hiện tại, tính bằng byte | ||
| 5A | GAS | 2 | . | gasRemaining | |||
| 5B | JUMPDEST | 1 | đánh dấu đích nhảy hợp lệ | một đích nhảy hợp lệ, ví dụ một đích nhảy không nằm trong dữ liệu đẩy | |||
| 5C | TLOAD | 100 | key | tstorage[key] | đọc một từ từ lưu trữ tạm thời (EIP-1153 (opens in a new tab)) | ||
| 5D | TSTORE | 100 | key, val | . | tstorage[key] := val | ghi một từ vào lưu trữ tạm thời (EIP-1153 (opens in a new tab)) | |
| 5E | MCOPY | 3+3*words+A0 (opens in a new tab) | dstOst, ost, len | . | mem[dstOst] := mem[ost:ost+len] | sao chép bộ nhớ từ vùng này sang vùng khác (EIP-5656 (opens in a new tab)) | |
| 5F | PUSH0 | 2 | . | uint8 | đẩy giá trị hằng số 0 vào ngăn xếp | ||
| 60 | PUSH1 | 3 | . | uint8 | đẩy giá trị 1-byte vào ngăn xếp | ||
| 61 | PUSH2 | 3 | . | uint16 | đẩy giá trị 2-byte vào ngăn xếp | ||
| 62 | PUSH3 | 3 | . | uint24 | đẩy giá trị 3-byte vào ngăn xếp | ||
| 63 | PUSH4 | 3 | . | uint32 | đẩy giá trị 4-byte vào ngăn xếp | ||
| 64 | PUSH5 | 3 | . | uint40 | đẩy giá trị 5-byte vào ngăn xếp | ||
| 65 | PUSH6 | 3 | . | uint48 | đẩy giá trị 6-byte vào ngăn xếp | ||
| 66 | PUSH7 | 3 | . | uint56 | đẩy giá trị 7-byte vào ngăn xếp | ||
| 67 | PUSH8 | 3 | . | uint64 | đẩy giá trị 8-byte vào ngăn xếp | ||
| 68 | PUSH9 | 3 | . | uint72 | đẩy giá trị 9-byte vào ngăn xếp | ||
| 69 | PUSH10 | 3 | . | uint80 | đẩy giá trị 10-byte vào ngăn xếp | ||
| 6A | PUSH11 | 3 | . | uint88 | đẩy giá trị 11-byte vào ngăn xếp | ||
| 6B | PUSH12 | 3 | . | uint96 | đẩy giá trị 12-byte vào ngăn xếp | ||
| 6C | PUSH13 | 3 | . | uint104 | đẩy giá trị 13-byte vào ngăn xếp | ||
| 6D | PUSH14 | 3 | . | uint112 | đẩy giá trị 14-byte vào ngăn xếp | ||
| 6E | PUSH15 | 3 | . | uint120 | đẩy giá trị 15-byte vào ngăn xếp | ||
| 6F | PUSH16 | 3 | . | uint128 | đẩy giá trị 16-byte vào ngăn xếp | ||
| 70 | PUSH17 | 3 | . | uint136 | đẩy giá trị 17-byte vào ngăn xếp | ||
| 71 | PUSH18 | 3 | . | uint144 | đẩy giá trị 18-byte vào ngăn xếp | ||
| 72 | PUSH19 | 3 | . | uint152 | đẩy giá trị 19-byte vào ngăn xếp | ||
| 73 | PUSH20 | 3 | . | uint160 | đẩy giá trị 20-byte vào ngăn xếp | ||
| 74 | PUSH21 | 3 | . | uint168 | đẩy giá trị 21-byte vào ngăn xếp | ||
| 75 | PUSH22 | 3 | . | uint176 | đẩy giá trị 22-byte vào ngăn xếp | ||
| 76 | PUSH23 | 3 | . | uint184 | đẩy giá trị 23-byte vào ngăn xếp | ||
| 77 | PUSH24 | 3 | . | uint192 | đẩy giá trị 24-byte vào ngăn xếp | ||
| 78 | PUSH25 | 3 | . | uint200 | đẩy giá trị 25-byte vào ngăn xếp | ||
| 79 | PUSH26 | 3 | . | uint208 | đẩy giá trị 26-byte vào ngăn xếp | ||
| 7A | PUSH27 | 3 | . | uint216 | đẩy giá trị 27-byte vào ngăn xếp | ||
| 7B | PUSH28 | 3 | . | uint224 | đẩy giá trị 28-byte vào ngăn xếp | ||
| 7C | PUSH29 | 3 | . | uint232 | đẩy giá trị 29-byte vào ngăn xếp | ||
| 7D | PUSH30 | 3 | . | uint240 | đẩy giá trị 30-byte vào ngăn xếp | ||
| 7E | PUSH31 | 3 | . | uint248 | đẩy giá trị 31-byte vào ngăn xếp | ||
| 7F | PUSH32 | 3 | . | uint256 | đẩy giá trị 32-byte vào ngăn xếp | ||
| 80 | DUP1 | 3 | a | a, a | sao chép giá trị thứ 1 trên ngăn xếp | ||
| 81 | DUP2 | 3 | _, a | a, _, a | sao chép giá trị thứ 2 trên ngăn xếp | ||
| 82 | DUP3 | 3 | _, _, a | a, _, _, a | sao chép giá trị thứ 3 trên ngăn xếp | ||
| 83 | DUP4 | 3 | _, _, _, a | a, _, _, _, a | sao chép giá trị thứ 4 trên ngăn xếp | ||
| 84 | DUP5 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 5 trên ngăn xếp | ||
| 85 | DUP6 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 6 trên ngăn xếp | ||
| 86 | DUP7 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 7 trên ngăn xếp | ||
| 87 | DUP8 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 8 trên ngăn xếp | ||
| 88 | DUP9 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 9 trên ngăn xếp | ||
| 89 | DUP10 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 10 trên ngăn xếp | ||
| 8A | DUP11 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 11 trên ngăn xếp | ||
| 8B | DUP12 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 12 trên ngăn xếp | ||
| 8C | DUP13 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 13 trên ngăn xếp | ||
| 8D | DUP14 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 14 trên ngăn xếp | ||
| 8E | DUP15 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 15 trên ngăn xếp | ||
| 8F | DUP16 | 3 | ..., a | a, ..., a | sao chép giá trị thứ 16 trên ngăn xếp | ||
| 90 | SWAP1 | 3 | a, b | b, a | |||
| 91 | SWAP2 | 3 | a, _, b | b, _, a | |||
| 92 | SWAP3 | 3 | a, _, _, b | b, _, _, a | |||
| 93 | SWAP4 | 3 | a, _, _, _, b | b, _, _, _, a | |||
| 94 | SWAP5 | 3 | a, ..., b | b, ..., a | |||
| 95 | SWAP6 | 3 | a, ..., b | b, ..., a | |||
| 96 | SWAP7 | 3 | a, ..., b | b, ..., a | |||
| 97 | SWAP8 | 3 | a, ..., b | b, ..., a | |||
| 98 | SWAP9 | 3 | a, ..., b | b, ..., a | |||
| 99 | SWAP10 | 3 | a, ..., b | b, ..., a | |||
| 9A | SWAP11 | 3 | a, ..., b | b, ..., a | |||
| 9B | SWAP12 | 3 | a, ..., b | b, ..., a | |||
| 9C | SWAP13 | 3 | a, ..., b | b, ..., a | |||
| 9D | SWAP14 | 3 | a, ..., b | b, ..., a | |||
| 9E | SWAP15 | 3 | a, ..., b | b, ..., a | |||
| 9F | SWAP16 | 3 | a, ..., b | b, ..., a | |||
| A0 | LOG0 | A8 (opens in a new tab) | ost, len | . | LOG0(memory[ost:ost+len-1]) | ||
| A1 | LOG1 | A8 (opens in a new tab) | ost, len, topic0 | . | LOG1(memory[ost:ost+len-1], topic0) | ||
| A2 | LOG2 | A8 (opens in a new tab) | ost, len, topic0, topic1 | . | LOG2(memory[ost:ost+len-1], topic0, topic1) | ||
| A3 | LOG3 | A8 (opens in a new tab) | ost, len, topic0, topic1, topic2 | . | LOG3(memory[ost:ost+len-1], topic0, topic1, topic2) | ||
| A4 | LOG4 | A8 (opens in a new tab) | ost, len, topic0, topic1, topic2, topic3 | . | LOG4(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) | ||
| A5-EF | không hợp lệ | ||||||
| F0 | CREATE | A9 (opens in a new tab) | val, ost, len | addr | addr = keccak256(rlp([address(this), this.nonce])) | ||
| F1 | CALL | AA (opens in a new tab) | gas, addr, val, argOst, argLen, retOst, retLen | success | mem[retOst:retOst+retLen-1] := returndata | ||
| F2 | CALLCODE | AA (opens in a new tab) | gas, addr, val, argOst, argLen, retOst, retLen | success | mem[retOst:retOst+retLen-1] = returndata | giống như DELEGATECALL, nhưng không truyền msg.sender và msg.value gốc | |
| F3 | RETURN | 0* (opens in a new tab) | ost, len | . | return mem[ost:ost+len-1] | ||
| F4 | DELEGATECALL | AA (opens in a new tab) | gas, addr, argOst, argLen, retOst, retLen | success | mem[retOst:retOst+retLen-1] := returndata | ||
| F5 | CREATE2 | A9 (opens in a new tab) | val, ost, len, salt | addr | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | ||
| F6-F9 | không hợp lệ | ||||||
| FA | STATICCALL | AA (opens in a new tab) | gas, addr, argOst, argLen, retOst, retLen | success | mem[retOst:retOst+retLen-1] := returndata | ||
| FB-FC | không hợp lệ | ||||||
| FD | REVERT | 0* (opens in a new tab) | ost, len | . | revert(mem[ost:ost+len-1]) | ||
| FE | INVALID | AF (opens in a new tab) | opcode không hợp lệ được chỉ định - EIP-141 (opens in a new tab) | ||||
| FF | SELFDESTRUCT | AB (opens in a new tab) | addr | . | gửi tất cả ETH đến addr; nếu được thực thi trong cùng một giao dịch mà một hợp đồng được tạo thì nó sẽ phá hủy hợp đồng đó |