# `EEVM.Block.Header`
[🔗](https://github.com/mw2000/eevm/blob/v0.1.0/lib/eevm/block/header.ex#L1)

Ethereum block header — the consensus-critical metadata for a block, with
its canonical RLP codec (`encode/1`, `decode/1`), its hash
(`compute_hash/1`), and the EIP-1559 base fee a child must carry
(`calc_base_fee_per_gas/1`). Validation lives in `EEVM.Block.HeaderValidator`.

### Fields

| Field | Description |
|-------|-------------|
| `parent_hash` | Keccak hash of the parent header |
| `ommers_hash` | Keccak hash of the RLP ommers list (the empty-list hash post-Merge) |
| `coinbase` | Address of the block producer (fee recipient) |
| `state_root` | Post-execution world-state MPT root |
| `transactions_root` | MPT root of `{rlp(index) => encoded transaction}` |
| `receipts_root` | MPT root of `{rlp(index) => encoded receipt}` |
| `logs_bloom` | 256-byte bloom summarising every log in the block |
| `difficulty` | Proof-of-work difficulty (always zero post-Merge) |
| `number` | Block number (height on the chain) |
| `gas_limit` | Maximum cumulative gas the block may consume |
| `gas_used` | Total gas the block's transactions consumed |
| `timestamp` | Block timestamp in seconds since epoch |
| `extra_data` | Arbitrary producer bytes (at most 32 bytes) |
| `prev_randao` | Mix hash; the beacon chain's RANDAO mix post-Merge (PREVRANDAO) |
| `nonce` | 8-byte proof-of-work nonce (all zero post-Merge) |
| `base_fee_per_gas` | EIP-1559 base fee; `nil` before London |
| `withdrawals_root` | EIP-4895 MPT root of the block's withdrawals; `nil` before Shanghai |
| `blob_gas_used` | EIP-4844 blob gas consumed by the block; `nil` before Cancun |
| `excess_blob_gas` | EIP-4844 running excess blob gas; `nil` before Cancun |
| `parent_beacon_block_root` | EIP-4788 beacon root of the parent slot, a 32-byte binary (an integer is deprecated); `nil` before Cancun |
| `requests_hash` | EIP-7685 commitment to the block's requests; `nil` before Prague |
| `hash` | Keccak hash of this header. Set by `decode/1`; `compute_hash/1` derives it |

The fork-dependent fields at the end are `nil` when absent, so a header
encodes with exactly the fields it carries and `decode/1` followed by
`encode/1` reproduces the input bytes.

# `t`

```elixir
@type t() :: %EEVM.Block.Header{
  base_fee_per_gas: non_neg_integer() | nil,
  blob_gas_used: non_neg_integer() | nil,
  coinbase: non_neg_integer(),
  difficulty: non_neg_integer(),
  excess_blob_gas: non_neg_integer() | nil,
  extra_data: binary(),
  gas_limit: non_neg_integer(),
  gas_used: non_neg_integer(),
  hash: binary(),
  logs_bloom: binary(),
  nonce: binary(),
  number: non_neg_integer(),
  ommers_hash: binary(),
  parent_beacon_block_root: &lt;&lt;_::256&gt;&gt; | nil,
  parent_hash: binary(),
  prev_randao: non_neg_integer(),
  receipts_root: binary(),
  requests_hash: binary() | nil,
  state_root: binary(),
  timestamp: non_neg_integer(),
  transactions_root: binary(),
  withdrawals_root: binary() | nil
}
```

# `calc_base_fee_per_gas`

```elixir
@spec calc_base_fee_per_gas(t()) :: non_neg_integer()
```

Returns the `base_fee_per_gas` a child of `parent` must carry (EIP-1559):
the parent's base fee moved by at most 1/8 towards its gas use relative to
its gas target (`gas_limit / 2`), rising by at least 1 wei above target.
A parent without a base fee is the last block before London, so its child
is London's first block and carries the initial 1 gwei.

## Example

    iex> parent = EEVM.Block.Header.new(gas_limit: 30_000_000, gas_used: 30_000_000, base_fee_per_gas: 800)
    iex> EEVM.Block.Header.calc_base_fee_per_gas(parent)
    900

# `compute_hash`

```elixir
@spec compute_hash(t()) :: binary()
```

Returns `keccak256(encode(header))`, the hash children reference as
`parent_hash`.

# `decode`

```elixir
@spec decode(binary()) :: {:ok, t()} | {:error, :invalid_block_encoding}
```

Decodes a canonical RLP header and sets `hash` to `keccak256(bytes)`.

Returns `{:error, :invalid_block_encoding}` for malformed RLP, a field of
the wrong size, a non-canonical integer, or an unknown field count.

# `empty_ommers_hash`

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

Returns the ommers hash of a block with no ommers, `keccak256(rlp([]))`,
which every post-Merge header carries.

# `encode`

```elixir
@spec encode(t()) :: binary()
```

Encodes `header` as canonical RLP.

## Example

    iex> header = EEVM.Block.Header.new(number: 1, gas_limit: 30_000_000, base_fee_per_gas: 7)
    iex> {:ok, decoded} = header |> EEVM.Block.Header.encode() |> EEVM.Block.Header.decode()
    iex> {decoded.number, decoded.base_fee_per_gas, decoded.withdrawals_root}
    {1, 7, nil}

# `from_rlp`

```elixir
@spec from_rlp(term()) :: {:ok, t()} | {:error, :invalid_block_encoding}
```

Builds a header from its decoded RLP list (as found inside a block), with
`hash` set to the keccak of the list's encoding.

# `new`

```elixir
@spec new() :: t()
```

Returns a header with default values and no fork-dependent fields.

# `new`

```elixir
@spec new(keyword()) :: t()
```

Returns a header with the given overrides.

## Example

    iex> header = EEVM.Block.Header.new(number: 18_000_000, gas_limit: 30_000_000)
    iex> {header.number, header.gas_limit}
    {18_000_000, 30_000_000}

# `to_rlp`

```elixir
@spec to_rlp(t()) :: [binary()]
```

Returns the RLP list for `header`, as embedded in an encoded block.

Fork-dependent fields are emitted up to the last non-`nil` one, in the
order London, Shanghai, Cancun, Prague define them.

---

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