# `EEVM.HardforkConfig`
[🔗](https://github.com/mw2000/eevm/blob/v0.1.0/lib/eevm/hardfork_config.ex#L1)

Hardfork configuration controlling which EIP rules are active during execution.

Internal: callers use `EEVM.Config.new/2`, `EEVM.Config.enabled?/2`, and
`EEVM.Config.hardforks/0`. eevm's own code gates rules with the
`enabled?/2` macro here, which rejects undeclared flags at compile time,
and new flags go in `@eip_activation`.

The `spec_id` atom identifies the target hardfork, and `enabled?/2` answers
whether a given EIP is active under that spec.

Hardfork timeline (oldest → newest):

| Hardfork         | Notable EIPs |
|------------------|--------------|
| `:frontier`      | baseline     |
| `:homestead`     | EIP-2 (contract-creation tx cost), EIP-7 (DELEGATECALL) |
| `:tangerine_whistle` | EIP-150 gas repricing |
| `:spurious_dragon` | EIP-155, EIP-160 (EXP cost), EIP-161, EIP-170 (code size limit) |
| `:byzantium`     | EIP-140 (REVERT), EIP-196/197 (alt_bn128 precompiles), EIP-198 (ModExp precompile), EIP-211 (RETURNDATASIZE/RETURNDATACOPY), EIP-214 (STATICCALL) |
| `:constantinople` | EIP-1014 (CREATE2), EIP-145 (SHL/SHR/SAR), EIP-1052 (EXTCODEHASH) |
| `:istanbul`      | EIP-152 (BLAKE2F precompile), EIP-1108 (alt_bn128 repricing), EIP-1344 (CHAINID), EIP-1884 (SELFBALANCE), EIP-2028 (calldata cost), EIP-2200 (SSTORE) |
| `:berlin`        | EIP-2565 (ModExp repricing), EIP-2929 (cold/warm access), EIP-2930 (access lists) |
| `:london`        | EIP-1559 (basefee), EIP-3198 (BASEFEE), EIP-3529 (refund cap), EIP-3541 (0xEF rejection) |
| `:paris`         | The Merge (PREVRANDAO replaces DIFFICULTY) |
| `:shanghai`      | EIP-3651 (COINBASE pre-warm), EIP-3855 (PUSH0), EIP-3860 (initcode limit) |
| `:cancun`        | EIP-1153 (TLOAD/TSTORE), EIP-4844 (blobs, BLOBHASH, KZG precompile), EIP-5656 (MCOPY), EIP-6780 (SELFDESTRUCT), EIP-7516 (BLOBBASEFEE) |
| `:prague`        | EIP-2537 (BLS12-381 precompiles), EIP-7623 (calldata floor), EIP-7702 (set-code) |
|                  | EIP-2935 (block hashes), EIP-7685 requests: EIP-6110 deposits, EIP-7002 withdrawals, EIP-7251 consolidations |
| `:osaka`         | EIP-7825 (tx gas limit cap), EIP-7918 (blob base fee floor), EIP-7934 (block RLP size limit), EIP-7939 (CLZ) |
|                  | EIP-7823 (ModExp bounds), EIP-7883 (ModExp repricing), EIP-7951 (P256VERIFY precompile) |
|                  | EIP-7594 (at most 6 blobs per transaction) |

# `spec_id`

```elixir
@type spec_id() ::
  :frontier
  | :homestead
  | :tangerine_whistle
  | :spurious_dragon
  | :byzantium
  | :constantinople
  | :istanbul
  | :berlin
  | :london
  | :paris
  | :shanghai
  | :cancun
  | :prague
  | :osaka
```

# `t`

```elixir
@type t() :: %EEVM.HardforkConfig{spec_id: spec_id()}
```

# `activation_ordinal!`

```elixir
@spec activation_ordinal!(atom()) :: non_neg_integer()
```

Returns the `ordinal/1` of the fork that activates `flag`. Raises
`ArgumentError` when `flag` isn't declared in `@eip_activation`.

# `all_spec_ids`

```elixir
@spec all_spec_ids() :: [spec_id()]
```

Returns a list of all known spec IDs in chronological order.

# `default`

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

Returns the default hardfork config — Cancun, the most-tested hardfork.

Callers that don't specify a hardfork explicitly get Cancun semantics,
preserving backwards compatibility with all existing tests.

# `enabled?`
*macro* 

Returns whether the EIP feature flag `flag` is active in `hardfork`.

A macro, so `require EEVM.HardforkConfig` first. With a literal flag, as
eevm's own code always passes, the flag is looked up when the caller
compiles: a flag missing from `@eip_activation`, such as a misspelling, is
a compile error rather than a rule that is silently off, and the check
compiles to one integer comparison. A flag held in a variable must be
declared too, or the check raises `ArgumentError`; tables of flags, like
the opcode registry's, are read when the per-fork tables are built at
compile time, so a bad entry fails that compilation.

`EEVM.Config.enabled?/2` is the public runtime check, for which unknown
flags are inactive.

## Examples

    iex> require EEVM.HardforkConfig
    iex> EEVM.HardforkConfig.enabled?(EEVM.HardforkConfig.new(:cancun), :eip_6780)
    true
    iex> EEVM.HardforkConfig.enabled?(EEVM.HardforkConfig.new(:london), :eip_6780)
    false
    iex> flag = :eip_2929
    iex> EEVM.HardforkConfig.enabled?(EEVM.HardforkConfig.new(:berlin), flag)
    true

# `flag?`

```elixir
@spec flag?(atom()) :: boolean()
```

Returns whether `flag` is declared in `@eip_activation`.

## Examples

    iex> EEVM.HardforkConfig.flag?(:eip_1559)
    true
    iex> EEVM.HardforkConfig.flag?(:eip_1595)
    false

# `new`

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

Creates a new hardfork config for the given `spec_id`.

## Example

    iex> EEVM.HardforkConfig.new(:cancun)
    %EEVM.HardforkConfig{spec_id: :cancun}

# `ordinal`

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

Returns the position of `hardfork`'s spec in the fork order, from 0 for
Frontier; `enabled?/2` compares it with a flag's activation.

---

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