EIP-8182: Private ETH and ERC-20 Transfers

What this EIP proposes

A canonical private transfer system for Ethereum: one shared pool for ETH and ERC-20 tokens, implemented as a system contract and verifier precompile, with public deposits and withdrawals. The system contract holds one note tree, nullifier set, user registry, auth policy registry, and delivery-key registry. It has no admin key and no on-chain upgrade path.

A recursive proof architecture keeps protocol invariants in a hard-fork-managed outer circuit while allowing permissionless inner auth circuits for authorization. New auth methods can be added without creating a new pool: users register an auth policy for an inner circuit, and the outer circuit continues to enforce the shared protocol rules.

Motivation

Sending assets publicly on Ethereum has a shared, widely interoperable default. Users send ETH and tokens to ordinary Ethereum addresses, often reached through ENS, and wallets, recipients, and applications rely on the same shared standards. Private transfers have no analogous shared default today, even though many ordinary financial activities require privacy.

Why has the market not produced a widely adopted default privacy application on Ethereum? Because a private transfer application cannot compete on product quality alone. Its effectiveness also depends on how many users and how much value shares the same pool. A small pool offers weak privacy even for a superior product, while a large pool can remain attractive even when competing products are better. That means app-layer teams cannot focus only on wallet UX, authentication, compliance, or proof systems. They must also persuade users to deposit into their pool, which is difficult when the pool is not already large.

But growing the pool is only part of the problem. App-layer teams also have to decide how the pool changes over time. If the pool is upgradeable, the parties with the power to change it could compromise user funds. Immutable pools avoid that risk, but they cannot adapt as proof systems weaken or cryptographic assumptions change. Neither is a good foundation for common privacy infrastructure.

Ethereum should break this impasse by providing a shared privacy layer.

Key design choices I’d like feedback on

  • Permissionless auth methods: The current draft is neutral about the signing format. Companion auth circuits can implement ECDSA, passkeys, multisig, or other schemes so long as they produce the required inner outputs and bind the canonical intent digest. Is that the right level of protocol neutrality, or should the base layer be more opinionated about auth?

  • Private fee compensation: Output slot 2 serves as an optional private fee note for compensating relayers, provers, or other service providers. The protocol itself charges no fee. Is a single fee output sufficient, or are there service-provider configurations that need more?

  • State growth: Each pool transaction adds permanent state (nullifiers and new commitment leaves). Is that acceptable for an initial version, or should an accumulator-based nullifier design be a prerequisite for enshrinement?

Links

6 Likes

Quite amusing that I missed you X post entirely but found it here. (To be fair I was sick last week)

Regarding intent format, have you considered EIP-712? It uses fixed-size fields which may be easier on circuits than RLP, and doesn’t require inventing fake chains. (Fun fact: I once had a conversation with Yak, who’s design for Ethereum wallets on Chia was also synthetic transactions and convinced him to go for EIP-712 as well) You still need to keccak twice in-circuit though.

About precompiles, I would say that precompiles should be as small and generic as possible given how hard they are to implement and maintain. It would be nice to have a new general purpose ZK precompile if the current ones are not enough. You already know how to write shielded pool protocols in solidity, the main novelty is to make them socially governed.

I don’t think state growth is a specific concern: since it happens via the regular EVM, existing and upcoming state growth control strategies like repricings, state gas etc. can still operate the same. It’s orthogonal.

1 Like

[Note: this post is based on an earlier version of the EIP. Changes have been made since then that obsolete some of the content.]

Thanks for the thoughtful feedback, @bbjubjub!

EIP-712 vs. intent transactions

The overall design philosophy of the EIP is that implementers should do extra work whenever it’s possible to make things easier for users and increase adoption potential.

With the intent transaction approach, the user hits the Send button in their wallet — the same Send button they use for everything else. The wallet shows “Send 1 ETH to 0xabc…” with token resolution, decimal formatting, dollar amounts, the whole purpose-built transaction confirmation UI. On day-one users get UX parity with their public transactions.

EIP-712 can express the same information, but wallets render it through a “Signature Request” modal — the raw data being signed, with no interpretation. Users would need to understand this new format on their own, and without wallet simulation showing how their balances will change, it’s easier to sign the wrong thing. For a system meant to bring new users to Ethereum, that’s a disaster.

