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

Dispatcher for EVM precompiled contracts.

Precompiled contracts are built-in functions at fixed addresses that provide
cryptographic and utility operations too expensive to implement in EVM bytecode.
When a CALL targets one of these addresses, execution is routed here instead of
interpreting bytecode.

## Supported Precompiles

| Address | Name | From |
|---------|------|------|
| 0x01 | ECRECOVER — elliptic curve signature recovery | Frontier |
| 0x02 | SHA256 — SHA-256 hash | Frontier |
| 0x03 | RIPEMD160 — RIPEMD-160 hash | Frontier |
| 0x04 | IDENTITY — data copy (no-op) | Frontier |
| 0x05 | MODEXP — big integer modular exponentiation | Byzantium (EIP-198) |
| 0x06 | BN256 ADD — elliptic curve point addition on alt_bn128 | Byzantium (EIP-196) |
| 0x07 | BN256 MUL — elliptic curve scalar multiplication on alt_bn128 | Byzantium (EIP-196) |
| 0x08 | BN256 PAIRING — bilinear pairing check on alt_bn128 | Byzantium (EIP-197) |
| 0x09 | BLAKE2F — BLAKE2b compression function | Istanbul (EIP-152) |
| 0x0A | KZG Point Evaluation — verify KZG commitment | Cancun (EIP-4844) |
| 0x0B | BLS12 G1ADD — add two BLS12-381 G1 points | Prague (EIP-2537) |
| 0x0C | BLS12 G1MSM — multiscalar multiplication over BLS12-381 G1 | Prague (EIP-2537) |
| 0x0D | BLS12 G2ADD — add two BLS12-381 G2 points | Prague (EIP-2537) |
| 0x0E | BLS12 G2MSM — multiscalar multiplication over BLS12-381 G2 | Prague (EIP-2537) |
| 0x0F | BLS12 PAIRING — pairing check over BLS12-381 | Prague (EIP-2537) |
| 0x10 | BLS12 MAP_FP_TO_G1 — map Fp element into BLS12-381 G1 | Prague (EIP-2537) |
| 0x11 | BLS12 MAP_FP2_TO_G2 — map Fp2 element into BLS12-381 G2 | Prague (EIP-2537) |
| 0x100 | P256VERIFY — secp256r1 ECDSA signature verification | Osaka (EIP-7951) |

An address is a precompile only from the fork that introduced it. ModExp and
the BN256 precompiles also receive the hardfork, because their prices changed
later: ModExp follows EIP-198, then EIP-2565 (Berlin), then EIP-7883 with the
EIP-7823 input bounds (Osaka);
BN256 follows EIP-196/197, then EIP-1108 (Istanbul).

The registry for each fork is built at compile time. Custom precompiles
registered through `EEVM.Config.register_precompile/3` implement
`EEVM.Precompile` and override built-ins at the same address.

# `entry`

```elixir
@type entry() :: {module(), atom(), list()}
```

How a precompile runs: `apply(module, function, [input, gas_limit | extra_args])`.

# `execute`

```elixir
@spec execute(non_neg_integer(), binary(), non_neg_integer()) ::
  {:ok, binary(), non_neg_integer()} | {:error, atom()}
```

# `execute`

```elixir
@spec execute(non_neg_integer(), binary(), non_neg_integer(), EEVM.Config.t()) ::
  {:ok, binary(), non_neg_integer()} | {:error, atom()}
```

# `precompile?`

```elixir
@spec precompile?(non_neg_integer()) :: boolean()
```

# `precompile?`

```elixir
@spec precompile?(non_neg_integer(), EEVM.Config.t()) :: boolean()
```

# `precompile_addresses`

```elixir
@spec precompile_addresses(EEVM.Config.t()) :: [non_neg_integer()]
```

# `registry`

```elixir
@spec registry(EEVM.Config.t()) :: %{optional(non_neg_integer()) =&gt; entry()}
```

Returns the precompiles active under `config`: the fork's built-ins merged
with the custom precompiles registered on `config`.

---

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