EIP-8250: Keyed Nonces for Frame Transactions

Hi @soispoke, @nerolation, lightclient and @vbuterin, thanks for putting this together. The privacy-protocols-as-shared-senders bottleneck is a real problem, and decoupling replay protection from a single linear sequence is the right shape of fix.

A note from a complementary direction: we’ve been operating a contract-level implementation in this design space since 2023, today inside EVVM, and the deployment experience has surfaced a few points that might be useful as EIP-8250 progresses.

Brief context

EVVM is a smart-contract-native virtual blockchain framework. Inside any EVVM instance, every transaction is validated through a single Core entry point, validateAndConsumeNonce, which checks signature, nonce, and executor permissions atomically. The nonce model is dual:

  • Sync nonce: per-account linear counter for sequential ordering.

  • Async nonce: per-account (account, nonce_value) slot in a mapping, marked consumed on use. The user picks the value. Different async nonces are replay-independent in exactly the sense your spec describes for non-zero nonce_key keys.

This maps onto your (nonce_key, nonce_seq) model with nonce_seq collapsed to a single bit (used / not used) per key. For the use cases we’ve seen in production so far (order books, subscriptions, recurring payments, multiple parallel intents per user, shared-sender privacy patterns), one bit has been enough. We’re aware that more compact storage layouts exist (encoding consumed sequences as [start, end] range pairs is the notable one), and they sit on our optimization path for when state growth becomes an actual bottleneck rather than a theoretical one.

Implementation references

Two design points worth flagging from production

1. Non-authoritative reservation as a deliberate choice.

EVVM ships one reservation primitive on top of the keyed nonce, and only one: non-authoritative.

Any actor (the user, an app, middleware) can publish “I intend to use nonce X” onchain at gas cost. The registry does not block anyone else from using the same nonce; it just makes intent visible and indexable. We deliberately did not ship authoritative locks because authoritative locks introduce their own failure modes: lock-grabbing as a DoS vector, bad-UI lockups holding keys hostage, and the same heterogeneous-RNG concern shifted onto a different primitive without solving it. An advisory layer adds information without adding new ways to deny service.

This is the point worth flagging for EIP-8250 specifically. The spec correctly notes that applications “deriving nonce_key from a per-use identifier SHOULD domain-separate the input and reject derived keys equal to 0.” But there is no protocol-level visibility into what keys are intended to be used, only what has already been used. In the edge case where two independent wallets generate the same nonce_key for different purposes (the 2**256 space makes it cosmically unlikely with strong RNG, but real-world UI code is not always strong RNG), an advisory registry surfaces the conflict before consumption. Cheap signal, voluntary, gas-priced, and the 2**64 nonce_seq space leaves room to reissue under a fresh derivation if a collision is detected.

Whether this belongs in EIP-8250 itself or in companion infrastructure is a separate question. It is worth at least anticipating in the Rationale or Security Considerations, since downstream wallets and middleware will face the heterogeneous-RNG question regardless of where the keyed-nonce state lives.

2. Pairing keyed nonces with tx.origin and msg.sender checks in the same validation step.

The EIP solves replay-domain separation; it doesn’t address “who is authorized to submit or relay this transaction.” By validating signature + nonce + (origin, sender) executor permits in one atomic call, two primitives become useful in practice:

  • tx.origin lets you restrict, at the validation step, which EOA is allowed to land a given keyed transaction. For relay markets and Fisher-style networks, this is the difference between “any submitter can extract this signed payload and replay it through a competing pathway” and “only the originator’s intended relayer is honored.” A lot of infra-level implementations open up if the validation cooperates with this hint.

  • msg.sender lets contracts queue, store, and conditionally trigger user-signed transactions onchain, without needing staking or token-permission systems to do DeFi. Trust comes from auditable contract code rather than economic security. Concrete pattern: a Storage contract that holds signed user transactions until a condition is met (timelock, oracle output, multisig vote), then becomes the msg.sender executing them. Code-level trust replaces slashing economics for an important class of intent-based and time-locked flows.

On necessity at protocol level

Not to argue against the EIP, just to give the discussion a data point: a lot of what EIP-8250 unlocks at the application layer is already accessible at the contract level today, with no fork. Async nonces in a mapping have served real privacy, shared-sender, and parallel-intent flows in production for us. The state-growth tax that motivates KEYED_NONCE_FIRST_USE_GAS = 20000 is real but, on contract-level implementations, has not yet approached a ceiling that would justify lifting the model into protocol. Smart-contract iteration speed on this surface has been a meaningful advantage while the use cases mature.

The framing we’ve been using internally: EVVM is a fast iteration path for vertically scaling the EVM. Changes a virtual blockchain can ship in days, real users use in weeks, and the EIP process can absorb at its own cadence. When the same primitives also land at the client and protocol layer (as EIP-8250 proposes), the impact compounds for everyone running virtual blockchains on top, especially in shared-sender and privacy contexts where the keyed-aware mempool is the unlock. The two layers are not competing. The contract layer is where primitives get tested under real load; the protocol layer is where they become free, mempool-addressable, and shared infrastructure for everyone.

Where EIP-8250 does unlock something the contract approach genuinely cannot replicate: protocol-level mempool addressability of keyed nonces, which is what enables future keyed-aware mempool policies admitting concurrent transactions per sender. That’s the real reason to push this to L1 and is worth the lift if mempool-level concurrency for shared senders is the strategic goal. For replay-domain separation alone, a contract-level keyed-nonce store gets you most of the way and lets the design iterate freely.

Invitation

If it would be useful to the discussion: an EVVM instance is deployable. We suggest deplying on Sepolia or any L2 testnet with one CLI command (Docker image at ghcr.io/evvm-org/evvm-docker). You could write a privacy-style or shared-sender flow against it, stress the keyed-nonce surface in production traffic, and use the data to inform the EIP. Happy to walk through any of it.

The point is not to compare. The point is that there is running code and live deployment data in the same design space, and learning from it might tighten the spec or surface edge cases earlier.

Quickstart: https://www.evvm.info/docs/QuickStart

Thanks again for the work on this.

Best,
German Abal / @ariutokintumi
Co-Founder, Architect & Security of EVVM

1 Like