A comprehensive reference for the Ethereum Virtual Machine (EVM), compiled from evm.codes, ethereum.org, and wolflo/evm-opcodes. This page holds the detailed notes: full opcode tables with gas and stack behavior, gas cost formulas, precompiled contracts, hardfork changes, and additional resources. For a short primer and the opcode threat index, see Threat Models.


Table of Contents

  1. What Is the EVM?
  2. Execution Environment
  3. Opcode Reference Table
  4. Opcode Categories
  5. Gas Costs
  6. Dynamic Gas Cost Formulas
  7. Precompiled Contracts
  8. Additional Resources

What Is the EVM?

The Ethereum Virtual Machine is a stack-based computer responsible for executing smart contract instructions. Key properties:

  • Stack-based: All instructions take parameters from the stack (except PUSHx, which reads from code).
  • Deterministic: The same input always produces the same output across all nodes.
  • 256-bit word size: All stack items are 32 bytes (256 bits).
  • Max stack depth: 1024 items.
  • Opcodes: Values 0x00 through 0xFF (0-255), each with a mnemonic name. The EVM currently implements ~141 opcodes, 65 of which are parametric variants (PUSHn, DUPn, SWAPn, LOGn).

Smart Contract Execution

A smart contract is a sequence of opcodes. The EVM reads and executes each instruction sequentially, except:

  • JUMP / JUMPI: Alter the program counter to a JUMPDEST.
  • REVERT: Halts execution, reverts state, refunds unused gas.
  • STOP / RETURN: Halts execution normally.

If an instruction cannot execute (insufficient gas, stack underflow), execution reverts and all state changes are rolled back.


Execution Environment

When the EVM executes a contract, it creates a call context with the following data regions:

RegionPersistenceAccess OpcodesDescription
CodePermanent (on-chain)CODESIZE, CODECOPY, EXTCODESIZE, EXTCODECOPYImmutable contract bytecode
StackPer call contextPUSHn, POP, DUPn, SWAPnLIFO list of 32-byte elements, max 1024 items
MemoryPer call contextMLOAD, MSTORE, MSTORE8, MSIZEByte-addressable, initialized to zero, volatile
StoragePermanent (on-chain)SLOAD, SSTORE32-byte key → 32-byte value mapping, per contract
Transient StoragePer transactionTLOAD, TSTORELike storage but cleared after each transaction (EIP-1153)
CalldataPer call contextCALLDATALOAD, CALLDATASIZE, CALLDATACOPYImmutable input data for the call
Return DataPer call contextRETURNDATASIZE, RETURNDATACOPYData returned from the last external call

Program Counter (PC)

The PC tracks the next instruction to execute. It increments by 1 byte per instruction, except:

  • PUSHn skips the next n bytes (its immediate data).
  • JUMP / JUMPI set the PC to a specified JUMPDEST.

Opcode Reference Table

Notation:

  • a, b => a + b means the opcode pops a and b from the stack and pushes the result.
  • . represents “nothing” (no stack input/output).
  • All arithmetic is modulo 2^256. Division by zero returns 0.

0x00-0x0B: Stop & Arithmetic

HexNameGasStackDescription
00STOP0Halt execution
01ADD3a, b a + bAddition modulo 2^256
02MUL5a, b a * bMultiplication modulo 2^256
03SUB3a, b a - bSubtraction modulo 2^256
04DIV5a, b a // bUnsigned integer division
05SDIV5a, b a // bSigned integer division
06MOD5a, b a % bUnsigned modulus
07SMOD5a, b a % bSigned modulus
08ADDMOD8a, b, N (a + b) % NAddition modulo N
09MULMOD8a, b, N (a * b) % NMultiplication modulo N
0AEXPdynamica, b a ** bExponentiation modulo 2^256
0BSIGNEXTEND5b, x SIGNEXTEND(x, b)Sign-extend x from (b+1) bytes to 32 bytes

0x10-0x1D: Comparison & Bitwise Logic

