# `EEVM.SystemContracts.BlockHashes`
[🔗](https://github.com/mw2000/eevm/blob/v0.1.0/lib/eevm/system_contracts/block_hashes.ex#L1)

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).

# `address`

```elixir
@spec address() :: non_neg_integer()
```

Canonical deployment address of the historical block hashes contract.

# `commit`

```elixir
@spec commit(EEVM.Database.t(), EEVM.BlockEnv.t(), &lt;&lt;_::256&gt;&gt;) ::
  {: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`

```elixir
@spec deployed_bytecode() :: binary()
```

Returns the exact deployed bytecode that the EIP specifies.

# `history_serve_window`

```elixir
@spec history_serve_window() :: pos_integer()
```

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

# `install`

```elixir
@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`

```elixir
@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`

```elixir
@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`

```elixir
@spec system_address() :: non_neg_integer()
```

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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