Yes, it costs us extra circuit complexity (RLP parsing, keccak in-circuit), but that’s implementer pain, which scales better than user pain. The spec does anticipate adding an EIP-712 circuit later (same public-input interface, new circuitId) for wallets that build native privacy support and can meaningfully render the payload.

Precompiles

Fully agree — the proof verification precompile in this spec is intended to be generic. Any contract can call it with a circuitId and get back a verification result. The enshrined pool is just the first consumer.

An application-level pool would use it like this:

  1. Route proof verification through the precompile, passing in the user’s chosen circuitId.
  2. When a new circuit is available (e.g., secp256r1-based verification), the pool would not need to update. Instead, users would call the same pool function with the new circuitId as a parameter and a corresponding proof.

This precompile benefits the entire ecosystem, not just the enshrined pool.

Notably, I do not call for an EIP-5988-esque Poseidon precompile. Poseidon is actually not prohibitively expensive to compute in the EVM today, and as gas limits grow it may be cheaper to just increase chain throughput than to maintain a hashing precompile. So there’s exactly one new precompile in this spec.

On state growth: I completely agree!

And to your broader point — yes, the novelty here is making the pool socially governed, not inventing a new privacy model. This is deliberately de-risking: we’re enshrining something we already know works at the app layer (shielded pools, proof of innocence, UTXO notes), removing the governance-vs-ossification dilemma, and giving it a canonical anonymity set.

Thank you for your answers. Since we are aligned on precompiles and state growth, I will push back on synthetic transactions a little bit more.

UX-wise, it depends what wallet you are using, but even a pretty generic EIP-712 decoder can display you something akin to this:

Field Value
TYPE FacetPrivateTransfer(…)
CHAINID 11155111
ASSET 0x…
AMOUNT 1e18
BENEFICIARY kzg.eth

and wallets recognize and display addresses. OTOH with intent transactions, while it is a cool hack and a great demo, you see a cryptic chain id along with a transaction fee that you actually have to ignore. Even if we assume that we don’t modify wallets, it’s not so clearly preferable.

Furthermore, if we are going to enshrine something protocol-level, we can certainly expect wallets to have first-class support for it eventually. Wallet UX is malleable, while system contract are much harder to modify, so any UX benefit is temporary while the note format we chose will be here much longer.

On a different note, if there is a soundness bug and we have to fix the contract via hard fork, the problem will be that divine intervention takes time and publicity — exactly what you don’t want in this situation. At this rate the pool will be drained well before we can fork and it ends up kind of pointless. The only way I can think of to fix this is to introduce a semi-trusted council with the ability to pause zk proofs for at most 3 months while we wait for the fork. Of course they would have no other power and cannot freeze or steal funds. How this plays with core devs is another question entirely.

Given that there is a pause button, we can also introduce public exits as a last resort way to get funds out. The way it works is you submit all the merkle proof data publicly onchain and it proceeds the same as a withdrawal except without privacy. This is similar to ragequits in Privacy pools. Since there is no zk this is not affected by the pause.

If something is to be backstopped by social consensus, we need to make sure people are comfortable with it, and so it’s important to make it as simple as possible. For this, external ASP support is a great feature. If withdrawals have to be implemented once in-circuit and once in-EVM though, they especially need to be simple, and EIP-712 is better in that regard.

Taking a step back, it’s also worth noting that both systems assume addresses are EOAs, otherwise ECDSA signatures don’t work.

1 Like

In general I like the idea of enshrined note and nullifier trees that privacy protocols can build on to increase effective anonymity set sizes.

Some questions I have with this proposal:

  1. I don’t have a solution to this problem, but adding new authorisation circuits via hardforks feels risky. Every new authorisation circuit here adds a lot of risk since it requires hardforks, new consensus-critical code, and extensive auditing. Maybe private transfers should be designed to be post quantum secure from the beginning? Or should we instead pick a single, well-defined authorisation primitive and commit to it, with a single upgrade path to PQ, rather than designing for flexibility that requires an unspecified number of upgrades?

  2. Could you elaborate on how this proposal fits into Ethereum’s PQ roadmap? The EIP mentions post‑quantum signatures, but would be interested to know about how the full upgrade path would work.

  3. I don’t think state growth is a blocker, implementing data structures such as note and nullifier trees will always result in more state growth, and this might be the right model for L1 privacy. That said, state size is a bottleneck that should be managed even when accounting for the expected increase in state growth rate with scaling the L1, and we should look to minimise it where possible. It might be good to eventually have numbers on what the impact on state growth would be. And agree it would be useful to come to a decision on whether to use an accumulator-based nullifier design.

