EVM용 연산 부호
페이지 마지막 업데이트됨: 2025년 9월 11일
개요
wolflo/evm-opcodes (opens in a new tab)에 있는 EVM 참조 페이지의 업데이트된 버전입니다. 또한 옐로페이퍼 (opens in a new tab), 젤로페이퍼 (opens in a new tab), geth (opens in a new tab) 구현을 참고했습니다. 이 문서는 이해하기 쉬운 참조 자료로 만들어졌지만, 특별히 엄격하지는 않습니다. 정확성을 확인하고 모든 에지 케이스를 인지하고 싶다면, 젤로페이퍼 또는 클라이언트 구현을 사용하는 것이 좋습니다.
상호작용형 참조 자료를 찾고 계신가요? evm.codes (opens in a new tab)를 확인해 보세요.
동적 가스 비용이 드는 연산에 대해서는 gas.md (opens in a new tab)를 참조하세요.
💡 빠른 팁: 전체 라인을 보려면, 데스크톱에서 [shift] + 스크롤을 사용하여 가로로 스크롤하세요.
| 스택 | 이름 | 가스 | 초기 스택 | 결과 스택 | 메모리 / 스토리지 | 참고사항 | |
|---|---|---|---|---|---|---|---|
| 00 | STOP | 0 | 실행 중단 | ||||
| 01 | ADD | 3 | a, b | a + b | (u)int256 덧셈(모듈로 2**256) | ||
| 02 | MUL | 5 | a, b | a * b | (u)int256 곱셈(모듈로 2**256) | ||
| 03 | SUB | 3 | a, b | a - b | (u)int256 뺄셈(모듈로 2**256) | ||
| 04 | DIV | 5 | a, b | a // b | uint256 나눗셈 | ||
| 05 | SDIV | 5 | a, b | a // b | int256 나눗셈 | ||
| 06 | MOD | 5 | a, b | a % b | uint256 모듈로 | ||
| 07 | SMOD | 5 | a, b | a % b | int256 모듈로 | ||
| 08 | ADDMOD | 8 | a, b, N | (a + b) % N | (u)int256 덧셈(모듈로 N) | ||
| 09 | MULMOD | 8 | a, b, N | (a * b) % N | (u)int256 곱셈(모듈로 N) | ||
| 0A | EXP | A1 (opens in a new tab) | a, b | a ** b | uint256 거듭제곱(모듈로 2**256) | ||
| 0B | SIGNEXTEND | 5 | b, x | SIGNEXTEND(x, b) | x를 (b+1) 바이트에서 32바이트로 부호 확장 (opens in a new tab) | ||
| 0C-0F | 유효하지 않음 | ||||||
| 10 | LT | 3 | a, b | a < b | uint256 보다 작음 | ||
| 11 | GT | 3 | a, b | a > b | uint256 보다 큼 | ||
| 12 | SLT | 3 | a, b | a < b | int256 보다 작음 | ||
| 13 | SGT | 3 | a, b | a > b | int256 보다 큼 | ||
| 14 | EQ | 3 | a, b | a == b | (u)int256 같음 | ||
| 15 | ISZERO | 3 | a | a == 0 | (u)int256이 0인지 확인 | ||
| 16 | AND | 3 | a, b | a && b | 비트 AND | ||
| 17 | OR | 3 | a, b | `a \ | \ | b` | |
| 18 | XOR | 3 | a, b | a ^ b | 비트 XOR | ||
| 19 | NOT | 3 | a | ~a | 비트 NOT | ||
| 1A | BYTE | 3 | i, x | (x >> (248 - i * 8)) && 0xFF | 왼쪽부터 (u)int256 x의 i번째 바이트 | ||
| 1B | SHL | 3 | shift, val | val << shift | 왼쪽으로 시프트 | ||
| 1C | SHR | 3 | shift, val | val >> shift | 논리적 오른쪽 시프트 | ||
| 1D | SAR | 3 | shift, val | val >> shift | 산술적 오른쪽 시프트 | ||
| 1E-1F | 유효하지 않음 | ||||||
| 20 | KECCAK256 | A2 (opens in a new tab) | ost, len | keccak256(mem[ost:ost+len-1]) | keccak256 | ||
| 21-2F | 유효하지 않음 | ||||||
| 30 | ADDRESS | 2 | . | address(this) | 실행 중인 컨트랙트의 주소 | ||
| 31 | BALANCE | A5 (opens in a new tab) | addr | addr.balance | 잔액, wei 단위 | ||
| 32 | ORIGIN | 2 | . | tx.origin | 트랜잭션을 시작한 주소 | ||
| 33 | CALLER | 2 | . | msg.sender | 메시지 발신자의 주소 | ||
| 34 | CALLVALUE | 2 | . | msg.value | 메시지 값, wei 단위 | ||
| 35 | CALLDATALOAD | 3 | idx | msg.data[idx:idx+32] | 인덱스 idx에서 메시지 데이터 워드 읽기 | ||
| 36 | CALLDATASIZE | 2 | . | len(msg.data) | 메시지 데이터의 길이, 바이트 단위 | ||
| 37 | CALLDATACOPY | A3 (opens in a new tab) | dstOst, ost, len | . | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | 메시지 데이터 복사 | |
| 38 | CODESIZE | 2 | . | len(this.code) | 실행 중인 컨트랙트 코드의 길이, 바이트 단위 | ||
| 39 | CODECOPY | A3 (opens in a new tab) | dstOst, ost, len | . | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | 실행 중인 컨트랙트의 바이트코드 복사 | |
| 3A | GASPRICE | 2 | . | tx.gasprice | 트랜잭션의 가스 가격, 가스 단위당 wei ** (opens in a new tab) | ||
| 3B | EXTCODESIZE | A5 (opens in a new tab) | addr | len(addr.code) | addr에 있는 코드 크기, 바이트 단위 | ||
| 3C | EXTCODECOPY | A4 (opens in a new tab) | addr, dstOst, ost, len | . | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | addr에서 코드 복사 | |
| 3D | RETURNDATASIZE | 2 | . | size | 마지막 외부 호출에서 반환된 데이터의 크기, 바이트 단위 | ||
| 3E | RETURNDATACOPY | A3 (opens in a new tab) | dstOst, ost, len | . | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | 마지막 외부 호출에서 반환된 데이터 복사 | |
| 3F | EXTCODEHASH | A5 (opens in a new tab) | addr | hash | 해시 = addr이 존재하는 경우 ? keccak256(addr.code) : 0 | ||
| 40 | BLOCKHASH | 20 | blockNum | blockHash(blockNum) | |||
| 41 | COINBASE | 2 | . | block.coinbase | 현재 블록 제안자의 주소 | ||
| 42 | TIMESTAMP | 2 | . | block.timestamp | 현재 블록의 타임스탬프 | ||
| 43 | NUMBER | 2 | . | block.number | 현재 블록의 번호 | ||
| 44 | PREVRANDAO | 2 | . | 랜덤성 비콘 | 랜덤성 비콘 | ||
| 45 | GASLIMIT | 2 | . | block.gaslimit | 현재 블록의 가스 한도 | ||
| 46 | CHAINID | 2 | . | chain_id | 현재 체인 ID (opens in a new tab)를 스택에 푸시 | ||
| 47 | SELFBALANCE | 5 | . | address(this).balance | 실행 중인 컨트랙트의 잔액, wei 단위 | ||
| 48 | BASEFEE | 2 | . | block.basefee | 현재 블록의 기본 수수료 | ||
| 49 | BLOBHASH | 3 | idx | tx.blob_versioned_hashes[idx] | EIP-4844 (opens in a new tab) | ||
| 4A | BLOBBASEFEE | 2 | . | block.blobbasefee | 현재 블록의 블롭 기본 수수료 (EIP-7516 (opens in a new tab)) | ||
| 4B-4F | 유효하지 않음 | ||||||
| 50 | POP | 2 | _anon | . | 스택 맨 위에서 항목을 제거하고 폐기 | ||
| 51 | MLOAD | 3* (opens in a new tab) | ost | mem[ost:ost+32] | 오프셋 ost의 메모리에서 워드 읽기 | ||
| 52 | MSTORE | 3* (opens in a new tab) | ost, val | . | mem[ost:ost+32] := val | 메모리에 워드 쓰기 | |
| 53 | MSTORE8 | 3* (opens in a new tab) | ost, val | . | mem[ost] := val && 0xFF | 메모리에 단일 바이트 쓰기 | |
| 54 | SLOAD | A6 (opens in a new tab) | key | storage[key] | 스토리지에서 워드 읽기 | ||
| 55 | SSTORE | A7 (opens in a new tab) | key, val | . | storage[key] := val | 스토리지에 워드 쓰기 | |
| 56 | JUMP | 8 | dst | . | $pc := dst는 dst가 유효한 점프 대상인 경우에만 pc가 할당됨을 표시 | ||
| 57 | JUMPI | 10 | dst, condition | . | $pc := condition ? dst : $pc + 1` | ||
| 58 | PC | 2 | . | $pc | 프로그램 카운터 | ||
| 59 | MSIZE | 2 | . | len(mem) | 현재 실행 컨텍스트의 메모리 크기, 바이트 단위 | ||
| 5A | GAS | 2 | . | gasRemaining | |||
| 5B | JUMPDEST | 1 | 유효한 점프 대상 표시 | 유효한 점프 대상(예: 푸시 데이터 내부에 있지 않은 점프 대상) | |||
| 5C | TLOAD | 100 | key | tstorage[key] | 임시 스토리지에서 워드 읽기 (EIP-1153 (opens in a new tab)) | ||
| 5D | TSTORE | 100 | key, val | . | tstorage[key] := val | 임시 스토리지에 워드 쓰기 (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] | 한 영역에서 다른 영역으로 메모리 복사 (EIP-5656 (opens in a new tab)) | |
| 5F | PUSH0 | 2 | . | uint8 | 상수 값 0을 스택에 푸시 | ||
| 60 | PUSH1 | 3 | . | uint8 | 1바이트 값을 스택에 푸시 | ||
| 61 | PUSH2 | 3 | . | uint16 | 2바이트 값을 스택에 푸시 | ||
| 62 | PUSH3 | 3 | . | uint24 | 3바이트 값을 스택에 푸시 | ||
| 63 | PUSH4 | 3 | . | uint32 | 4바이트 값을 스택에 푸시 | ||
| 64 | PUSH5 | 3 | . | uint40 | 5바이트 값을 스택에 푸시 | ||
| 65 | PUSH6 | 3 | . | uint48 | 6바이트 값을 스택에 푸시 | ||
| 66 | PUSH7 | 3 | . | uint56 | 7바이트 값을 스택에 푸시 | ||
| 67 | PUSH8 | 3 | . | uint64 | 8바이트 값을 스택에 푸시 | ||
| 68 | PUSH9 | 3 | . | uint72 | 9바이트 값을 스택에 푸시 | ||
| 69 | PUSH10 | 3 | . | uint80 | 10바이트 값을 스택에 푸시 | ||
| 6A | PUSH11 | 3 | . | uint88 | 11바이트 값을 스택에 푸시 | ||
| 6B | PUSH12 | 3 | . | uint96 | 12바이트 값을 스택에 푸시 | ||
| 6C | PUSH13 | 3 | . | uint104 | 13바이트 값을 스택에 푸시 | ||
| 6D | PUSH14 | 3 | . | uint112 | 14바이트 값을 스택에 푸시 | ||
| 6E | PUSH15 | 3 | . | uint120 | 15바이트 값을 스택에 푸시 | ||
| 6F | PUSH16 | 3 | . | uint128 | 16바이트 값을 스택에 푸시 | ||
| 70 | PUSH17 | 3 | . | uint136 | 17바이트 값을 스택에 푸시 | ||
| 71 | PUSH18 | 3 | . | uint144 | 18바이트 값을 스택에 푸시 | ||
| 72 | PUSH19 | 3 | . | uint152 | 19바이트 값을 스택에 푸시 | ||
| 73 | PUSH20 | 3 | . | uint160 | 20바이트 값을 스택에 푸시 | ||
| 74 | PUSH21 | 3 | . | uint168 | 21바이트 값을 스택에 푸시 | ||
| 75 | PUSH22 | 3 | . | uint176 | 22바이트 값을 스택에 푸시 | ||
| 76 | PUSH23 | 3 | . | uint184 | 23바이트 값을 스택에 푸시 | ||
| 77 | PUSH24 | 3 | . | uint192 | 24바이트 값을 스택에 푸시 | ||
| 78 | PUSH25 | 3 | . | uint200 | 25바이트 값을 스택에 푸시 | ||
| 79 | PUSH26 | 3 | . | uint208 | 26바이트 값을 스택에 푸시 | ||
| 7A | PUSH27 | 3 | . | uint216 | 27바이트 값을 스택에 푸시 | ||
| 7B | PUSH28 | 3 | . | uint224 | 28바이트 값을 스택에 푸시 | ||
| 7C | PUSH29 | 3 | . | uint232 | 29바이트 값을 스택에 푸시 | ||
| 7D | PUSH30 | 3 | . | uint240 | 30바이트 값을 스택에 푸시 | ||
| 7E | PUSH31 | 3 | . | uint248 | 31바이트 값을 스택에 푸시 | ||
| 7F | PUSH32 | 3 | . | uint256 | 32바이트 값을 스택에 푸시 | ||
| 80 | DUP1 | 3 | a | a, a | 스택의 첫 번째 값 복제 | ||
| 81 | DUP2 | 3 | _, a | a, _, a | 스택의 두 번째 값 복제 | ||
| 82 | DUP3 | 3 | _, _, a | a, _, _, a | 스택의 세 번째 값 복제 | ||
| 83 | DUP4 | 3 | _, _, _, a | a, _, _, _, a | 스택의 네 번째 값 복제 | ||
| 84 | DUP5 | 3 | ..., a | a, ..., a | 스택의 다섯 번째 값 복제 | ||
| 85 | DUP6 | 3 | ..., a | a, ..., a | 스택의 여섯 번째 값 복제 | ||
| 86 | DUP7 | 3 | ..., a | a, ..., a | 스택의 일곱 번째 값 복제 | ||
| 87 | DUP8 | 3 | ..., a | a, ..., a | 스택의 여덟 번째 값 복제 | ||
| 88 | DUP9 | 3 | ..., a | a, ..., a | 스택의 아홉 번째 값 복제 | ||
| 89 | DUP10 | 3 | ..., a | a, ..., a | 스택의 열 번째 값 복제 | ||
| 8A | DUP11 | 3 | ..., a | a, ..., a | 스택의 열한 번째 값 복제 | ||
| 8B | DUP12 | 3 | ..., a | a, ..., a | 스택의 열두 번째 값 복제 | ||
| 8C | DUP13 | 3 | ..., a | a, ..., a | 스택의 열세 번째 값 복제 | ||
| 8D | DUP14 | 3 | ..., a | a, ..., a | 스택의 열네 번째 값 복제 | ||
| 8E | DUP15 | 3 | ..., a | a, ..., a | 스택의 열다섯 번째 값 복제 | ||
| 8F | DUP16 | 3 | ..., a | a, ..., a | 스택의 열여섯 번째 값 복제 | ||
| 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 | 유효하지 않음 | ||||||
| F0 | CREATE | A9 (opens in a new tab) | val, ost, len | addr | addr = keccak256(rlp([주소(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 | DELEGATECALL과 동일하지만, 원래의 msg.sender와 msg.value는 전파하지 않습니다. | |
| F3 | RETURN | 0* (opens in a new tab) | ost, len | . | 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 ++ 주소(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | ||
| F6-F9 | 유효하지 않음 | ||||||
| FA | STATICCALL | AA (opens in a new tab) | gas, addr, argOst, argLen, retOst, retLen | success | mem[retOst:retOst+retLen-1] := returndata | ||
| FB-FC | 유효하지 않음 | ||||||
| FD | REVERT | 0* (opens in a new tab) | ost, len | . | revert(mem[ost:ost+len-1]) | ||
| FE | INVALID | AF (opens in a new tab) | 지정된 유효하지 않은 연산 부호 - EIP-141 (opens in a new tab) | ||||
| FF | SELFDESTRUCT | AB (opens in a new tab) | addr | . | 모든 ETH를 addr로 보냅니다. 컨트랙트가 생성된 것과 동일한 트랜잭션에서 실행되면 해당 컨트랙트를 파기합니다. |