EIP-4788: Beacon block root in the EVM
Expose beacon chain roots in the EVM
|Authors||Alex Stokes (@ralexstokes), Ansgar Dietrichs (@adietrichs), Danny Ryan (@djrtwo)|
Table of Contents
Commit to the hash tree root of each beacon chain block in the corresponding execution payload header.
Store each of these roots in a stateful precompile.
Roots of the beacon chain blocks are cryptographic accumulators that allow proofs of arbitrary consensus state. Exposing these roots inside the EVM allows for trust-minimized access to the consensus layer. This functionality supports a wide variety of use cases that improve trust assumptions of staking pools, restaking constructions, smart contract bridges, MEV mitigations and more.
The high-level idea is that each execution block contains the parent beacon block root. Even in the event of missed slots since the previous block root does not change, we only need a constant amount of space to represent this “oracle” in each execution block. To improve the usability of this oracle, a small history of block roots are stored in a stateful precompile. To bound the amount of storage this construction consumes, a ring buffer is used that mirrors a block root accumulator on the consensus layer.
Block structure and validity
Beginning at the execution timestamp
FORK_TIMESTAMP, execution clients MUST:
- set 32 bytes of the execution block header after the last header field as of
FORK_TIMESTAMPto the 32 byte hash tree root of the parent beacon block.
NOTE: this field is appended to the current block header structure with this EIP so that the size of the header grows after (and including) the
At the start of processing any execution block where
block.timestamp >= FORK_TIMESTAMP (i.e. before processing any transactions),
write the parent beacon root provided in the block header into the storage of the contract at
The root itself is used as a key into the contract’s storage and the timestamp of the header is written as the key’s value. The timestamp (a 64-bit unsigned integer value) is encoded as 32 bytes in big-endian format.
In Python pseudocode:
parent_beacon_block_root = block_header.parent_beacon_block_root timestamp = to_uint256_be(block_header.timestamp) sstore(HISTORY_STORAGE_ADDRESS, parent_beacon_block_root, timestamp)
New stateful precompile
Beginning at the execution timestamp
FORK_TIMESTAMP, the code and storage at
HISTORY_STORAGE_ADDRESS constitute a “stateful” precompile.
Callers of the precompile should provide the
root they are querying encoded as 32 bytes.
Alongside the existing gas for calling the precompile, there is an additional gas cost of
G_beacon_root cost to reflect the implicit
the precompile’s state. The timestamp of the corresponding root is returned as 32 bytes in the caller’s provided return buffer and represents the
64-bit unsigned integer from the header in big-endian format.
root = evm.calldata[:32] timestamp = sload(HISTORY_STORAGE_ADDRESS, root) evm.returndata[:32].set(timestamp)
If there is no timestamp stored at the given root, the opcode follows the existing EVM semantics of
Gas cost of precompile
The suggested gas cost reflects a cold
SLOAD analogous to the operation performed while executing the precompile’s logic.
Why not repurpose
BLOCKHASH opcode could be repurposed to provide the beacon root instead of some execution block hash.
To minimize code change, avoid breaking changes to smart contracts, and simplify deployment to mainnet, this EIP suggests leaving
BLOCKHASH alone and adding a new opcode with the desired semantics.
Beacon block root instead of state root
Block roots are preferred over state roots so there is a constant amount of work to do with each new execution block. Otherwise, skipped slots would require a linear amount of work with each new payload. While skipped slots are quite rare on mainnet, it is best to not add additional load under what would already be nonfavorable conditions.
Use of block root over state root does mean proofs will require a few additional nodes but this cost is negligible (and could be amortized across all consumers, e.g. with a singleton state root contract that caches the proof per slot).
Copyright and related rights waived via CC0.
Please cite this document as:
Alex Stokes (@ralexstokes), Ansgar Dietrichs (@adietrichs), Danny Ryan (@djrtwo), "EIP-4788: Beacon block root in the EVM [DRAFT]," Ethereum Improvement Proposals, no. 4788, February 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-4788.