2 Likes

[Note: this post is based on an earlier version of the EIP. Changes have been made since then that obsolete some of the content.]

Thanks, @johnG and @bbjubjub!

On auth circuit risk and hard forks:

A well-defined, general authorization primitive is a good goal. Here’s how one could work within this framework. Split the auth circuit into an:

  • Outer circuit that enforces protocol-level invariants (value conservation, nullifier derivation, Merkle membership, encryption)

  • Inner circuit that handles only auth and intent parsing.

The outer circuit recursively verifies the inner circuit. A broken inner circuit can only prove false authorization claims — it can’t weaken value conservation or encryption because those are enforced by the outer circuit.

This setup would make it safe to allow permissionless inner circuits, and a new auth method would never require a hard fork.

The question is whether to build this recursive architecture for v0 or hard fork into it later. I think later:

  • Recursive proof composition in privacy systems is new. The monolithic approach uses the same proven cryptography as existing deployed systems. Less novelty means less risk for the version that needs to earn trust.

  • Hard forking into the recursive architecture has no major disadvantage — notes created by the v0 circuit are fully compatible with any future circuit.

On PQ roadmap fit:

The circuitId architecture lets a hard fork change the encryption scheme without changing the auth method. This matters because PQ encryption is more urgent than PQ auth — “harvest-now-decrypt-later” means pre-quantum ciphertexts are retroactively vulnerable even while ECDSA remains secure against online attacks. So the first PQ upgrade can add a circuit that pairs ECDSA auth with PQ encryption, without touching anything else.

Until a PQ encryption circuit is available, users should be aware that historical ciphertexts could eventually be decrypted by a quantum adversary.

This isn’t unique to the enshrined pool. Every privacy protocol deployed today faces the same exposure: a quantum adversary could decrypt Tornado Cash ciphertexts, and worse, forge Groth16 proofs by breaking the pairing assumptions, putting the entire TVL at risk. And Tornado Cash can’t upgrade.

An enshrined pool is better positioned to protect users against quantum risks than are app-level pools.

On state growth:

Following @bbjubjub’s argument, I believe that state growth per se isn’t the concern — the pool is an ordinary EVM contract from a state perspective, and existing strategies for managing high-usage contracts apply equally.

Once state growth is priced correctly, what does using the privacy pool cost? Moving to accumulator-based nullifiers would reduce storage but add significant circuit complexity, trading lower on-chain gas costs for higher proving costs. Whether that helps users depends on the tradeoff.

My inclination is to pursue cost reduction when it becomes a real problem. The note format doesn’t encode the nullifier storage mechanism, so this optimization can be introduced later without disrupting anything.

For the moment, the important thing is to ensure that the enshrined pool manages state growth at least as well as the alternatives (app-level pools) and I believe it does.

On EIP-712 vs type-2 intents:

Even if a wallet shows the EIP-712 struct in the most intuitive way, the UX will not be good unless the wallet understands the semantics of the signature.

E.g., when you sign to list an item for sale on OpenSea, wallets show you what the signature could cause: a loss of an NFT and a gain of ETH. Wallets do this because users can’t be expected to understand what a signature can do by inspection. This is particularly true here as, in all other contexts when a user is sending an ERC20, they expect the wallet to at the very least resolve the token name and symbol.

That said, you’re right that wallet UX is malleable and system contracts are not. We should absolutely expect wallets to build first-class support for an enshrined privacy pool. When they do, an EIP-712 circuit becomes a serious option — and the circuitId architecture lets us add one without changing anything else. A lighter EIP-712 circuit (smaller, cheaper, no RLP parsing or keccak) could coexist alongside Circuit A. Users with updated wallets use the EIP-712 circuit; everyone else stays on type-2 intents.

On soundness bugs, pause mechanisms, and public exits:

