<!--
Blockchain Lab reading mirror.
Licence: CC0-1.0. This is the upstream licence, not a Blockchain Lab grant.
Canonical: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8250.md
Repository: https://github.com/ethereum/EIPs
Mirrored: 2026-10-10
The text below is the upstream file. The desk study is a different page and is not covered by this licence.
-->

---
eip: 8250
title: Keyed Nonces for Frame Transactions
description: Independent nonce domains for frame transactions
author: Thomas Thiery (@soispoke), Toni Wahrstätter (@nerolation), lightclient (@lightclient), Vitalik Buterin (@vbuterin)
discussions-to: https://ethereum-magicians.org/t/eip-8250-keyed-nonces-for-frame-transactions/28437
status: Draft
type: Standards Track
category: Core
created: 2026-04-16
requires: 7928, 7976, 8037, 8038, 8141
---

## Abstract

Replaces the single sender nonce of an [EIP-8141](./eip-8141.md) frame transaction with `(nonce_keys, nonce_seq)`: a bounded set of nonce keys sharing one sequence number. `nonce_keys == [0]` aliases the legacy account nonce; each non-zero key selects an independent protocol-managed nonce sequence stored in a `NONCE_MANAGER` system contract. Transactions whose non-zero key sets do not overlap are replay-independent. This helps privacy applications use one shared sender for many users without forcing every transaction through the same nonce sequence.

## Motivation

A frame transaction currently consumes one linear sender nonce, so a delayed transaction blocks every later frame transaction from the same sender. This is too restrictive for designs that intentionally share one sender across many independent users or actions.

The leading example is privacy protocols. To avoid binding onchain activity to a unique public sender, users transact through a single shared sender address. With one linear nonce, that shared sender becomes a throughput bottleneck: one user's inclusion invalidates every other user's pending withdrawal even when the spends are otherwise unrelated. Smart-wallet session keys and relayer-style senders face the same problem.

Keyed nonces let each spend pick its own nonce domain, for example one derived from a privacy nullifier. Transactions on disjoint non-zero key sets are replay-independent. This removes the protocol-level nonce obstacle to future keyed-aware mempools that admit concurrent transactions from the same sender. This EIP preserves EIP-8141's limit of one pending frame transaction per sender in the public mempool.

Tying nonce consumption to EIP-8141's payment-approval step also gives single-use-key applications, such as nullifiers, an atomic spent-once guarantee: if validation requires every selected key to be unused, successful inclusion makes all selected keys used, regardless of whether later frames revert.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

This specification is a delta against [EIP-8141](./eip-8141.md).

### Constants

| Name | Value |
|---|---|
| `FORK_TIMESTAMP` | `TBD` |
| `NONCE_MANAGER` | `0x8250968C12e01A19d6F667b9B2F3b3A4d0e51cB7` |
| `NONCE_MANAGER_CODE` | `0x60006000fd` |
| `KEYED_NONCE_FIRST_USE_STATE_GAS` | `STATE_BYTES_PER_STORAGE_SET * CPSB` |
| `KEYED_NONCE_ACCESS_COST` | `COLD_STORAGE_ACCESS + STORAGE_WRITE` |
| `MAX_NONCE_SEQ` | `2**64 - 1` |
| `MAX_NONCE_KEYS` | `16` |
| `TXPARAM_LEGACY_NONCE` | `0x0D` |
| `TXPARAM_NONCE_KEY_COUNT` | `0x0E` |
| `TXPARAM_NONCE_KEYS_HASH` | `0x0F` |
| `TXPARAM_NONCE_KEY_0` | `0x10` |

`STATE_BYTES_PER_STORAGE_SET` and `CPSB` are defined by [EIP-8037](./eip-8037.md). EIP-8037 currently sets `STATE_BYTES_PER_STORAGE_SET = 64` and `CPSB = 1530`, so each fresh key costs `97920` state gas.

`COLD_STORAGE_ACCESS` and `STORAGE_WRITE` are defined by [EIP-8038](./eip-8038.md). EIP-8038 currently sets `COLD_STORAGE_ACCESS = 2100` and `STORAGE_WRITE = 10000`, so each non-zero key costs `12100` execution gas for the cold read and write of its slot.

`NONCE_MANAGER_CODE` is a runtime equivalent to `revert(0, 0)`: any ordinary call to `NONCE_MANAGER` immediately reverts with empty returndata.

