Skip to main content

Opcodes

All Ethereum opcodes are represented however the opcodes in bold are altered from Ethereum. A short description is on the right hand side but an longer one is denoted below.

The original source of the below chart comes from the Ethereum docs.

StackNameGasInitial StackResulting StackMem / StorageNotes
00STOP0alt execution
01ADD3a, ba + b(u)int256 addition modulo 2**256
02MUL5a, ba * b(u)int256 multiplication modulo 2**256
03SUB3a, ba - b(u)int256 addition modulo 2**256
04DIV5a, ba // buint256 division
05SDIV5a, ba // bint256 division
06MOD5a, ba % buint256 modulus
07SMOD5a, ba % bint256 modulus
08ADDMOD8a, b, N(a + b) % N(u)int256 addition modulo N
09MULMOD8a, b, N(a * b) % N(u)int256 multiplication modulo N
0AEXPA1a, ba ** buint256 exponentiation modulo 2**256
0BSIGNEXTEND5b, xSIGNEXTEND(x, b)sign extend x from (b+1) bytes to 32 bytes
0C-0Finvalid
10LT3a, ba < buint256 less-than
11GT3a, ba > buint256 greater-than
12SLT3a, ba < bint256 less-than
13SGT3a, ba > bint256 greater-than
14EQ3a, ba == b(u)int256 equality
15ISZERO3aa == 0(u)int256 iszero
16AND3a, ba && bbitwise AND
17OR3a, b`a \ \ b`
18XOR3a, ba ^ bbitwise XOR
19NOT3a~abitwise NOT
1ABYTE3i, x(x >> (248 - i * 8)) && 0xFFith byte of (u)int256 x, from the left
1BSHL3shift, valval << shiftshift left
1CSHR3shift, valval >> shiftlogical shift right
1DSAR3shift, valval >> shiftarithmetic shift right
1E-1Finvalid
20SHA3A2ost, lenkeccak256(mem[ost:ost+len-1])keccak256
21-2Finvalid
30ADDRESS2.address(this)address of executing contract
31BALANCEA5addraddr.balancebalance, in wei
32ORIGIN2.tx.originaddress that originated the tx
33CALLER2.msg.senderaddress of msg sender
34CALLVALUE2.msg.valuemsg value, in wei
35CALLDATALOAD3idxmsg.data[idx:idx+32]read word from msg data at index idx
36CALLDATASIZE2.len(msg.data)length of msg data, in bytes
37CALLDATACOPYA3dstOst, ost, len.mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1]copy msg data
38CODESIZE2.len(this.code)length of executing contract's code, in bytes
39CODECOPYA3dstOst, ost, len.mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1]copy executing contract's bytecode
3AGASPRICE2.tx.gaspricegas price of tx, in wei per unit gas **
3BEXTCODESIZEA5addrlen(addr.code)size of code at addr, in bytes
3CEXTCODECOPYA4addr, dstOst, ost, len.mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1]copy code from addr
3DRETURNDATASIZE2.sizesize of returned data from last external call, in bytes
3ERETURNDATACOPYA3dstOst, ost, len.mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1]copy returned data from last external call
3FEXTCODEHASHA5addrhashhash = addr.exists ? keccak256(addr.code) : 0
40BLOCKHASH20blockNumblockHash(blockNum)hash = sha256(0x0, chain_id, evm_account_id, block_height)
41COINBASE2.block.coinbase(2^256-1) 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
42TIMESTAMP2.block.timestamptimestamp of current block
43NUMBER2.block.numbernumber of current block
44DIFFICULTY2.block.difficultyreturns 0
45GASLIMIT2.block.gaslimit(2^256-1) 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
46CHAINID2.chain_idpush current chain id onto stack
47SELFBALANCE5.address(this).balancebalance of executing contract, in wei
48BASEFEE2.block.basefeebase fee of current block
49-4Finvalid
50POP2_anon.remove item from top of stack and discard it
51MLOAD3*ostmem[ost:ost+32]read word from memory at offset ost
52MSTORE3*ost, val.mem[ost:ost+32] := valwrite a word to memory
53MSTORE83*ost, val.mem[ost] := val && 0xFFwrite a single byte to memory
54SLOADA6keystorage[key]read word from storage
55SSTOREA7key, val.storage[key] := valwrite word to storage
56JUMP8dst.$pc := dst mark that pc is only assigned if dst is a valid jumpdest
57JUMPI10dst, condition.$pc := condition ? dst : $pc + 1
58PC2.$pcprogram counter
59MSIZE2.len(mem)size of memory in current execution context, in bytes
5AGAS2.gasRemaining
5BJUMPDEST1mark valid jump destinationa valid jump destination for example a jump destination not inside the push data
5C-5Finvalid
60PUSH13.uint8push 1-byte value onto stack
61PUSH23.uint16push 2-byte value onto stack
62PUSH33.uint24push 3-byte value onto stack
63PUSH43.uint32push 4-byte value onto stack
64PUSH53.uint40push 5-byte value onto stack
65PUSH63.uint48push 6-byte value onto stack
66PUSH73.uint56push 7-byte value onto stack
67PUSH83.uint64push 8-byte value onto stack
68PUSH93.uint72push 9-byte value onto stack
69PUSH103.uint80push 10-byte value onto stack
6APUSH113.uint88push 11-byte value onto stack
6BPUSH123.uint96push 12-byte value onto stack
6CPUSH133.uint104push 13-byte value onto stack
6DPUSH143.uint112push 14-byte value onto stack
6EPUSH153.uint120push 15-byte value onto stack
6FPUSH163.uint128push 16-byte value onto stack
70PUSH173.uint136push 17-byte value onto stack
71PUSH183.uint144push 18-byte value onto stack
72PUSH193.uint152push 19-byte value onto stack
73PUSH203.uint160push 20-byte value onto stack
74PUSH213.uint168push 21-byte value onto stack
75PUSH223.uint176push 22-byte value onto stack
76PUSH233.uint184push 23-byte value onto stack
77PUSH243.uint192push 24-byte value onto stack
78PUSH253.uint200push 25-byte value onto stack
79PUSH263.uint208push 26-byte value onto stack
7APUSH273.uint216push 27-byte value onto stack
7BPUSH283.uint224push 28-byte value onto stack
7CPUSH293.uint232push 29-byte value onto stack
7DPUSH303.uint240push 30-byte value onto stack
7EPUSH313.uint248push 31-byte value onto stack
7FPUSH323.uint256push 32-byte value onto stack
80DUP13aa, aclone 1st value on stack
81DUP23_, aa, _, aclone 2nd value on stack
82DUP33_, _, aa, _, _, aclone 3rd value on stack
83DUP43_, _, _, aa, _, _, _, aclone 4th value on stack
84DUP53..., aa, ..., aclone 5th value on stack
85DUP63..., aa, ..., aclone 6th value on stack
86DUP73..., aa, ..., aclone 7th value on stack
87DUP83..., aa, ..., aclone 8th value on stack
88DUP93..., aa, ..., aclone 9th value on stack
89DUP103..., aa, ..., aclone 10th value on stack
8ADUP113..., aa, ..., aclone 11th value on stack
8BDUP123..., aa, ..., aclone 12th value on stack
8CDUP133..., aa, ..., aclone 13th value on stack
8DDUP143..., aa, ..., aclone 14th value on stack
8EDUP153..., aa, ..., aclone 15th value on stack
8FDUP163..., aa, ..., aclone 16th value on stack
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
A0LOG0A8ost, len.LOG0(memory[ost:ost+len-1])
A1LOG1A8ost, len, topic0.LOG1(memory[ost:ost+len-1], topic0)
A2LOG2A8ost, len, topic0, topic1.LOG1(memory[ost:ost+len-1], topic0, topic1)
A3LOG3A8ost, len, topic0, topic1, topic2.LOG1(memory[ost:ost+len-1], topic0, topic1, topic2)
A4LOG4A8ost, len, topic0, topic1, topic2, topic3.LOG1(memory[ost:ost+len-1], topic0, topic1, topic2, topic3)
A5-EFinvalid
F0CREATEA9val, ost, lenaddraddr = keccak256(rlp([address(this), this.nonce]))
F1CALLAAgas, addr, val, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
F2CALLCODEAAgas, addr, val, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] = returndatasame as DELEGATECALL, but does not propagate original msg.sender and msg.value
F3RETURN0*ost, len.return mem[ost:ost+len-1]
F4DELEGATECALLAAgas, addr, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
F5CREATE2A9val, ost, len, saltaddraddr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:]
F6-F9invalid
FASTATICCALLAAgas, addr, argOst, argLen, retOst, retLensuccessmem[retOst:retOst+retLen-1] := returndata
FB-FCinvalid
FDREVERT0*ost, len.revert(mem[ost:ost+len-1])
FEINVALIDAFdesignated invalid opcode - EIP-141
FFSELFDESTRUCTABaddr.destroy contract and sends all funds to addr