HexNameGasStackDescription
10LT3a, b a < bUnsigned less-than
11GT3a, b a > bUnsigned greater-than
12SLT3a, b a < bSigned less-than
13SGT3a, b a > bSigned greater-than
14EQ3a, b a == bEquality
15ISZERO3a a == 0Is zero
16AND3a, b a & bBitwise AND
17OR3a, b a | bBitwise OR
18XOR3a, b a ^ bBitwise XOR
19NOT3a ~aBitwise NOT
1ABYTE3i, x (x >> (248 - i*8)) & 0xFFExtract byte at position i
1BSHL3shift, val val << shiftShift left
1CSHR3shift, val val >> shiftLogical shift right
1DSAR3shift, val val >> shiftArithmetic shift right

0x20: Cryptographic

HexNameGasStackDescription
20KECCAK256dynamicoffset, length keccak256(mem[offset:offset+length])Compute Keccak-256 hash

0x30-0x3F: Environmental Information

HexNameGasStackDescription
30ADDRESS2. address(this)Address of executing contract
31BALANCEdynamicaddr addr.balanceBalance in wei (warm/cold access)
32ORIGIN2. tx.originTransaction originator address
33CALLER2. msg.senderDirect caller address
34CALLVALUE2. msg.valueValue sent with call, in wei
35CALLDATALOAD3idx msg.data[idx:idx+32]Read 32-byte word from calldata
36CALLDATASIZE2. len(msg.data)Calldata size in bytes
37CALLDATACOPYdynamicdstOst, ost, len .Copy calldata to memory
38CODESIZE2. len(this.code)Size of executing contract code
39CODECOPYdynamicdstOst, ost, len .Copy contract code to memory
3AGASPRICE2. tx.gaspriceGas price of transaction
3BEXTCODESIZEdynamicaddr len(addr.code)Size of external contract code
3CEXTCODECOPYdynamicaddr, dstOst, ost, len .Copy external code to memory
3DRETURNDATASIZE2. sizeSize of last call’s return data
3ERETURNDATACOPYdynamicdstOst, ost, len .Copy return data to memory
3FEXTCODEHASHdynamicaddr hashKeccak-256 of external code

0x40-0x4A: Block Information

HexNameGasStackDescription
40BLOCKHASH20blockNum blockHash(blockNum)Hash of a recent block (last 256)
41COINBASE2. block.coinbaseCurrent block proposer address
42TIMESTAMP2. block.timestampCurrent block timestamp
43NUMBER2. block.numberCurrent block number
44PREVRANDAO2. randomness_beaconRandomness beacon (post-Merge; was DIFFICULTY)
45GASLIMIT2. block.gaslimitCurrent block gas limit
46CHAINID2. chain_idCurrent chain ID (EIP-155)
47SELFBALANCE5. address(this).balanceBalance of executing contract
48BASEFEE2. block.basefeeBase fee of current block (EIP-1559)
49BLOBHASH3idx tx.blob_versioned_hashes[idx]Blob versioned hash (EIP-4844)
4ABLOBBASEFEE2. block.blobbasefeeBlob base fee (EIP-7516)

0x50-0x5F: Stack, Memory, Storage & Flow

HexNameGasStackDescription
50POP2_ .Remove top stack item
51MLOAD3*offset mem[offset:offset+32]Load word from memory
52MSTORE3*offset, val .Store word to memory
53MSTORE83*offset, val .Store single byte to memory
54SLOADdynamickey storage[key]Load word from storage
55SSTOREdynamickey, val .Store word to storage
56JUMP8dst .Set PC to dst (must be JUMPDEST)
57JUMPI10dst, cond .Conditional jump
58PC2. $pcCurrent program counter
59MSIZE2. len(mem)Size of active memory in bytes
5AGAS2. gasRemainingRemaining gas
5BJUMPDEST1Mark valid jump destination
5CTLOAD100key tstorage[key]Load from transient storage (EIP-1153)
5DTSTORE100key, val .Store to transient storage (EIP-1153)
5EMCOPYdynamicdst, src, len .Copy memory area (EIP-5656)
5FPUSH02. 0Push zero onto stack (EIP-3855)