`NONCE_MANAGER` is an ordinary contract deployed by a keyless transaction (see [Deployment](#deployment)). It is not installed by the protocol at activation.

### Transaction payload

This EIP replaces the `nonce` field in the EIP-8141 `FRAME_TX_TYPE` payload with two consecutive fields, `nonce_keys` followed by `nonce_seq`. No other payload field is changed. Applied to the EIP-8141 payload, the result is:

```text
[chain_id, nonce_keys, nonce_seq, sender, frames, signatures, fees, blob_versioned_hashes]

fees = [max_priority_fee_per_gas, max_fee_per_gas, max_fee_per_blob_gas]
```

`nonce_keys` is a list of `uint256` values; `nonce_seq` is a `uint64`. Each nonce key and `nonce_seq` MUST be encoded as canonical minimal-length RLP integers. The frame layout and all other EIP-8141 transaction fields are unchanged.

The EIP-8141 signature hash procedure applies after this replacement. The signing payload contains `nonce_keys` and `nonce_seq` at the position previously occupied by `nonce`.

The `nonce_keys` and `nonce_seq` encodings are priced as transaction data. Define:

```python
nonce_calldata = rlp(nonce_keys) || rlp(nonce_seq)
nonce_calldata_cost = calldata_cost(nonce_calldata)
nonce_calldata_floor_tokens = floor_tokens_in(nonce_calldata)

keyed_nonce_count = 0 if nonce_keys == [0] else len(nonce_keys)
keyed_nonce_access_cost = keyed_nonce_count * KEYED_NONCE_ACCESS_COST
```

`nonce_calldata` is priced exactly as EIP-8141 prices frame and signature data under [EIP-7976](./eip-7976.md). Each non-zero key additionally pays for the slot it reads and writes:

- add `nonce_calldata_cost` and `keyed_nonce_access_cost` to `frame_tx_intrinsic_gas`;
- add `nonce_calldata_floor_tokens` to `calldata_floor_tokens`;
- add `keyed_nonce_access_cost` to `calldata_floor_gas`.

`nonce_calldata_cost` and `keyed_nonce_access_cost` are execution gas and are derivable from the transaction alone. Every EIP-8141 rule that uses `frame_tx_intrinsic_gas`, `calldata_floor_tokens`, or `calldata_floor_gas` uses these updated quantities; EIP-8141 is otherwise unchanged.

Decoders MUST reject a `FRAME_TX_TYPE` transaction to which this EIP applies if any of the following is true:

- the payload does not match the EIP-8141 schema after replacing `nonce` with consecutive fields `nonce_keys` and `nonce_seq`;
- `nonce_keys` is not an RLP list;
- `len(nonce_keys) < 1` or `len(nonce_keys) > MAX_NONCE_KEYS`;
- any item in `nonce_keys`, or `nonce_seq`, is not encoded as a canonical RLP integer;
- any item in `nonce_keys` is greater than or equal to `2**256`;
- `nonce_seq >= 2**64`;
- `nonce_keys` is not strictly increasing by numeric value;
- any item in `nonce_keys` is `0` and `nonce_keys != [0]`.

A `FRAME_TX_TYPE` transaction to which this EIP applies is invalid if `nonce_seq >= MAX_NONCE_SEQ`. This bound depends on no state, so clients MAY check it together with the decoding rules above, before stateful validity.

### Nonce state

For `nonce_keys == [0]`, the selected nonce domain is the sender's legacy account nonce.

For `nonce_keys != [0]`, each selected nonce key is stored in protocol-managed storage under `NONCE_MANAGER`.

Let:

```text
A = left_pad_32(sender)
K = uint256_to_bytes32(nonce_key)
```

Then:

```text
slot(sender, nonce_key) = keccak256(A || K)
```

Equivalently, `slot(sender, nonce_key)` is the keccak256 hash of the 32-byte left-padded sender address followed by the 32-byte big-endian encoding of `nonce_key`.

```python
def current_nonce_seq(sender, nonce_key):
    if nonce_key == 0:
        return state[sender].nonce
    return uint256(state[NONCE_MANAGER].storage[slot(sender, nonce_key)])
```

For `nonce_key != 0`, an absent slot reads as `0`. The protocol never writes `0`: sequence `0` is represented only by an absent slot, so first use of a key is detectable as a zero-valued read. Only the protocol writes keyed-nonce slots; ordinary calls to `NONCE_MANAGER` revert.

### Stateful validity

Let `tx_legacy_nonce` be the value of `state[tx.sender].nonce` observed from the transaction's actual pre-state within block execution order, before any frame executes.

A post-fork frame transaction is statefully valid only if:

```python
for nonce_key in tx.nonce_keys:
    assert tx.nonce_seq == current_nonce_seq(tx.sender, nonce_key)
```

This check occurs at the same stage as EIP-8141's existing nonce check, before any frame executes.

Stateful validity is evaluated against the transaction's actual pre-state within block execution order. Therefore, two frame transactions whose selected key sets overlap for the same sender are valid in one block only if each transaction's `nonce_seq` equals the current sequence of every selected key at its position in block execution order.

### Nonce consumption

EIP-8141's payment-approval transition currently increments the sender's account nonce. This EIP replaces that increment with:

```python
def consume_nonce_set(sender, nonce_keys, nonce_seq):
    if nonce_keys == [0]:
        increment_account_nonce(sender)
    else:
        for nonce_key in nonce_keys:
            state[NONCE_MANAGER].storage[slot(sender, nonce_key)] = nonce_seq + 1
```

`consume_nonce_set` runs exactly once per transaction, on the unique successful payment-scoped `APPROVE` that sets `payer` from `None` to `resolved_target`.

A payment-scoped `APPROVE` is an `APPROVE` whose scope includes `APPROVE_PAYMENT`, i.e. scope `0x1` or `0x3`.

For `nonce_keys == [0]`, `increment_account_nonce(sender)` increments the sender's current account nonce; it does not set the account nonce to `tx.nonce_seq + 1`. This preserves EIP-8141 behavior if an earlier frame in the same transaction has already changed the sender's legacy nonce, for example by account deployment or by executing `CREATE` or `CREATE2` at `tx.sender`.

If `nonce_keys == [0]` and `increment_account_nonce(sender)` would make `state[sender].nonce > MAX_NONCE_SEQ`, the payment-scoped `APPROVE` fails with an exceptional halt and performs no approval effects.

For `nonce_keys != [0]`, transaction validity guarantees `tx.nonce_seq < MAX_NONCE_SEQ`, so `tx.nonce_seq + 1` is in range.

For a payment-scoped `APPROVE`, clients first perform all EIP-8141 approval checks and execution gas charges, including memory expansion, except the sender existence and state gas checks tied to its nonce increment. The transition below replaces those checks, the state gas charge, and the sender nonce increment.

Only after those checks and costs succeed, and before any approval effect is committed, clients MUST perform:

1. If `tx.nonce_keys == [0]`, set `nonce_state_gas = STATE_BYTES_PER_NEW_ACCOUNT * CPSB` when `tx.sender` does not exist under EIP-8037's existence rule immediately before approval. Otherwise set it to `0`. If `tx.nonce_keys != [0]`, read each selected slot and set `nonce_state_gas = KEYED_NONCE_FIRST_USE_STATE_GAS * first_use_count`, where `first_use_count` is the number of slots whose value is `0`.
2. If `state_gas_left < nonce_state_gas`, halt the current call frame exceptionally without applying any approval effects.
3. Charge `nonce_state_gas` as state gas from `state_gas_left`. EIP-8141 attributes the charge to the current frame's receipt.
4. Execute `consume_nonce_set(tx.sender, tx.nonce_keys, tx.nonce_seq)`.
5. Commit the remaining EIP-8141 payment approval effects, excluding the sender nonce increment and sender account creation charge replaced above.

Steps 3 through 5 are one approval transition. The state gas charge, nonce consumption, `max_cost` collection, `payer` update, and any `sender_approved` update either all apply or none apply.

If the enclosing EIP-8141 frame reverts or halts exceptionally, clients MUST revert the transition. Once that frame succeeds, a later frame failure, an atomic batch rollback, or a validation-prefix state restore that discards the transaction body MUST NOT revert it unless the transaction is invalid under EIP-8141. Clients MUST discard all effects of an invalid transaction.

The charge counts toward the transaction's and block's state gas totals and is included in fee settlement. It does not consume execution gas or increase `gas_used.execution`.

Keyed-nonce reads and writes performed by stateful validity and `consume_nonce_set` are protocol bookkeeping: they do NOT add `NONCE_MANAGER` or its slots to [EIP-2929](./eip-2929.md) `accessed_addresses` or `accessed_storage_keys`, are NOT charged under [EIP-2200](./eip-2200.md) `SSTORE` pricing, and do NOT warm the address or slot for later user-level access. They are priced by `keyed_nonce_access_cost` instead.

### Block access list

Keyed-nonce state is ordinary storage of `NONCE_MANAGER` and is recorded in the [EIP-7928](./eip-7928.md) block access list as such. The exemption above only changes gas charging and warming, not block access list recording.

For every transaction with `nonce_keys != [0]`, `NONCE_MANAGER` MUST appear in the block access list, and each slot written by `consume_nonce_set` MUST appear in its `storage_changes` with the transaction's `block_access_index` and with `new_value` equal to the value `consume_nonce_set` writes. A valid transaction writes every slot it reads during stateful validity, and the written value always differs from the value read, so these slots never appear in `storage_reads`.

### Transaction introspection

`TXPARAM(0x01)` returns `tx.nonce_seq`. EIP-8141 assigns `TXPARAM` indices through `0x0C`, including `0x0B = len(signatures)`. This EIP adds four non-conflicting indices:

| `param` | Return value |
| ------- | ------------ |
| `0x0D` | pre-state legacy sender nonce |
| `0x0E` | `len(tx.nonce_keys)` |
| `0x0F` | `nonce_keys_hash(tx)` |
| `0x10` | `tx.nonce_keys[0]` |

`nonce_keys_hash(tx)` is defined as:

```text
keccak256(
    uint256_to_bytes32(len(tx.nonce_keys)) ||
    concat(uint256_to_bytes32(k) for k in tx.nonce_keys)
)
```

Because valid `nonce_keys` are strictly increasing, `nonce_keys_hash(tx)` has one canonical encoding for each selected key set.

`TXPARAM(0x0D)` returns `tx_legacy_nonce`, the value of `state[tx.sender].nonce` observed during stateful validity before any frame executes. It is transaction-scoped and is not updated by payment approval, keyed-nonce consumption, account deployment, `CREATE`, or `CREATE2` within the same transaction.

For `nonce_keys == [0]`, stateful validity requires `TXPARAM(0x01) == TXPARAM(0x0D)` at transaction start. For `nonce_keys != [0]`, they may differ.

### Deployment

The nonce manager is deployed like any other smart contract. A special synthetic address is generated by working backwards from the desired deployment transaction:

```json
{
  "type": "0x0",
  "nonce": "0x0",
  "to": null,
  "gas": "0x3d090",
  "gasPrice": "0xe8d4a51000",
  "maxPriorityFeePerGas": null,
  "maxFeePerGas": null,
  "value": "0x0",
  "input": "0x60058060095f395ff360006000fd",
  "v": "0x1b",
  "r": "0x539",
  "s": "0x825000000000000141de",
  "hash": "0x5fb73d939ec0b319de03454f0e787a57543d7edcf889a1a8e3fd0473f8fb6c1f"
}
```

```text
Sender: 0x7A57307E9985b0e26B66A7BB920BcaF0396b8198
Address: 0x8250968C12e01A19d6F667b9B2F3b3A4d0e51cB7
```

The init code returns `NONCE_MANAGER_CODE`. No private key is known for the sender, so no other transaction can deploy code at `NONCE_MANAGER`.

### Activation

This EIP MUST activate at or after [EIP-8141](./eip-8141.md).

If `timestamp < FORK_TIMESTAMP`, clients MUST NOT replace `nonce` and MUST NOT apply keyed nonce logic.

If `timestamp >= FORK_TIMESTAMP`, clients MUST replace `nonce` with `nonce_keys` and `nonce_seq` and MUST apply keyed nonce logic.

When this EIP activates, the chain's state MUST already contain `NONCE_MANAGER` with a nonzero nonce and code `NONCE_MANAGER_CODE`. A chain meets this requirement by including the deployment transaction in a block before the fork or by including the account in its genesis state with nonce `1`. If an already running chain's gas parameters no longer allow the deployment transaction, adding the account requires a coordinated irregular state transition, which is outside the scope of this EIP.

Clients MUST NOT check for `NONCE_MANAGER` at the fork boundary. Activation changes no state, so it adds nothing to the [EIP-7928](./eip-7928.md) block access list.

Pre-fork frame transactions and authorizations bound to the pre-fork canonical signature hash do not survive the boundary and MUST be evicted from mempools and regenerated.

### Mempool

For the EIP-8141 public mempool rules:

- replace the pending transaction identity `(sender, nonce)` with `(sender, nonce_keys, nonce_seq)`;
- replace every EIP-8141 public mempool dependency on the sender nonce with `current_nonce_seq(sender, nonce_key)` for each `nonce_key` in `nonce_keys`.

If the validation prefix reads `TXPARAM(0x0D)`, the sender's legacy account nonce is an additional dependency.

Nodes MUST revalidate a pending transaction when any of its selected nonce sequences changes. If the validation prefix reads `TXPARAM(0x0D)`, nodes MUST also revalidate when the sender's legacy account nonce changes.

For transactions under this EIP, EIP-8141 Structural Rule 6 also allows a `VERIFY` frame to use state gas when a payment-scoped `APPROVE` creates a keyed nonce slot. That state gas draws from the frame's `limits.state` and does not count toward `MAX_VERIFY_GAS`. The existing `MAX_VERIFY_STATE_GAS` cap on the sum of state limits in the validation prefix is unchanged.

All other EIP-8141 public mempool rules, including the limit of one pending frame transaction per sender, remain unchanged.

## Rationale

A contract-managed nullifier table inside a `VERIFY` frame is not sufficient: `VERIFY` is static-call-like and cannot write ordinary contract state, and deferring the spent-mark to a later `SENDER` frame breaks atomicity once payment approval can persist through later-frame failure. Lifting nonce consumption into the payment-approval transition gives a single, atomic spent-once guarantee.

`nonce_keys == [0]` aliases the legacy account nonce so EIP-8141's existing replay behavior is preserved. Account deployment, `CREATE`, and `CREATE2` continue to affect account nonces by ordinary EVM rules. Only payment-approval nonce-bumping is replaced.

`nonce_keys` are `uint256` values because privacy protocols often derive keys from 32-byte nullifiers, commitments, or hash outputs. [ERC-4337](./eip-4337.md) uses the same key/sequence model but has only one 32-byte nonce field, so it packs a 24-byte key and an 8-byte sequence into that field. This EIP uses explicit fields: 32-byte nonce keys and an 8-byte `nonce_seq`. That keeps ERC-4337's 64-bit sequence width, avoids truncating nullifier-derived labels, and makes ERC-4337-style 24-byte keys a subset of this EIP's key space.

This EIP intentionally uses one `nonce_seq` shared by all selected `nonce_keys`, rather than a vector of `(nonce_key, nonce_seq)` pairs. A shared sequence preserves the scalar replay semantics of EIP-8141 and keeps transaction introspection simple. Strictly increasing `nonce_keys` give each selected key set one canonical transaction encoding and one canonical hash. Applications that require single-use capabilities, including privacy nullifiers and expiring authorizations, can derive distinct nonce keys and use `nonce_seq == 0`. Applications that require atomic advancement of unrelated nonce domains at unrelated sequence numbers are outside the scope of this EIP and may be addressed by a future extension.

Keyed-nonce state lives in the storage of one `NONCE_MANAGER` system contract rather than extending account state, since the latter would change the account MPT layout. This minimizes consensus-surface change while keeping keyed state committed under the existing execution `stateRoot`.

`NONCE_MANAGER` is deployed by an ordinary transaction rather than installed at the fork, as with [EIP-7997](./eip-7997.md) and the EIP-8141 expiry verifier. The fork block then makes no irregular state change, so activation adds no block access list entry and needs no rule for an occupied address. Keyed nonce logic is inactive before the fork and ordinary calls to the contract revert, so no pre-fork guard is needed.

Because keyed nonces are ordinary storage, EIP-7928 records them without any change to its format, and a block access list consumer needs no knowledge of this EIP to prefetch, conflict-check, or apply them. A dedicated nonce-change field under the sender would be no smaller for 32-byte keys, would require every consumer to derive the storage slot, and would escape the EIP-7928 item bound, which counts storage keys and addresses but not nonce changes.

The first use of a keyed nonce creates one storage slot, so it pays EIP-8037's state gas for one new slot. Later uses update the same slot and do not pay the creation charge again.

Every use of a key is a cold read and write of one storage slot that adds a 32-byte key and a value to the block access list. `KEYED_NONCE_ACCESS_COST` is the EIP-8038 access and write components of an `SSTORE` that changes a cold slot, what a user pays for the same work, and keeps each block access list item above EIP-7928's `ITEM_COST`. The state-creation component is the existing first-use state gas charge. The cost is a flat intrinsic sum of schedule primitives rather than an EIP-2929 charge because the slots are unreachable from EVM code and the cost must be derivable from the transaction alone; defining it from the primitives lets EIP-8038 repricings flow through, as [EIP-2780](./eip-2780.md) does for intrinsic gas. The cost is added to the calldata floor as well as to intrinsic gas, as EIP-8141 does for signature verification. An intrinsic charge alone would be absorbed by a calldata-heavy transaction whose floor already exceeds its standard gas, and its keys would then add 64 block bytes each for no floor cost. In the floor, each key raises the minimum charge by `12100` gas, more than the `4096` gas its block access list bytes would cost at the EIP-7976 floor rate, so no separate byte term is needed.

This EIP does not relax EIP-8141's public-mempool one-pending-frame-transaction-per-sender guidance, but it removes the protocol-level obstacle to doing so. A future policy MAY admit multiple pending frame transactions for the same sender on disjoint non-zero key sets, subject to its own dependency-tracking and replacement rules.

## Backwards Compatibility

`nonce_keys == [0]` preserves EIP-8141 replay behavior. Legacy account objects, non-frame transaction types, and `eth_getTransactionCount` are unchanged.

`TXPARAM(0x01)` continues to return the transaction's replay-protection sequence, which equals the sender's legacy nonce only when `nonce_keys == [0]`. Verifier code that previously assumed `TXPARAM(0x01)` is the legacy account nonce MUST either enforce `TXPARAM(0x0E) == 1 and TXPARAM(0x10) == 0` or be updated to handle keyed sequences.

`TXPARAM(0x0D)` provides explicit pre-state legacy-account-nonce access for verifier code that needs it.

If activated after EIP-8141, pre-fork frame transactions become invalid at the fork boundary and any authorization bound to the pre-fork signature hash MUST be regenerated.

## Security Considerations

Replay protection is scoped to `(sender, nonce_keys, nonce_seq)`, with validity requiring every selected key to have the selected sequence. Disjoint non-zero key sets remove only the replay-ordering dependency; transactions on disjoint keys may still conflict on sender or payer balance, contract storage, paymaster state, or any other shared state. This EIP provides replay-domain separation, not confidentiality of key selection: `nonce_keys` are visible in the payload and committed by `compute_sig_hash(tx)`.

Single-use-key applications, such as nullifiers, MUST authenticate at least `(sender, nonce_keys_hash, nonce_seq == 0)` in `VERIFY` and SHOULD bind the canonical signature hash via `TXPARAM(0x08)`. Treating `nonce_seq == 0` alone as authorization is unsafe. Authenticating only `TXPARAM_NONCE_KEY_0` is also unsafe when `TXPARAM_NONCE_KEY_COUNT > 1`, because an attacker could add unauthorized keys that would be consumed by payment approval. Applications deriving nonce keys from per-use identifiers SHOULD domain-separate the input and reject derived keys equal to `0`.

A non-zero-key frame transaction does not advance the sender's legacy account nonce during payment approval. If such a transaction executes `CREATE` at `tx.sender`, the created address depends on the sender's legacy account nonce at execution time. Another transaction that advances the sender's legacy nonce before inclusion can therefore change the `CREATE` address without invalidating the keyed transaction. Applications whose semantics depend on a `CREATE` address SHOULD use `CREATE2` or MUST authenticate the expected pre-state legacy nonce via `TXPARAM(0x0D)`.

Nonce consumption persists through later-frame reverts and EIP-8141 atomic-batch rollback because it is part of payment approval. Single-use applications SHOULD minimize post-approval revert paths.

A "send another transaction with the same legacy nonce" cancellation strategy does not invalidate a pending non-zero-key frame transaction. Replacement requires the same `(sender, nonce_keys, nonce_seq)` under the relevant mempool replacement rules, or another transaction that intentionally consumes an overlapping keyed domain.

Each consumed `(sender, nonce_key != 0)` occupies one persistent slot in `NONCE_MANAGER` storage, and entries are never deleted. Creating a slot consumes state gas, so a block can create at most `block_gas_limit // KEYED_NONCE_FIRST_USE_STATE_GAS` new keyed nonce slots. `nonce_seq == MAX_NONCE_SEQ` represents an exhausted key; a key at that sequence cannot advance further.

Ordinary direct calls to `NONCE_MANAGER` revert. However, the account may still receive ETH through force-send mechanisms where applicable. Any balance held at `NONCE_MANAGER` is outside the scope of this EIP and is not recoverable by protocol logic defined here.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