Differences

BLOCKHASH

This opcode currently does not return a real block hash and there currently are no plans to do so due to limitations. However, it does respect the logic that a non-zero value is returned for the most recent 256 blocks (not including the current block). For all other inputs, it returns zero. The non-zero value that is returned is computed based on the block height and properties of the Aurora Engine contract (chain ID and account ID).

Concretely, as of #213, the value returned is:

BLOCKHASH(h: u64) = sha256( 0x00 || chain_id || account_id || h )

where || is byte concatenation, and it is assumed h (a 64-bit number) is converted to bytes in big endian encoding. The leading zero byte in the concatenation is a version byte which may change if a new blockhash scheme is introduced in the future. The chain_id depends on the network the Aurora Engine contract is deployed to ( see networks table). The account_id is the name of the NEAR account where the contract is deployed (see the Engine ID column in the networks table).

COINBASE

This opcode returns the EVM address of the Aurora Engine.

For example, for the Aurora Engine deployment on the aurora account, COINBASE returns 0x4444588443C3a91288c5002483449Aba1054192b.

DIFFICULTY

This opcode always returns zero as there is no difficulty in NEAR or Aurora.

In the future, if and when EIP-4399 is merged in, this would instead return NEAR's provided randomness value.

GASLIMIT

This opcode always returns 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff (2^256-1).