EEVM.SystemContracts.BlockHashes (eevm v0.1.0)

Copy Markdown View Source

EIP-2935 historical block hashes contract (activated in Prague).

Installs the canonical EIP-2935 deployed bytecode at 0x0000F90827F1C53a10cb7A02335B175320002935 and drives it through the normal executor. At the start of every block the execution layer performs a system call (caller = SYSTEM_ADDRESS 0xff..fe) with the parent block hash as 32-byte calldata; the contract stashes the hash in a ring buffer of HISTORY_SERVE_WINDOW = 8191 slots keyed by the parent block number. User contracts read past hashes back via a plain CALL with a 32-byte block number.

API

  • install/1 — place the deployed bytecode into a Database.
  • commit/3 — perform the block-start system call that stores a hash. Takes the current block (number N) plus the hash of its parent (block N-1); the contract does the N - 1 subtraction internally before writing to storage[(N - 1) mod 8191]. Returns {:ok, db} on success and {:error, reason, db} on execution failure.
  • lookup/2 — read a stored hash directly from storage. A slot that has never been written returns :not_found (distinguishable from a genuinely-stored zero only if the caller knows the slot was written).

Summary

Functions

Canonical deployment address of the historical block hashes contract.

Executes the block-start system call that records parent_block_hash as the hash for block block.number - 1.

Returns the exact deployed bytecode that the EIP specifies.

Ring-buffer size for historical block hashes (constant, 8191).

Installs the historical block hashes contract into db at the canonical address.

Installs only if EIP-2935 is active in the given hardfork config. Callers setting up a pre-Prague genesis get a no-op.

Reads the hash stored at block_number mod 8191, as the storage word, directly from the contract's storage slot.

Caller address used by the execution layer's block-start system call.

Functions

address()

@spec address() :: non_neg_integer()

Canonical deployment address of the historical block hashes contract.

commit(db, block, parent_block_hash)

@spec commit(EEVM.Database.t(), EEVM.BlockEnv.t(), <<_::256>>) ::
  {:ok, EEVM.Database.t()} | {:error, atom(), EEVM.Database.t()}

Executes the block-start system call that records parent_block_hash as the hash for block block.number - 1.

Uses SYSTEM_ADDRESS as the caller so the contract takes its storage branch, and runs the code deployed at the contract address; when none is deployed yet (the fork's first blocks, before the deployment transaction), the call is a no-op. Returns the updated database, or an error tuple if the call reverted (which should never happen with the canonical bytecode, but we surface it rather than swallow it).

deployed_bytecode()

@spec deployed_bytecode() :: binary()

Returns the exact deployed bytecode that the EIP specifies.

history_serve_window()

@spec history_serve_window() :: pos_integer()

Ring-buffer size for historical block hashes (constant, 8191).

install(db)

@spec install(EEVM.Database.t()) :: EEVM.Database.t()

Installs the historical block hashes contract into db at the canonical address.

Idempotent — re-installing leaves storage untouched and only ensures the code is present.

install_if_enabled(db, config)

@spec install_if_enabled(EEVM.Database.t(), EEVM.HardforkConfig.t()) ::
  EEVM.Database.t()

Installs only if EIP-2935 is active in the given hardfork config. Callers setting up a pre-Prague genesis get a no-op.

lookup(db, block_number)

@spec lookup(EEVM.Database.t(), non_neg_integer()) ::
  {:ok, non_neg_integer()} | :not_found

Reads the hash stored at block_number mod 8191, as the storage word, directly from the contract's storage slot.

This is a raw storage read: it deliberately does NOT enforce any range checks, so callers with no view of the current block number can still inspect the ring buffer. A slot that has never been written returns :not_found (distinguishable from a genuinely-stored zero only if the caller knows the slot was written).

system_address()

@spec system_address() :: non_neg_integer()

Caller address used by the execution layer's block-start system call.