* Plus memory expansion cost if applicable.

0x60-0x7F: Push Operations

All PUSH opcodes cost 3 gas and push 1-32 bytes from the code onto the stack.

HexNameBytes Pushed
60PUSH11 byte (uint8)
61PUSH22 bytes (uint16)
62PUSH33 bytes (uint24)
7FPUSH3232 bytes (uint256)

0x80-0x8F: Duplication Operations

All DUP opcodes cost 3 gas. DUPn clones the nth stack item to the top.

HexNameStack Effect
80DUP1a a, a
81DUP2_, a a, _, a
8FDUP16..., a a, ..., a

0x90-0x9F: Swap Operations

All SWAP opcodes cost 3 gas. SWAPn swaps the top stack item with the (n+1)th item.

HexNameStack Effect
90SWAP1a, b b, a
91SWAP2a, _, b b, _, a
9FSWAP16a, ..., b b, ..., a

0xA0-0xA4: Logging

HexNameGasStackDescription
A0LOG0dynamicoffset, length .Log with 0 topics
A1LOG1dynamicoffset, length, topic0 .Log with 1 topic
A2LOG2dynamicoffset, length, topic0, topic1 .Log with 2 topics
A3LOG3dynamicoffset, length, topic0, topic1, topic2 .Log with 3 topics
A4LOG4dynamicoffset, length, topic0, topic1, topic2, topic3 .Log with 4 topics

0xF0-0xFF: System Operations

HexNameGasStackDescription
F0CREATEdynamicval, offset, length addrCreate new contract; addr = keccak256(rlp([sender, nonce]))
F1CALLdynamicgas, addr, val, argOst, argLen, retOst, retLen successCall another contract
F2CALLCODEdynamicgas, addr, val, argOst, argLen, retOst, retLen successLike DELEGATECALL but doesn’t propagate msg.sender/value
F3RETURN0*offset, length .Return data from memory
F4DELEGATECALLdynamicgas, addr, argOst, argLen, retOst, retLen successCall with caller’s context
F5CREATE2dynamicval, offset, length, salt addrCreate with deterministic address
FASTATICCALLdynamicgas, addr, argOst, argLen, retOst, retLen successRead-only call (no state modification)
FDREVERT0*offset, length .Revert with return data, refund unused gas
FEINVALIDall gasDesignated invalid opcode; consumes all gas
FFSELFDESTRUCTdynamicaddr .Mark contract for destruction, send ETH to addr

* Plus memory expansion cost if applicable.


Opcode Categories

CategoryOpcodesPurpose
ArithmeticADD, MUL, SUB, DIV, SDIV, MOD, SMOD, ADDMOD, MULMOD, EXP, SIGNEXTENDMath operations on 256-bit integers
ComparisonLT, GT, SLT, SGT, EQ, ISZEROBoolean comparisons returning 0 or 1
BitwiseAND, OR, XOR, NOT, BYTE, SHL, SHR, SARBit manipulation
CryptographicKECCAK256Hashing
EnvironmentalADDRESS, BALANCE, ORIGIN, CALLER, CALLVALUE, CALLDATALOAD, CALLDATASIZE, CALLDATACOPY, CODESIZE, CODECOPY, GASPRICE, EXTCODESIZE, EXTCODECOPY, RETURNDATASIZE, RETURNDATACOPY, EXTCODEHASHContext about the call and external contracts
BlockBLOCKHASH, COINBASE, TIMESTAMP, NUMBER, PREVRANDAO, GASLIMIT, CHAINID, SELFBALANCE, BASEFEE, BLOBHASH, BLOBBASEFEECurrent block/chain info
Stack/Memory/StoragePOP, MLOAD, MSTORE, MSTORE8, SLOAD, SSTORE, TLOAD, TSTORE, MCOPY, PUSH0, PUSH1-32, DUP1-16, SWAP1-16Data manipulation
Flow ControlJUMP, JUMPI, PC, MSIZE, GAS, JUMPDEST, STOPExecution flow
LoggingLOG0-LOG4Emit event logs
SystemCREATE, CALL, CALLCODE, RETURN, DELEGATECALL, CREATE2, STATICCALL, REVERT, INVALID, SELFDESTRUCTContract interaction and lifecycle

