PRIVACY WITH NATIVE AAResearch · 14 September 2026

Privacy with
native AA

Private ownership needs a private path to paying for execution.

StateAuthorizationComputationFees
PRIVACY WITH NATIVE AAContents

From the account model to native AA

Four parts. The native-AA section uses the specifications’ own frame and field names and ends on the 8130 / 8141 comparison.

I
The EVM account model
03
II
Privacy techniques: pools, RAILGUN and 0xbow, FHE, stealth addresses
04–07
III
Existing systems and how they pay for gas
08–12
IV
Native AA: 8130 and 8141 workflows, extensions, comparison
13–22
02 / 22
PRIVACY WITH NATIVE AAI · Account model

An account is not its token balance

State, authorization and computation are distinct parts of the EVM model.

State

What the account holds

  • nonce, ETH balance, codeHash, storageRoot
  • USDC balances live in the USDC contract’s storage
Authorization

Who may act

  • A signature authenticates the sender
  • Contract rules authorize token spending: transfer, allowance
Computation

What gets executed

  • The EVM runs the contract call
  • Execution reads and updates state
An ERC-20 balance is application state. ETH for gas is native account state, checked by the protocol before any contract code runs.
PRIVACY WITH NATIVE AAII · Privacy pool

How a privacy pool works: Tornado Cash

Deposit and withdrawal are public. The proof says only: I control one unspent note in this tree.

Original Tornado Cash: Alice deposits a fixed amount, public commitments accumulate in a pool, and a ZK proof authorizes a public withdrawal to Bob while hiding the matching deposit. Note secrets and the selected Merkle path stay private; the proof, root and nullifier hash are public.
PRIVACY WITH NATIVE AAII · Three pools compared

Same primitives. Three different proof statements.

Commitments, a Merkle tree, nullifiers and a ZK proof in all three. What each proof asserts is what each one hides.

Tornado Cash0xbow · Privacy PoolsRAILGUN
The proof says“I control an unspent deposit in this tree.”“…and its label is in the approved set.”“This private state transition is valid.”
Privacy setEvery deposit in the poolThe ASP-approved subset of depositsEvery shielded balance and transfer
A spend leavesA public withdrawal to a chosen addressA public withdrawal plus a change commitmentNew private notes, or a public unshield
Who can exclude youNobody: the pool holds no policyThe ASP revokes the label; ragequit exits publiclyA Broadcaster may decline; self-signing stays open
All three hide which input funded the spend. Only RAILGUN also hides the output; only 0xbow lets a third party decide whose input qualifies.
PRIVACY WITH NATIVE AAII · RAILGUN and public DeFi

RAILGUN: private balances, public execution

Private balance → Relay Adapt → ordinary EVM calls → private balance. Ownership is hidden; the calls are not.

One RAILGUN cross-contract transaction in three steps: an unshield of the exact declared amounts into the Relay Adapt contract with a 0.25% fee, an ordered multicall against ordinary public contracts that see Relay Adapt as their caller, and a shield of only the listed result tokens back into a private balance. Below, what stays private — the 0zk wallet, its balances and the UTXO graph — against what is public: every contract called, its calldata, the route and the amounts crossing the boundary.
PRIVACY WITH NATIVE AAII · FHE and stealth addresses

FHE hides values. Stealth addresses hide the recipient link.

The two techniques protect different parts of the same transfer.

Zama / ERC-7984 · FHE

Alice → Bob: encrypted amount

  • Public token contract and public addresses
  • Encrypted balances and arithmetic
  • Decryption follows an access-control policy
ERC-5564 · stealth address

Alice → fresh address B′

  • Bob derives B′’s spending key from a stealth meta-address
  • Public amount and token flow
  • Funding B′ with ETH for gas can reveal Bob again
Combine mechanisms when both the value and the identity link must be hidden.
PRIVACY WITH NATIVE AAIII · Two levels of authorization

The same account model applies at both levels

Account / state → auth → EVM. The pool’s contract logic runs inside the protocol’s execution step.

A pool proof authorizes the withdrawal. Protocol auth still requires a valid nonce and an ETH-funded fee payer.
PRIVACY WITH NATIVE AAIII · Zcash

Zcash: the fee is a value-balance residual

The fee is the value a spend does not hand to an output. ZIP-317 prices it by structure, not computation.

A shielded spend of one 10 ZEC note sending 3 ZEC: the hidden note amounts, their difference surfacing as the public valueBalanceOrchard of 0.0001 ZEC taken as the fee, and the ZIP-317 price beside it.
PRIVACY WITH NATIVE AAIII · Aztec

Aztec: many users, one public fee payer

Each user’s credit is a private note inside the same contract. The chain records the contract paying, not the user.

Private credit notes for Alice, Bob and Carol converge on one shared private fee-paying contract that holds the Fee Juice and nominates itself as payer; below, the single public observation against the three things that stay hidden.
PRIVACY WITH NATIVE AAIII · Aztec

Aztec: proving and spending that credit