A soundness bug in the proof system could indeed allow an attacker to forge proofs and drain the pool before a hard fork is possible. A pause council could respond in seconds, but it would be virtually impossible to ensure that they only responded to soundness bugs, and not, for example, the desires of their local government (leaving aside even the nightmare scenarios of kidnapping etc).

Zcash doesn’t have a pause button either, and when they discovered an infinite counterfeiting vulnerability in their zk-SNARK construction, they fixed it through a scheduled upgrade without an emergency mechanism. Zcash had the advantage of being able to include the fix covertly, which Ethereum’s public hard fork process wouldn’t allow. But the enshrined pool is better positioned to tolerate that transparency: in Zcash, a counterfeiting bug lets an attacker mint unlimited fake tokens inside the shielded pool, and because the shielded supply is opaque, the damage is unbounded and undetectable. In the enshrined pool, an attacker can at most drain the pool’s actual token balance. No fake tokens enter the broader Ethereum economy. The damage is bounded by TVL and immediately visible on-chain.

2 Likes

@JohnG @bbjubjub

I rewrote the draft and now many of my earlier comments in this thread are no longer accurate! Here are the changes:

1. Recursive auth is now the v0 architecture.

I previously argued for a monolithic v0 and a later hard fork into recursion. I no longer think that is the right trade. I now think it is important not to require repeated hard forks for new auth methods, and not to split the anonymity pool by auth method.

2. The old synthetic-intent / Privacy RPC framing is gone from the spec.

I still think delegated proving and a Privacy-RPC-style UX are useful, but they do not belong in the base protocol. The draft still supports third-party proving; it just no longer bakes a specific delegated-proving UX into the protocol.

The only concrete auth flow in the spec is a simpler ECDSA / EIP-712 example, and that is just an example companion auth circuit, not the protocol’s required signing scheme.

3. Labels are narrower now.

Labels are no longer presented as a full proof-of-innocence / compliance system. They are a limited lineage primitive in the base layer. This feature can be extended in the future.

4. Issuer-specific visibility is out of the base draft.

I still think compliance-related extensions may matter, and I’m open to adding something back if we get clearer requirements. But issuer visibility felt too underspecified to enshrine now, especially without better evidence about what issuers actually want from the feature.

The rationale and security sections were also rewritten heavily, so a lot of the earlier discussion about synthetic transaction UX, circuitId, hard-forking in new auth methods, labels, and issuer visibility is now stale.

So if you read the thread from the top, please treat many of my earlier replies as superseded by the current draft.

Thanks again for your feedback! You showed me the error of my ways and the EIP is stronger because of it!

Updated PR: Add EIP: Protocol-Enshrined Privacy Pool by RogerPodacter · Pull Request #11373 · ethereum/EIPs · GitHub

3 Likes

Note: this post is based on an earlier version of the EIP. Changes have been made since then that obsolete some of the content.

S1nus wrote on the PR:

This mechanism is opinionated about note encryption, but not opinionated about secret dispersion: there is no description of where in the block the ciphertexts will live, or if wallets will have to perform trial decryption

Rather than enforcing a specific cipher for note encryption, maybe just leave that up to the wallet and fully decouple the shielded protocol from the payment protocol

Responding here:

On note discovery: fair point. The draft did specify that the ciphertexts are emitted in encryptedNoteData, but it did not state the wallet-side flow clearly enough. I’ve updated the draft to say that wallets discover incoming notes by scanning encryptedNoteData from each ShieldedPoolTransact event and trial-decrypting it with their viewing key material.

On decoupling encryption from the protocol: encryption correctness is enforced in the outer circuit because it means a transfer literally cannot succeed unless the recipient can recover the funds. A proof that encrypts incorrectly doesn’t verify. This is a nice property generally (it prevents users from accidentally burning funds), but it’s especially important for delegated proving as it ensures that a malicious prover can’t silently burn your recipient’s funds by producing garbage ciphertexts.

The tradeoff is that changing the encryption scheme requires a hard fork. But encryption schemes change much less frequently than auth methods, which is why auth is permissionless and encryption is fork-managed.

1 Like

I’ve reversed my position on in-circuit encryption.