Gas Costs

Intrinsic Gas

Every transaction pays gas before any opcode execution:

ComponentCost
Base transaction21,000 gas
Contract creation (tx.to == null)+32,000 gas
Calldata zero byte4 gas/byte
Calldata non-zero byte16 gas/byte (64 before Istanbul)

Memory Expansion

Memory grows dynamically. Cost is quadratic in size, computed as:

memory_size_word = (memory_byte_size + 31) / 32
memory_cost = (memory_size_word ** 2) / 512 + (3 * memory_size_word)
expansion_cost = new_memory_cost - previous_memory_cost

Memory cost is linear up to ~724 bytes, then grows quadratically. Opcodes that trigger expansion include: MLOAD, MSTORE, MSTORE8, RETURN, REVERT, CALLDATACOPY, CODECOPY, EXTCODECOPY, RETURNDATACOPY, CREATE, CALL, etc. A zero-length access does not trigger expansion.

Access Sets (EIP-2929, Post-Berlin)

Two transaction-wide sets track “touched” addresses and storage slots:

Access TypeWarm CostCold Cost
Address (BALANCE, EXTCODESIZE, etc.)100 gas2,600 gas
Storage slot (SLOAD)100 gas2,100 gas

Addresses initialized as warm at transaction start:

  • tx.sender and tx.to
  • All precompiled contract addresses (post-Berlin)
  • The COINBASE address (post-Shanghai)

EIP-2930 allows transactions to pre-populate access sets: 2,400 gas per address, 1,900 gas per (address, slot) pair.

Gas Refunds

Only SSTORE can trigger refunds (post-London/EIP-3529). Maximum refund is capped at 1/5 of total transaction gas consumed. Refunds are applied at transaction end; they do not prevent out-of-gas failures during execution.


Dynamic Gas Cost Formulas

EXP (0x0A)

gas_cost = 10 + 50 * byte_len_exponent

Where byte_len_exponent is the number of bytes in the exponent.

KECCAK256 (0x20)

data_size_words = (data_size + 31) / 32
gas_cost = 30 + 6 * data_size_words + mem_expansion_cost

COPY Operations (CALLDATACOPY, CODECOPY, RETURNDATACOPY)

data_size_words = (data_size + 31) / 32
gas_cost = 3 + 3 * data_size_words + mem_expansion_cost

EXTCODECOPY

data_size_words = (data_size + 31) / 32
gas_cost = access_cost + 3 * data_size_words + mem_expansion_cost

Where access_cost = 100 (warm) or 2,600 (cold).

SLOAD

gas_cost = 100   (warm)
gas_cost = 2100  (cold)

SSTORE

The most complex gas calculation, depending on current value, new value, original value, and warm/cold access:

ScenarioGas CostRefund
Cold access surcharge+2,100
No-op (new == current)+100
Clean slot: 0 → nonzero+20,000
Clean slot: nonzero → different nonzero+2,900
Clean slot: nonzero → 0+2,900+4,800
Dirty slot (any change)+100varies
Dirty slot reset to original nonzero+100+2,800
Dirty slot reset to original zero+100+19,900

Minimum 2,300 gas must remain to execute SSTORE (backward compatibility).

LOG Operations

gas_cost = 375 + 375 * num_topics + 8 * data_size + mem_expansion_cost

CREATE

gas_cost = 32000 + mem_expansion_cost + code_deposit_cost
code_deposit_cost = 200 * returned_code_size

CREATE2