mint proves the bridge claim against the nullifier tree. pay_fee() deducts from the note during setup.

Funding runs once per deposit: an L1 deposit made out to the contract, the Fee Juice claim nullifier in the tree, a mint call that rebuilds and asserts it before crediting a note. Spending runs every transaction: pay_fee deducts the maximum gas cost, the contract names itself payer, and the protocol charges it.
PRIVACY WITH NATIVE AAIII · Starknet

Starknet: a paymaster decouples payer from sender

AVNU’s paymaster submits apply_action through its forwarder and pays the STRK gas. That hop is also the censorship point.

Reviewed AVNU private flow · sponsored_private fee mode · API marked Preview
Wallet proves the pool action client-side
Paymaster forwarder submits apply_action and pays gas
Pool fee reimburses the paymaster

Two costs: STRK gas to the network, paid by the paymaster; the pool fee, paid from the private balance in poolFeeToken.

The decoupling

No public account is linked to the private balance

  • The fee payer is the paymaster; the actor is a shielded note
  • No personal STRK top-up, and apply_action carries no user signature
The cost

Inclusion runs through one permissioned service

  • x-paymaster-api-key is required for sponsored_private
  • Only a whitelisted pool; a blacklisted call returns UNKNOWN_ERROR
  • No documented unsponsored path: PRIVACY_REQUIRES_SPONSORING
PRIVACY WITH NATIVE AAIV · First principles

Three solution families

Who converts private value into a fee the protocol can collect?

ArchitectureHow it paysWhat it requires
Service fronts gasUser emits a private fee output; a relayer pays native gasA submitting service and a reimbursement policy
Native contract vaultA proof authorizes a shared native reserve; the user settles privatelyAdmissible validation and a durable fee entitlement
Native shielded fee validityThe protocol accepts a proof of conserved private value that includes the feeA shielded value / fee state transition in the protocol
For Ethereum native AA, the contract vault is the incremental design target.
PRIVACY WITH NATIVE AAIV · EIP-8130

8130: one transaction, two actors

The same RLP list names the account that authorizes the calls and the account that pays the ETH.

The AA_TX_TYPE 0x79 RLP field list in specification order, with sender and sender_auth shaded mint and payer and payer_auth shaded peach. Brackets carry the mint pair to a sender card that authorizes the calls and the peach pair to a payer card that pays the gas in ETH; both point at the protocol, which precharges the payer, runs the calls as the sender, and refunds the unspent gas limit.
PRIVACY WITH NATIVE AAIV · EIP-8130

8130: nothing changes until the payer is charged

Four mempool checks, then four block steps. The ETH precharge opens execution, before any calls run.

Eight numbered steps on one timeline. Steps one to four sit under a mempool acceptance band and change no state: authenticate the sender, authorize the payer, check nonce, payer ETH and the time window, and apply node pending limits. A dashed divider marks where block execution begins. Steps five to eight change state: precharge ETH from the payer, advance the nonce and delegation, run the call phases, settle and refund. Below the timeline a payer box sends ETH to a protocol box at step five, and the protocol returns the unspent gas limit at step eight.
PRIVACY WITH NATIVE AAIV · EIP-8130

8130: where a private fee falls out

Three obstacles, each one a rule of the draft rather than an implementation gap.

Three panels. Charged too early: a timeline shows the step five precharge before the step seven calls, with a dashed arrow back from the calls to the precharge, because the note arrives after the charge. Charged in public: a transaction receipt with the payer row highlighted, pointing to a box for indexers, explorers and anyone watching. Proved off the path: a dashed MAX_AUTHENTICATION_GAS ceiling over a short mint bar for the enshrined canonical set and a tall dashed peach bar for a note proof that must fit under it, with a note that canonical-only chains do not accept it on the 8130 path at all.
PRIVACY WITH NATIVE AAIV · EIP-8141

8141: a brand-new account spends from the pool

Six frames, three modes. Frame 2 is where the privacy pool pays the gas, before anything executes.

Six frame chips in one envelope, each tagged with its mode and filled by mode colour. Frame 0 deploy in DEFAULT mode creates the account B. Frame 1 only_verify in VERIFY mode with flags 0x2 targets B, checks the spend proof and sets sender_approved. Frame 2 pay in VERIFY mode with flags 0x1 targets the pool vault P, collects max_cost and sets payer to P; a dashed divider marks the end of the validation prefix. Frame 3 user_op in SENDER mode withdraws the tokens from the pool and writes the nullifier, frame 4 user_op spends them on the application in the same atomic batch, and frame 5 post_op in DEFAULT mode is optional settlement. A strip below names what moves: the fee out of the vault, the tokens to B, and the action B runs with them.
PRIVACY WITH NATIVE AAIV · EIP-8141 mempool

8141: three mempool rules, two proposed fixes

Each rule blocks the private spend for a different reason. Two have draft EIPs, the third an unmerged PR — and none of them makes the note spendable exactly once.