Above I argued that the protocol should enforce correct encryption so that a valid transfer guarantees the recipient can decrypt. That’s a nice property, but the cost is too high.

There is a fundamental asymmetry between doing encryption and proving encryption. Encrypting something is cheap. Proving you encrypted correctly inside a ZK circuit is more expensive. By putting encryption in the circuit, the protocol can only use schemes that are cheap to prove, not schemes that are cheap to do.

This matters most for post-quantum encryption. Users should be able to adopt PQ encryption on day one. But if the protocol mandates proving encryption in-circuit, PQ adoption has to wait until someone figures out how to prove a PQ scheme cheaply.

Moving encryption out of the circuit removes this constraint.

The draft has changed substantially since my last update.

Please treat the current version of the EIP as canonical.

The updated FAQ also covers the current design.

The proposal is a lot cleaner without specifying the private rpc flow and reducing governance attack surfaces. Also agree with more limited compliance features without concrete compliance requirements.

My take is that a private transfer proposal at the L1 should also solve the following from day 1:

  • PQ secure: At the moment, the proof system in the outer circuit would need upgrading via hardfork to be PQ secure. Why not solve this now to align with the Ethereum post-quantum roadmap?
  • State growth: I do think a prerequisite is to consider state growth, and likely have a mechanism to scale the state growth of nullifiers and commitments.

Having some numbers to hand would aid reasoning about state growth. A nice next step could be to outline some scenarios. E.g. 10,000 private transfers a day leads to X number of commitments, and X amount of state growth.

Regarding scalability, have you thought about proof aggregation?

Hi middlemarch, building on your update around removing in-circuit encryption:

“moving encryption out of the circuit avoids constraining schemes (e.g. PQ) and significantly reduces proving cost”

This tradeoff makes sense at the protocol level. But it also shifts where complexity lives in practice.

Specifically, reducing circuit constraints tends to push more responsibility to the proving layer, and in many real-world settings this makes remote proving more likely than purely local proving.

That introduces a new concern:

Remote Proving as a Trust Surface

A remote prover necessarily has access to transaction inputs in order to construct the proof.

EIP-8182 leaves prover choice open (which is the right call for permissionlessness), and includes mitigations like rotating noteSecretSeed. But there is still an unresolved question:

How does a user—or more realistically, a wallet—distinguish between proving services with different privacy properties?

“Anyone can run a prover” ensures openness, but it doesn’t provide a way to reason about:

  • whether a prover logs or retains inputs

  • how its behavior evolves over time

  • how it compares to other available provers

another trusted third party, but without a standard way to make its assumptions explicit or comparable.

Toward a Proving Service Attestation Layer

One possible direction is a lightweight attestation layer for proving services, without changing EIP-8182 itself.

At a minimum, an attestation could commit to:

  • prover implementation/version

  • evaluation methodology

  • evaluator set and aggregation rule

  • observable properties (e.g. correctness rate, latency distribution)

For example:

struct ProverAttestation {

bytes32 implementationHash;

uint8   version;

bytes32 evaluationCommitment; // methodology + inputs + evaluators

}

The goal here is not to prove properties like non-logging (which is fundamentally hard to verify externally), but to:

  • make evaluation methodologies explicit

  • allow competing attestation frameworks

  • enable comparison across provers on consistent signals

In practice, this would likely be consumed by wallets or relayers when selecting proving services.

Mechanism

As a simple baseline:

  • N independent evaluators interact with a proving service

  • Each submits test workloads and verifies proof correctness

  • Metrics (failure rate, latency, etc.) are recorded

  • Final outputs are aggregated via median-of-N

  • The attestation commits to:

    hash(methodology || evaluatorSet || testInputs || aggregationRule)

This does not eliminate trust requirements entirely, but:

  • makes assumptions explicit

  • enables comparison across services

  • provides a foundation for stronger mechanisms (e.g. staking or reputation)

Interaction with the Current Design Direction

Framed this way, the tradeoff introduced by moving functionality out of the circuit becomes:

  • Lower circuit complexity / greater cryptographic flexibility (e.g. PQ)

  • Higher reliance on the proving layer in practice

An attestation layer doesn’t remove that tradeoff, but makes it:

an informed and observable choice, rather than a blind one

