EIP-8079 - Native rollups

Created 2025-11-13
Status Draft
Category Core
Type Standards Track
Authors

Abstract

Expose the state transition function to the execution layer via a new EXECUTE precompile.

Motivation

Today, EVM-equivalent rollups need to implement and maintain complex proof systems just to be able to replicate what Ethereum already provides on L1. Such complexity significantly increases the probability of encountering bugs and prevents projects from getting rid of security councils and from moving to Stage 2. EVM-equivalent projects are not similar enough and lack the proper incentives to benefit from each other efforts, significantly delaying multi-proof systems.

Moreover, to maintain feature parity with Ethereum, rollups need to implement bespoke governance systems that can't be forced to follow Ethereum's governance decisions, and thus are free to arbitrarily diverge from it. Because of this, the best that an EVM-equivalent rollup can do is to provide long exit windows for their users, to protect them from its governance going rogue. No finite (and reasonable) exit window can protect all use-cases, especially those that rely on timelocks (governance, staking contracts, vesting contracts). Longer exit windows protect more use-cases, at the cost of increase un-equivalence time.

This EIP provides a way for rollups to reuse Ethereum's state transition verification infrastructure, and as a consequence massively simplify their infrastructure and upgrade processes. This enables projects to better redirect resources towards user-facing features and products.

Specification

Parameters

<-- TODO --> | Constant | Value | | - | - | | PROOF_TX_TYPE | Bytes1(TBD) | | EXECUTE_PRECOMPILE_ADDRESS | TBD | | ANCHOR_ADDRESS | TBD |

EXECUTE precompile

Add a precompile at EXECUTE_PRECOMPILE_ADDRESS that verifies a state transition function with the provided inputs.

The precompile executes the following logic:

<-- TODO -->

def execute(input: Bytes) -> Bytes:
    """
    Verify a `state_transition(chain: BlockChain, block: Block)`.
    Disable blob transactions and perform anchoring to enable L1->L2 messaging.
    """

    chain = input[...] # TBD
    block = input[...] # TBD
    anchor = input[...] # TBD

    transactions = get_transactions(block)

    # Blob-carrying transactions are not supported
    for tx in map(decode_transaction, transactions):
        if isinstance(tx, BlobTransaction):
            raise ExecuteError

    block_env = get_block_env(chain, block)

    # Perform anchoring
    process_unchecked_system_transaction(
        block_env     =block_env,
        target_address=ANCHOR_ADDRESS,
        data          =anchor
    )

    state_transition(chain, block)

    return Bytes(...) # TBD

Header extension

The current header encoding is extended with a new 64-bit unsigned integer field representing the total amount of native tokens burned in the current block as part of the base fee.

The resulting RLP encoding of the header is therefore:

execution_payload_header_rlp = RLP([
  parent_hash,
  0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347, # ommers hash
  coinbase,
  state_root,
  txs_root,
  receipts_root,
  logs_bloom,
  0, # difficulty
  number,
  gas_limit,
  gas_used,
  timestamp,
  extradata,
  prev_randao,
  0x0000000000000000, # nonce
  base_fee_per_gas,
  withdrawals_root,
  burned_fees
])

The cumulative value of burned_fees can be calculated as follows:

burned_fees = effective_gas_fee - gas_refund_amount - transaction_fee + blob_gas_fee

By making the value available for L1, it is also automatically made available for native rollups too.

Proof-carrying transactions

<-- TODO --> TBD: heavily depends on the ZK L1 design.

Rationale

Programmable "consensus layer"

The EXECUTE precompile allows rollups to define their own inputs and constrained their behaviour through smart contract. For example, in contrast to Ethereum's own consensus layer, a rollup can decide to:

This allows projects to preserve most of their configurations they already benefits from.

Gas tokens

Several rollups implement new transaction types to be able to mint the rollup gas token when depositing funds on L1. We decide not to introduce complexity and instead rely on general L1->L2 messaging to unlock pre-minted tokens, as other existing projects already do. As a consequence, projects are free to decide what type of L1 interaction triggers the release of the rollup gas token, trivially enabling custom gas tokens without the need to modify the EVM behaviour at all.

Anchoring

To support L1->L2 messages, rollups need to be able to "anchor" information from L1 to the L2. Inspired by EIP-4788 and existing implementations, we make use of a system transaction to inject a bytes32 anchor in the rollup state in a predeploy. This anchor can be used to relay L1's state root, a message root, or a rolling hash, or something completely different, based on design preferences.

The trade-off of this approach, compared to some existing ones based on custom transaction types, is that the L2 side of an L1->L2 message cannot have the msg.sender derived from the sender on L1, and therefore L1 access control-based smart contracts need to be adapted when deployed on L2 and used with cross-chain permissions. We believe this trade-off to be acceptable as the same scenario already exists when supporting L2->L1 access controls, as Ethereum is already not natively aware of the L2 sender.

Basefee collection

While Ethereum burns the base fee, most rollups collect it for themselves, which enables opinionated funding models that are not possible on L1. To enable this use-case, and to minimize the code changes, we simply expose the amount of fees burned through the burned_fees block header value. Projects can now decide to ignore the value, burning the L2 base fee too, or credit the amount to some address, allowing for base fee collection from the L1->L2 token escrow.

Re-execution vs ZK proofs

<-- TODO --> TBD

Backwards Compatibility

Existing rollups can more or less easily migrate to being native based on their degree of equivalency, as native rollups do not support custom opcodes, custom precompiles or custom transaction types within the exposed state transition function.

Test Cases

<-- TODO --> TBD

Reference Implementation

<-- TODO --> TBD

Security Considerations

<-- TODO --> TBD

Copyright

Copyright and related rights waived via CC0.