Three rows, one per public-mempool rule, each paired with the proposal against it. Row one: SLOAD is permitted only at tx.sender, even through CALL* or DELEGATECALL, so the pay frame cannot read the pool vault P’s own root or nullifiers; EIP-8272 answers it by moving the root into a canonical ring that one narrow frame verifies and the proof binds. Row two: MAX_VERIFY_GAS 100,000 gas and MAX_VERIFY_STATE_GAS 500,000 must cover the spend verifier alongside signature checks and 8272’s own frame; feasibility needs measurement; EIP-8288 answers it by taking the proof out of the EVM, declaring it in a mode-3 dependency frame priced at 30,000 gas per leanSTARK dependency. Row three: MAX_PENDING_TXS_USING_NON_CANONICAL_PAYMASTER is 1, so a proof-checking vault backs one pending spend pool-wide while the canonical exception wants an ecrecover signer instead; nothing is merged against it, and the row is marked with a cross. A panel below the three rows is headed even with all three fixed, the pool still has to spend its note once: a verified tuple proves a root was stored and is recent, never that the note is unspent, and VERIFY is a STATICCALL, so the nullifier SSTORE lands in a SENDER frame after pay collected max_cost.
PRIVACY WITH NATIVE AAIV · EIP-8272

8272: the root arrives as frame data

Mempool rule 1 blocks the read. 8272 removes the need for it.

Left, without 8272: the pay frame at the pool vault P has to read P’s own roots, which is storage outside tx.sender, so mempool rule 1 rejects the prefix and any helper it calls. Right, with 8272, three steps: the pool publishes its root with a CALL to RECENT_ROOT_ADDRESS, kept for 8192 slots; one canonical recent_root_verify frame verifies it with exactly two extra permissions; and account validation binds the verified tuple, handed forward as frame data, so P’s storage is never read. A closing strip notes that rules 2 and 3 still stand and that a recorded root is not current unspentness.
PRIVACY WITH NATIVE AAIV · EIP-8288

8288: make proof-heavy validation affordable

Aggregation is a cost mechanism; zero knowledge comes from the underlying proof.

Proposed aggregation path
DEP_VERIFY_FRAME_MODE frame (mode 3) declares (scheme, data_hash, verification_key_hash) triples
Mempool wrapper per AGGREGATION_INTERVAL: direct proofs or one recursive STARK
Block validity: one recursive STARK proves every dependency
Privacy relevance

Amortize repeated verification

  • Schemes: LEANSPHINCS_SCHEME signatures and LEANSTARK_SCHEME proofs against a shared verifier
  • Aggregation lowers the per-transaction cost, not the disclosure
Remaining work

Fit the whole validation prefix

  • Root checks, proof checks, calldata and state must fit MAX_VERIFY_GAS = 100,000 and MAX_VERIFY_STATE_GAS = 500,000
  • A cheap Merkle-proof estimate is not a ZK-verifier benchmark
PRIVACY WITH NATIVE AAIV · Compatibility status

These drafts are a design space, not a ready stack

Resolve the conflicts before claiming a working public-mempool protocol.

IssueWhy it mattersRequired resolution
Frame mode 3 claimed three times8288 DEP_VERIFY_FRAME_MODE, 8209 COMMIT and 7906 POST_TX cannot all be mode 3Agree a registry / mode allocation (PR 12253)
Stale introspection fieldsProof and intent adapters may inspect different dataAlign payloads and frame accessors (PRs 12309, 12322)
Failure semantics7906 prose conflicts; repayment preservation is pendingReconcile PR 12304 exemptions and PR 12266 approval effects
Unfinished admission details8272 runtime (RECENT_ROOT_CODE TBD), sealed payer and proof budget unprovenImplement, measure and test the composed rules
PRIVACY WITH NATIVE AAIV · Final comparison

8130 vs 8141: the privacy-relevant differences

Both separate sender and payer. The validation and payment interfaces differ.

Capability8130 · Keystore Accounts8141 · Frame Transaction
Authenticate / authorizeauthenticate(hash, data) → actorId; Keystore scope grants OPERATOR / POLICYonly_verifyAPPROVE(APPROVE_EXECUTION)
Authorize gas paymentpayer + payer_auth; SPONSOR_PAYER; ETH prechargepayAPPROVE(APPROVE_PAYMENT); collect max_cost
Execute the operationcalls: sequentially-committed atomic phasesuser_op in SENDER mode; optional atomic batches
Custom private fee proofPermissive acceptance policy: any authenticator via bounded STATICCALL; canonical-only path: noProgrammable VERIFY; public-mempool trace and payer rules still apply
Shared-root validationNo spec mechanism; a custom dependency policy is needed8272 recent_root_verify: an explicit, narrow exception
8130: depends on the chain’s authenticator acceptance policy (the L1 profile pairs with permissive). 8141: explicit frames and a clearer extension path, with fee safety and public-mempool admission unresolved.

← → to navigate · N for speaker notes · Print exports every slide · Research: 14 September 2026