Open Questions

  • Is a standardized prover attestation format useful at the EIP level, or better handled at the wallet / relayer layer?

  • What observable properties of proving services are actually meaningful to standardize?

  • Should prover selection be abstracted away from users entirely?

Does this reintroduce trusted third parties at the prover layer?

I’ve been exploring one possible design for this kind of attestation layer (VPAI), but the main goal here is to surface the gap. One would expect multiple approaches to emerge.

Curious how others are thinking about prover trust given the direction toward lighter circuits and more flexible cryptography.

I am a privacy researcher in DeFi & DeFAI.

Quantum

Going PQ would mean switching to STARKs, which would make proof sizes massive; larger than the 128kb calldata size limit in my testing.

I think 8182 should align with the PQ roadmap in that its eventual PQ approach should be decided in tandem with Ethereum’s approach as a whole. Today we don’t know the exact form PQ Ethereum will take and so I think it’s premature to select an exact PQ proof system construction for 8182.

The question is whether we wait to launch until Ethereum PQ is figured out or launch with a classical system. My opinion is that private transfers are too important a feature to wait years to release. Also, it’s relevant that users probably do not want to wait and so will likely use classical systems that have worse PQ potential than the Ethereum protocol.

State Growth

Each transact adds 3 unbounded state entries:

  • 2 nullifier slots
  • 1 intent-replay-ID slot

Each entry is 64 bytes — a 32-byte slot value plus a 32-byte storage-trie key — so per tx that’s 192 bytes of new state.

  • 192 * 10k/day = ~1.9 MB/day
  • 192 * 10k * 365 = ~700 MB/year

This is around 1% of overall Ethereum state growth.

We could get rid of at least the 2 nullifier slots with a Tachyon-like approach that relied on users proving their notes hadn’t been nullifiied instead of the pool contract enforcing this. But this would make proofs more complicated.

Ultimately this might be a user research question: do users prefer (a) cheaper / easier proofs or (b) not paying for 3 permanent state entries (which might get more expensive as the L1 tries to keep state growth under control).

Also we could upgrade to Tachyon-style nullifiers in the future without invalidating existing notes or losing what notes are in the spent-set.

@arifa: Interesting idea! I think prover evaluation belongs outside the protocol on the app level. Also I think part of the evaluation can be systematized by using a prover with a TEE setup that guarantees (to the extent possible by TEEs) that they will obey your rules.

This is really interesting, I had a bunch of thoughts I wanted to share -

(1) I love the auth contracts & decoupling of view & write permissions. This enables stuff like multisig or timelock - controlled private balances natively, right? And lots more.

(2) If this were adopted I’d love to make it more compatible with paymasters and frame transactions so users can natively pay for private transactions natively. Current privacy protocols suffer from a double-validation issues because the paymaster can’t write the private operation in the validation phase. To fix this the interface could support splitting validation and execution into two calls, writing some 7562-compatible “approved“ flag in tstore for a given msg.sender + private transaction. Frame transaction support is more challenging due to gas restrictions, not sure how to solve that.

(3) I’m not sure why this is pushed as a system contract. An immutable smart contract offers the same trust model & censorship resistance, and this EIP doesn’t seem to do anything smart contracts can’t. System contracts are arguably more canonical, but an officially-endorsed smart contract gets the same thing.

(4) Since privacy protocols already exist, this seems politically challenging. I agree privacy is essential infrastructure and that having a canonical pool would be helpful, but I’m not sure if it’s viable. It feels akin to making a canonical DEX. The 4337 entrypoint feels most comparable as a piece of highly important infrastructure, but it’s not like 4337 competed with anyone.

(5) I’d like to re-visit state growth from a user perspective. For reference - I’m a contributor to Kohaku and have been working on the railgun impl. Syncing note-style privacy protocols generally require users to download and process the entire event history. This has high network and compute costs. For example, running natively in rust & syncing railgun on mainnet for a single account involved:

  • Downloading (220k commitments + 190k nullifiers = ) ~249.24 MB of event logs.
  • 10s to process the downloaded events (hashing and trial decryption).

Since old state is never pruned, wallets that are a few years old would have to sync increasingly large amounts of data to fetch their spendable balance. In practice it functionally necessitates some third-party indexing service (IE railgun’s subsquid).

