본문으로 건너뛰기
Change page

EVM 연산 코드

개요

이 문서는 wolflo/evm-opcodes (새 탭에서 열림)의 EVM 참조 페이지를 업데이트한 버전입니다. 또한 황서 (새 탭에서 열림), Jello Paper (새 탭에서 열림), 그리고 고 이더리움 (geth) (새 탭에서 열림) 구현체에서도 내용을 발췌했습니다. 이 문서는 접근하기 쉬운 참조 자료로 작성되었지만, 특별히 엄밀하지는 않습니다. 정확성을 확신하고 모든 엣지 케이스를 파악하고 싶다면, Jello Paper나 클라이언트 구현체를 참고하는 것이 좋습니다.

대화형 참조 자료를 찾고 계신가요? evm.codes (새 탭에서 열림)를 확인해 보세요.

동적 가스 비용이 있는 연산에 대해서는 gas.md (새 탭에서 열림)를 참조하세요.

💡 간단한 팁: 전체 줄을 보려면 데스크톱에서 [shift] + 스크롤을 사용하여 가로로 스크롤하세요.

스택이름가스초기 스택결과 스택메모리 / 스토리지참고
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 (새 탭에서 열림)a, ba ** buint256 거듭제곱 모듈로 2**256
0BSIGNEXTEND5b, xSIGNEXTEND(x, b)(b+1) 바이트에서 32 바이트로 x부호 확장(sign extend) (새 탭에서 열림)
0C-0F유효하지 않음
10LT3a, ba < buint256 미만
11GT3a, ba > buint256 초과
12SLT3a, ba < bint256 미만
13SGT3a, ba > bint256 초과
14EQ3a, ba == b(u)int256 같음
15ISZERO3aa == 0(u)int256 0인지 여부
16AND3a, ba && b비트 AND
17OR3a, ba || b비트 OR
18XOR3a, ba ^ b비트 XOR
19NOT3a~a비트 NOT
1ABYTE3i, x(x >> (248 - i * 8)) && 0xFF왼쪽에서부터 (u)int256 xi번째 바이트
1BSHL3shift, valval << shift왼쪽 시프트
1CSHR3shift, valval >> shift논리적 오른쪽 시프트
1DSAR3shift, valval >> shift산술적 오른쪽 시프트
1E-1F유효하지 않음
20KECCAK256A2 (새 탭에서 열림)ost, lenkeccak256(mem[ost:ost+len-1])keccak256
21-2F유효하지 않음
30ADDRESS2.address(this)실행 중인 컨트랙트의 주소
31BALANCEA5 (새 탭에서 열림)addraddr.balance잔액 (Wei 단위)
32ORIGIN2.tx.origin트랜잭션을 시작한 주소
33CALLER2.msg.sendermsg 발신자의 주소
34CALLVALUE2.msg.valuemsg 값 (Wei 단위)
35CALLDATALOAD3idxmsg.data[idx:idx+32]인덱스 idx의 msg 데이터에서 워드 읽기
36CALLDATASIZE2.len(msg.data)msg 데이터의 길이 (바이트 단위)
37CALLDATACOPYA3 (새 탭에서 열림)dstOst, ost, len.mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1]msg 데이터 복사
38CODESIZE2.len(this.code)실행 중인 컨트랙트 코드의 길이 (바이트 단위)
39CODECOPYA3 (새 탭에서 열림)dstOst, ost, len.mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1]
3AGASPRICE2.tx.gasprice트랜잭션의 가스 가격 (단위 가스당 Wei) ** (새 탭에서 열림)
3BEXTCODESIZEA5 (새 탭에서 열림)addrlen(addr.code)addr에 있는 코드의 크기 (바이트 단위)
3CEXTCODECOPYA4 (새 탭에서 열림)addr, dstOst, ost, len.mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1]addr에서 코드 복사
3DRETURNDATASIZE2.size마지막 외부 호출에서 반환된 데이터의 크기 (바이트 단위)
3ERETURNDATACOPYA3 (새 탭에서 열림)dstOst, ost, len.mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1]마지막 외부 호출에서 반환된 데이터 복사
3FEXTCODEHASHA5 (새 탭에서 열림)addrhashhash = addr.exists ? keccak256(addr.code) : 0
40BLOCKHASH20blockNumblockHash(blockNum)
41COINBASE2.block.coinbase현재 블록 제안자의 주소
42TIMESTAMP2.block.timestamp현재 블록의 타임스탬프
43NUMBER2.block.number현재 블록의 번호
44PREVRANDAO2.randomness beacon무작위성 비콘
45GASLIMIT2.block.gaslimit현재 블록의 가스 한도
46CHAINID2.chain_id현재 체인 ID (새 탭에서 열림)를 스택에 푸시
47SELFBALANCE5.address(this).balance실행 중인 컨트랙트의 잔액 (Wei 단위)
48BASEFEE2.block.basefee현재 블록의 기본 수수료
49BLOBHASH3idxtx.blob_versioned_hashes[idx]EIP-4844 (새 탭에서 열림)
4ABLOBBASEFEE2.block.blobbasefee현재 블록의 블롭 기본 수수료 (EIP-7516 (새 탭에서 열림))
4B-4F유효하지 않음
50POP2_anon.스택의 맨 위에서 항목을 제거하고 버림
51MLOAD3* (새 탭에서 열림)ostmem[ost:ost+32]오프셋 ost의 메모리에서 워드 읽기
52MSTORE3* (새 탭에서 열림)ost, val.mem[ost:ost+32] := val메모리에 워드 쓰기
53MSTORE83* (새 탭에서 열림)ost, val.mem[ost] := val && 0xFF메모리에 단일 바이트 쓰기
54SLOADA6 (새 탭에서 열림)keystorage[key]스토리지에서 워드 읽기
55SSTOREA7 (새 탭에서 열림)key, val.storage[key] := val스토리지에 워드 쓰기
56JUMP8dst.$pc := dst dst가 유효한 jumpdest인 경우에만 pc가 할당됨을 표시
57JUMPI10dst, condition.$pc := condition ? dst : $pc + 1
58PC2.$pc프로그램 카운터
59MSIZE2.len(mem)현재 실행 컨텍스트의 메모리 크기 (바이트 단위)
5AGAS2.gasRemaining
5BJUMPDEST1유효한 점프 목적지 표시유효한 점프 목적지 (예: 푸시 데이터 내부에 있지 않은 점프 목적지)
5CTLOAD100keytstorage[key]임시 스토리지에서 워드 읽기 (EIP-1153 (새 탭에서 열림))
5DTSTORE100key, val.tstorage[key] := val임시 스토리지에 워드 쓰기 (EIP-1153 (새 탭에서 열림))
5EMCOPY3+3*words+A0 (새 탭에서 열림)dstOst, ost, len.mem[dstOst] := mem[ost:ost+len]한 영역에서 다른 영역으로 메모리 복사 (EIP-5656 (새 탭에서 열림))
5FPUSH02.uint8상수 값 0을 스택에 푸시
60PUSH13.uint81바이트 값을 스택에 푸시
61PUSH23.uint162바이트 값을 스택에 푸시
62PUSH33.uint243바이트 값을 스택에 푸시
63PUSH43.uint324바이트 값을 스택에 푸시
64PUSH53.uint405바이트 값을 스택에 푸시
65PUSH63.uint486바이트 값을 스택에 푸시
66PUSH73.uint567바이트 값을 스택에 푸시
67PUSH83.uint648바이트 값을 스택에 푸시
68PUSH93.uint729바이트 값을 스택에 푸시
69PUSH103.uint8010바이트 값을 스택에 푸시
6APUSH113.uint8811바이트 값을 스택에 푸시
6BPUSH123.uint9612바이트 값을 스택에 푸시
6CPUSH133.uint10413바이트 값을 스택에 푸시
6DPUSH143.uint11214바이트 값을 스택에 푸시
6EPUSH153.uint12015바이트 값을 스택에 푸시
6FPUSH163.uint12816바이트 값을 스택에 푸시
70PUSH173.uint13617바이트 값을 스택에 푸시
71PUSH183.uint14418바이트 값을 스택에 푸시
72PUSH193.uint15219바이트 값을 스택에 푸시
73PUSH203.uint16020바이트 값을 스택에 푸시
74PUSH213.uint16821바이트 값을 스택에 푸시
75PUSH223.uint17622바이트 값을 스택에 푸시
76PUSH233.uint18423바이트 값을 스택에 푸시
77PUSH243.uint19224바이트 값을 스택에 푸시
78PUSH253.uint20025바이트 값을 스택에 푸시
79PUSH263.uint20826바이트 값을 스택에 푸시
7APUSH273.uint21627바이트 값을 스택에 푸시
7BPUSH283.uint22428바이트 값을 스택에 푸시
7CPUSH293.uint23229바이트 값을 스택에 푸시
7DPUSH303.uint24030바이트 값을 스택에 푸시
7EPUSH313.uint24831바이트 값을 스택에 푸시
7FPUSH323.uint25632바이트 값을 스택에 푸시
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 (새 탭에서 열림)ost, len.LOG0(memory[ost:ost+len-1])
A1LOG1A8 (새 탭에서 열림)ost, len, topic0.LOG1(memory[ost:ost+len-1], topic0)
A2LOG2A8 (새 탭에서 열림)ost, len, topic0, topic1.LOG2(memory[ost:ost+len-1], topic0, topic1)
A3LOG3A8 (새 탭에서 열림)ost, len, topic0, topic1, topic2.LOG3(memory[ost:ost+len-1], topic0, topic1, topic2)
A4LOG4A8 (새 탭에서 열림)ost, len, topic0, topic1, topic2, topic3.LOG4(memory[ost:ost+len-1], topic0, topic1, topic2, topic3)
A5-EF유효하지 않음
F0CREATEA9 (새 탭에서 열림)val, ost, lenaddraddr = keccak256(rlp([address(this), this.nonce]))
F1CALLAA (새 탭에서 열림)gas, addr, val, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
F2CALLCODEAA (새 탭에서 열림)gas, addr, val, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] = returndataDELEGATECALL과 동일하지만, 원래의 msg.sender와 msg.value를 전달하지 않음
F3RETURN0* (새 탭에서 열림)ost, len.return mem[ost:ost+len-1]
F4DELEGATECALLAA (새 탭에서 열림)gas, addr, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
F5CREATE2A9 (새 탭에서 열림)val, ost, len, saltaddraddr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:]
F6-F9유효하지 않음
FASTATICCALLAA (새 탭에서 열림)gas, addr, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
FB-FC유효하지 않음
FDREVERT0* (새 탭에서 열림)ost, len.revert(mem[ost:ost+len-1])
FEINVALIDAF (새 탭에서 열림)지정된 유효하지 않은 연산 코드 - EIP-141 (새 탭에서 열림)
FFSELFDESTRUCTAB (새 탭에서 열림)addr.모든 ETH를 addr로 전송; 컨트랙트가 생성된 것과 동일한 트랜잭션에서 실행되는 경우 컨트랙트를 파기함