Skip to content

New Opcodes

EIP-8141 introduces four new opcodes that provide the EVM interface for frame transaction execution and introspection.

APPROVE (0xaa)

The most significant new opcode. APPROVE is the mechanism by which a frame signals that the transaction sender and/or gas payer has been verified.

Stack

PositionValue
top - 0offset — return data memory offset
top - 1length — return data length
top - 2scope — what is being approved

Scope Values

ScopeMeaning
0x0Approve execution — sender authorizes future SENDER mode frames
0x1Approve payment — account commits to paying gas costs
0x2Approve both execution and payment

Behavior

APPROVE works like RETURN (exits the frame successfully) but additionally updates transaction-scoped approval state:

  • Scope 0x0: Sets sender_approved = true. Only valid when frame.target == tx.sender. Cannot be called twice.
  • Scope 0x1: Increments the sender's nonce, collects gas fees from the account, sets payer_approved = true. Requires sender_approved == true first. Cannot be called twice.
  • Scope 0x2: Combines both — sets sender_approved, increments nonce, collects gas, sets payer_approved. Only valid when frame.target == tx.sender. Cannot be called twice.

Constraints

  • ADDRESS must equal frame.target — only the frame's target contract can call APPROVE
  • The approval bits in frame.mode (bits 9-10) must permit the requested scope
  • Any violation results in an exceptional halt or frame revert

TXPARAM (0xb0)

An introspection opcode for accessing transaction metadata. Gas cost: 2.

Stack

PositionValue
top - 0param — which field to read
top - 1in2 — frame index (or must be 0)

Parameters

Transaction-level (in2 must be 0)

paramReturns
0x00Transaction type
0x01nonce
0x02sender
0x03max_priority_fee_per_gas
0x04max_fee_per_gas
0x05max_fee_per_blob_gas
0x06Max cost (worst-case total fee)
0x07len(blob_versioned_hashes)
0x08compute_sig_hash(tx)
0x09len(frames)

Frame-level (in2 = frame index)

paramReturns
0x10Currently executing frame index
0x11target of frame at index
0x12gas_limit of frame at index
0x13mode of frame at index
0x14len(data) of frame at index (0 for VERIFY frames)
0x15status of frame at index (only past frames)

Error Cases

  • Invalid param values: exceptional halt
  • Out-of-bounds frame index: exceptional halt
  • Accessing status of current or future frame: exceptional halt
  • len(data) returns 0 for VERIFY mode frames (data is elided)

FRAMEDATALOAD (0xb1)

Loads a 32-byte word from another frame's data. Gas cost: 3 (matches CALLDATALOAD).

Stack

PositionValue
top - 0offset — byte offset into frame data
top - 1frameIndex — which frame's data to read

Semantics match CALLDATALOAD — reads 32 bytes starting at offset, zero-padding if the offset extends beyond the data length. When targeting a VERIFY frame, the returned data is always zero.

FRAMEDATACOPY (0xb2)

Copies data from another frame into memory. Gas cost matches CALLDATACOPY (fixed cost of 3 + memory expansion + copy cost).

Stack

PositionValue
top - 0memOffset — destination in memory
top - 1dataOffset — byte offset into frame data
top - 2length — bytes to copy
top - 3frameIndex — which frame's data to read

When targeting a VERIFY frame, no data is copied (the region is zero-filled per standard memory expansion).

A Feel Your Protocol project — EIP-8141 reference implementation by the EthereumJS team.