(6) Compliance feels under-valued. In the FAQ you mentioned tracking disclosures through privacy pools and layering additional compliance protocols. In practice it seems like you’d need a small set of “canonical“ compliance systems. Since users opt-into compliance and different systems will probably be incompatible, having too many is logistically challenging and could lead to fingerprinting.

Thanks, @trebor this is very helpful! Taking it point by point:

(1) Yes! That is one of the intended benefits. Notes are not bound to one fixed signing method, so private balances can be controlled through multisig, timelocks, passkeys, etc. Users can also migrate to PQ auth methods without moving their notes.

(2) I agree native paymaster / frame-transaction support would be valuable. The current design should already support ordinary sponsorship: output slot 2 is reserved for an optional private fee note, so a prover, broadcaster, or sponsor can be compensated inside the same shielded note model.

The harder question is validation-time certainty. A paymaster wants to know before execution that the private operation will reimburse it. But a private spend depends on mutable pool state: accepted note roots, nullifiers, intent replay IDs, auth-policy roots, expiry, etc. So the challenge is giving the paymaster enough assurance during validation without forcing full double-validation or introducing an intermediate approval state whose guarantees are hard to define.

Given that, I’m not yet sure how tightly this can integrate with frame transactions, but I’m open to ideas!

(3) The system-contract choice is mainly about governance of the proof system.

An immutable contract removes upgrade-key risk, but it also freezes the proof system. That is a problem for long-lived privacy infrastructure, especially as cryptography changes and post-quantum migration becomes important. Existing immutable privacy pools, for example Tornado Cash, can only respond to a broken or obsolete proof system by migrating liquidity to a new pool. We should avoid this for the canonical privacy layer.

(4) I agree this is politically challenging, though I think a shielded pool’s built-in validity system creates a much higher burden for an app than does a DEX. For example, Ethereum DEXs do not (or shouldn’t) have to individually manage quantum risk.

I’d argue that a shielded pool is closer to an Ethereum rollup than a DEX, and our experience with the Rollup-centric Roadmap is instructive. We spent years hoping app-layer systems would independently converge toward Ethereum-equivalent safety and governance, and then only recently changed course. I don’t think Ethereum can afford to repeat the same path for privacy.

(5) A few issues come to mind:

First, trial decryption is not required by this EIP. The design is compatible with that model, but it does not enshrine it. There is no requirement that encrypted note data be posted on-chain. Wallets can deliver notes peer-to-peer or through other out-of-band channels. Trial decryption is the worst-case recovery path, not necessarily the normal path. That said, out-of-band note delivery can be annoying, so it would be good to have another option here, though I can’t think of one!

Second, EIP-8182 does have a witness-maintenance issue. To spend, a user does not only need to know their note; they also need to prove that the note exists in an accepted note-commitment root. Because the tree is append-only, the note’s position does not change, but the Merkle path to newer roots does. The current draft forces the user to prove against the current tree (with a root window), which means they have to compute the path to their notes as the tree evolves. So even if users share and store notes out of band this requirement could lead them to turn to an indexer.

One possible improvement would be an accumulator design for historical note roots, allowing users to prove inclusion against the post-insertion root from when the note was created. That would make peer-to-peer note delivery work better and reduce the need to track the live tree, but it adds complexity. I did not include that in the first draft, but I think it is worth considering.

For protocol state growth, the unavoidable issue is still unprunable nullifier-type data. I know Vitalik and others have proposed moving this kind of data to dedicated storage, but I think that would be a mistake, at least in the short term.

Keeping nullifiers in the EVM gives synchronous composability and implementation simplicity, which is especially valuable in the early stages.

(6) I agree compliance deserves more attention. Earlier versions included an optional field where users could mark a note as originating from a particular deposit, which could support provenance/compliance proofs. I removed it because I felt like designing a compliance primitive in the abstract risked permanently enshrining an approach that would not actually get used.

I do think canonical compliance standards would be useful, but I am still inclined to keep the base pool minimal and put disclosure formats, provenance proofs, and compliance workflows in companion standards. The purpose of 8182 is mainly to solve the governance, canonicity, and anonymity-set problem for the privacy protocol itself.

Why don’t use the orchard version of Zcash? The 2-2 transfer is pretty limited