data_size_words = (init_code_size + 31) / 32
gas_cost = 32000 + 6 * data_size_words + mem_expansion_cost + code_deposit_cost

CALL Operations

base_gas = access_cost + mem_expansion_cost
ConditionAdditional Cost
Sending value (call_value > 0)+9,000 gas
Creating new account (CALL only, value > 0 to empty address)+25,000 gas

Gas forwarded with call:

remaining_gas = available_gas - base_gas
all_but_one_64th = remaining_gas - (remaining_gas / 64)
gas_sent_with_call = min(requested_gas, all_but_one_64th)

If call_value > 0, a 2,300 gas stipend is added to the gas sent (but not to the cost).

SELFDESTRUCT

gas_cost = 5000
+ 25000  (if balance > 0 AND target is empty)
+ 2600   (if target is cold)

Precompiled Contracts

Precompiled contracts are special functions bundled into the EVM at fixed addresses. They are called like regular contracts via CALL, STATICCALL, etc. After Berlin, all precompile addresses are always warm.

For all precompiles: if input is shorter than expected, it is zero-padded at the end. Surplus bytes are ignored.

AddressNameEIPGasDescription
0x01ecRecover3,000ECDSA public key recovery from signature
0x02SHA2-25660 + 12 * wordsSHA-256 hash
0x03RIPEMD-160600 + 120 * wordsRIPEMD-160 hash
0x04Identity15 + 3 * wordsReturns input unchanged (data copy)
0x05ModExpEIP-198dynamicModular exponentiation: base^exp % mod
0x06ecAddEIP-196150Point addition on alt_bn128 elliptic curve
0x07ecMulEIP-1966,000Scalar multiplication on alt_bn128
0x08ecPairingEIP-19745,000 + 34,000 * pairsBilinear pairing check on alt_bn128
0x09blake2fEIP-152per roundsBLAKE2b compression function F

Precompile Details

ecRecover (0x01): Recovers the signer address from an ECDSA signature. Input: 128 bytes (hash, v, r, s). Output: 32 bytes (left-padded address).

SHA2-256 (0x02): Standard SHA-256 hash. Input: arbitrary bytes. Output: 32 bytes.

RIPEMD-160 (0x03): RIPEMD-160 hash. Input: arbitrary bytes. Output: 32 bytes (left-padded to 32 bytes from 20-byte hash).

Identity (0x04): Returns input data unchanged. Useful for copying memory via CALL.

ModExp (0x05): Computes base^exponent % modulus for arbitrary-precision integers. Gas cost depends on input sizes and exponent magnitude.

ecAdd (0x06): Adds two points on the BN256 (alt_bn128) elliptic curve. Used in zk-SNARK verification.

ecMul (0x07): Multiplies a point on BN256 by a scalar. Used in zk-SNARK verification.

ecPairing (0x08): Checks a bilinear pairing equation on BN256. Fundamental for zk-SNARK proof verification. Input: k pairs of (G1 point, G2 point). Returns 1 if pairing check passes, 0 otherwise.

blake2f (0x09): Runs the BLAKE2b compression function F for a given number of rounds. Enables BLAKE2b interoperability for cross-chain verification (e.g., Zcash).


Key Hardfork Changes

HardforkEIPsNotable Changes
IstanbulEIP-1884, EIP-2028Calldata cost reduced from 64 to 16 gas/byte (non-zero). SLOAD increased to 800 gas.
BerlinEIP-2929, EIP-2930Warm/cold access pricing. Optional access lists.
LondonEIP-3529, EIP-1559Gas refund cap reduced to 1/5. SELFDESTRUCT no longer provides refund. Base fee mechanism.
ShanghaiEIP-3651COINBASE address is warm at start of transaction.
CancunEIP-1153, EIP-4844, EIP-5656, EIP-7516Transient storage (TLOAD/TSTORE). Blob transactions (BLOBHASH). MCOPY opcode. BLOBBASEFEE.

Additional Resources


*Sources: evm.codes, ethereum.org/opcodes, wolflo/evm-opcodes.