Skip to content

What Changed From Original to Latest ​


Structural Comparison ​

AspectOriginal (Jan 29)Latest (Oct 21)
OpcodesAPPROVE, TXPARAMLOAD, TXPARAMSIZE, TXPARAMCOPY (4)APPROVE (0xaa), TXPARAM (0xb0), FRAMEDATALOAD (0xb1), FRAMEDATACOPY (0xb2), FRAMEPARAM (0xb3), SIGPARAM (0xb4), SIGDATACOPY (0xb5) (7, #12187). Parameters are named TXPARAM_*/FRAMEPARAM_*/SIGPARAM_* (#12469). The 0xb5 collision ended when EIP-8272 dropped its opcode (#12281); EIP-7906 now holds 0xb6-0xb7
APPROVE mechanismReturn codes 0-4 at top-level frameTransaction-scoped with scope operand (0x1, 0x2, 0x3), callable at any depth, double-approval prevention. Failures revert only the current call frame (#12212), and payer/sender_approved roll back with a reverted call (#12458)
APPROVE scope0x0 (execution), 0x1 (payment), 0x2 (both)0x1 (payment), 0x2 (execution), 0x3 (both)
APPROVE restrictionMust be top-level frameADDRESS == frame.target only
Frame structure[mode, target, gas_limit, data][mode, flags, target, [execution_limit, state_limit], value, data] (mode/flags split, per-frame value, explicit two-dimensional gas)
Outer envelope signaturesNo outer signatures field; all signatures carried inside frame.data of VERIFY framessignatures outer-envelope list carrying (scheme, signer, msg, signature) entries. SECP256K1 and canonical low-s P256 are protocol-validated; ARBITRARY carries custom witness bytes for account-code validation and costs 100 gas per entry. Default code reads index 0 when approving execution and index 1 for payment-only approval. Forward-compat hook for PQ signature aggregation (PR #11481, repaired by #11837/#11814, sponsorship-restored by #11954, and hardened by #11976/#11984). Sibling EIP-8397 adds an AUTHENTICATOR (0x3) scheme
Mode fieldJust mode value (0, 1, 2)Pure mode (0, 1, 2) with separate flags field
Flags fieldN/ABits 0-1 = approval scope constraint; bit 2 = atomic batch flag, valid only for DEFAULT and SENDER
Frame modesDEFAULT, VERIFY, SENDERSame three modes plus an expiry-verifier shape (VERIFY with target == EXPIRY_VERIFIER). Validity is set membership, mode in (DEFAULT, VERIFY, SENDER), which siblings extend: ASSERT = 3 (EIP-7906), DEP_VERIFY = 4 (EIP-8288), COMMIT/REVEAL = 5/6 (EIP-8209) (#12453)
Atomic batchingNot supportedBit 2 of flags on DEFAULT/SENDER frames. VERIFY cannot participate in or terminate a batch, and no frame belonging to a batch may carry approval scope, including its terminating frame (#12109)
MAX_FRAMES10^3 (1,000)64
Per-frame costNoneFRAME_TX_PER_FRAME_COST = 475 gas
Fee-field boundsNot explicitEvery execution and blob fee field must be less than 2**256 (PR #12005)
Gas settlementOne gas limit with no cross-frame refund modelExplicit per-frame execution/state pools under EIP-8037; FRAME_TX_INTRINSIC_COST = 12,000; EIP-7825 caps intrinsic plus execution budgets; state gas remains frame-isolated; the EIP-7976 floor (uniform 64 gas per byte) applies to execution and net state gas is added; cross-frame state refills reduce the owning frame's receipt (#12062, #12209, #12395). Blocks count execution gas before refunds under EIP-7778 (#12226), and each frame pays its target's access at entry (#12211)
APPROVE gasN/ANo base gas cost; only memory expansion, matching RETURN (PR #12003)
Blob supportBlob hashes present only through inherited EIP-4844 contextFull KZG versioned-hash validation, BLOBHASH, EIP-7594 pooled-transaction wrapper, and payer blob-fee settlement (PR #11985)
EOA supportNoneDefault code: ECDSA secp256k1 verification in VERIFY only, with canonical v/r/low-s encoding. Execution approval uses tx.signatures[0]; payment-only EOA sponsorship uses index 1. P256 is protocol-validated in the outer list but not accepted by codeless EOA default code. SENDER and DEFAULT no longer revert (PR #11621): top-level value transfer to a default-code account completes. The earlier RLP-call-batch payload was removed by PR #11577 (Apr 29) once native batching plus per-frame value covered the multi-call use case
Signature hashVERIFY data NOT elided (bug)Raw sig.signature bytes are elided for signatures with empty msg; frame data stays covered. EIP-2718 type-byte prefix included (PR #11544, merged Apr 22). The Jul 6-7 repair (#11837/#11814) fixes the circular dependency introduced by the signatures-list merge
Receipt statusNot specified0x0 failure, 0x1 success, 0x2 skipped-batch (corrected by PR #11953, merged Jul 17)
Expiry mechanismNoneEXPIRY_VERIFIER = 0x81413f0c...FfFf, an ordinary contract deployed by Nick's method rather than installed at activation (#12387); an expiry-verifier VERIFY frame carries an 8-byte unix-seconds deadline as frame.data. Public-mempool admission MUST drop transactions whose expiry has passed; TIMESTAMP opcode gets a carve-out for this canonical runtime only. Public propagation requires the expiry frame to be first
Mempool policyNot defined (just "Security Considerations" section)Four prefixes, canonical paymaster, MAX_VERIFY_GAS = 100,000, MAX_VERIFY_STATE_GAS = 500,000, trace rules, deterministic replacement/eviction, per-payer exposure, and a producer-side bound on unpaid re-execution (#12213). The validation prefix is a consensus definition (#12471). SLOTNUM is banned; deterministic ORIGIN, TLOAD, TSTORE, and BLOBHASH are allowed (#12167)
Requires header2718, 48441559, 2718, 2780, 3529, 3607, 4844, 7594, 7702, 7708, 7778, 7825, 7976, 8037 (two-dimensional gas and value accounting added the August dependencies; EIP-7778 joined Aug 24 and EIP-7976 replaced EIP-7623 Sep 29)
EIP-3607 origination checkInherited unconditionally (would block contract-account senders)Carved out for frame transactions: SENDER frames may originate from contract accounts; non-frame txs unchanged (PR #11272, merged May 5)
Authors7 co-authors10 co-authors (derekchiang, nerolation, and svlachakis added)
ReceiptNot specified in detailIncludes payer and per-frame [status, [execution_gas, state_gas], logs]; no transaction-level status. Transaction logs concatenate frame logs in order, while failed-batch logs are discarded (#12008, #12061, #12062)
Initial warm stateInherited implicitlySender, coinbase, and active precompiles start warm; storage keys start cold (#12113). Each frame charges its resolved target's access at entry, which is how the payer warms (#12211)
SENDER frame requirementsCould execute without prior approvalRequires sender_approved == true
Value in framesNot in frame structurePer-frame value field; non-zero only in SENDER frames. DEFAULT/VERIFY observe CALLVALUE = 0
VERIFY frame behaviorState changes allowedBehaves as STATICCALL, no state changes. APPROVE requirement narrowed to self_verify/only_verify/pay shapes (PR #11662 relaxed the previous "every VERIFY frame must call APPROVE" rule to "if the frame reverts, the tx is invalid")
Target resolutionDirect use of frame.targetExplicit resolved_target (null target resolves to tx.sender); an active precompile target is dispatched as an ordinary call before the default-code check (#12157)
Deterministic deployerNot specifiedEIP-7997 is the canonical-but-optional factory; any stateless factory qualifies under the deploy-frame trace rules (PR #11567, merged Apr 30)
Deploy-frame mempool ruleN/ATrace-rule policy: write carve-out for CREATE/CREATE2/SETDELEGATE installing code at tx.sender and SSTOREs on tx.sender's storage; any contract may be frame.target (PR #11567)
Fork inclusion statusN/AScheduled for Inclusion (SFI) in Hegotá (PR #12251, merged Aug 27; CFI since Apr 30) and confirmed as the fork's headliner at ACDE #245
Sibling EIPsN/AEIP-8250, EIP-8266, EIP-8272, EIP-8288 (#11772, Sep 9), and EIP-8397 (#12244, Oct 14) are merged siblings; EIP-7906 and EIP-8209 extend the mode set. EIP-8272 now uses a canonical verify frame instead of an envelope field and opcode (#12281). EIP-8250, EIP-8272, and EIP-7906 are CFI for Hegotá

Key Philosophical Shifts ​

The overall trajectory: from expressive abstraction toward deployability, compatibility, and mempool safety. The early drafts prioritized flexibility; the later drafts constrain that flexibility into something the network can reason about.

1. From Smart-Account-Only to EOA-First ​

The original spec assumed users would have smart accounts. The latest spec makes EOAs first-class citizens with default code, recognizing that most users won't migrate to smart accounts immediately.

This was the single biggest change to the EIP's trajectory, driven by adoption concerns raised by DanielVF and derek's commercial AA experience showing that hardware wallets and most consumer wallets are slow/unwilling to adopt smart contract accounts.

2. From Minimal Mempool Guidance to Full Policy ​

The original spec had a brief "Security Considerations" section with general warnings about DoS vectors. The latest has a comprehensive mempool policy with:

  • Specific structural rules (four recognized validation prefixes)
  • Banned opcodes list
  • Gas caps (MAX_VERIFY_GAS = 100,000)
  • A canonical paymaster contract (removing ERC-7562's reputation/staking complexity)
  • Non-canonical paymaster handling
  • Explicit acceptance and revalidation algorithms

3. From Top-Level APPROVE to Transaction-Scoped APPROVE ​

Originally, approval status was determined by the return code of the top-level frame, similar to how RETURN works but with extended codes (2, 3, 4). This had several problems:

  • Proxy-based accounts couldn't adopt it (proxy returns 0 or 1)
  • APPROVE in nested calls required awkward propagation
  • Return codes >1 from CALL broke backwards compatibility assumptions

Now APPROVE is a dedicated opcode that updates transaction-scoped approval context (sender_approved and payer) directly, from anywhere in the call stack. It's cleaner and more compatible with existing smart account patterns.

4. From Generic TXPARAM Opcodes to Specialized Data Access ​

The original TXPARAMLOAD/SIZE/COPY trio treated all transaction parameters uniformly. The redesign recognized that:

  • Most parameters are scalar (32 bytes or less) → TXPARAM handles these
  • Only frame data is variable-length → FRAMEDATALOAD/FRAMEDATACOPY handle this

This is more gas-efficient and easier to reason about.

5. From No Batching Control to Explicit Atomicity ​

The original spec had no mechanism for atomic multi-call. The latest provides fine-grained control via the atomic batch flag in the flags field (originally bit 11 of the packed mode, now bit 2 of the separate flags after the mode/flags split), allowing users to specify exactly which SENDER frames must succeed together. This was a response to the universal expectation from developers that "if I'm batching operations, they should be atomic," while preserving the non-atomic default needed for paymaster patterns.

6. Mode/Flags Split and Signature Hash Repair ​

The original spec simply checked mode == VERIFY to elide frame data from the signature hash. An intermediate version packed flags into the upper bits of mode, requiring (frame.mode & 0xFF) == VERIFY to mask them out. PR #11521 split mode and flags into separate fields, but the July signatures-list repair changed the hash model again: frame data is now covered, while raw sig.signature bytes are elided for signature entries whose msg is empty. That moves self-referential witness data into the outer signatures list. SIGPARAM exposes metadata and witness length; SIGDATACOPY copies custom bytes with a static stack shape.

7. From "No Value Field" to Per-Frame Value ​

The original spec deliberately had no value field in frames, on the principle that account code could send ETH via its own call encoding. That rationale held as long as every user had a smart account capable of encoding sub-calls. As the spec shifted toward an EOA-first, good-out-of-the-box experience (see Phase 1), the case for native per-frame value became hard to resist: a simple ETH transfer should not require the sender to construct an RLP-encoded call list, and wallets should not have to ship batching boilerplate to achieve parity with a regular transaction. PR #11534 (Apr 16) added a value field to the frame tuple, restricted to SENDER frames so that VERIFY stays STATICCALL-like and DEFAULT does not require ENTRY_POINT to fund transfers. The original rationale section was renamed from "No value in frame" to "Per-frame value."

8. From One Gas Limit to Explicit Execution and State Budgets ​

The original frame carried one gas limit. PR #12062 split that field into per-frame execution and state budgets to align EIP-8141 with EIP-8037 while preserving isolation between mutually distrusting frames. The two pools never borrow from each other. This lets builders reserve block capacity exactly, lets validation code inspect later frames' budgets before approving, and prevents a user frame from consuming state gas reserved for a paymaster post-op. The tradeoff is a wider envelope, two-dimensional estimation, and journaled cross-frame attribution when later execution clears state created by an earlier frame.

9. From Protocol-Installed Contracts to Ordinary Deployments ​

The May expiry design installed verifier code at address(0x8141) when the fork activated. PR #12387 replaced that with a keyless Nick's-method deployment at a deterministic address, and EIP-8250 and EIP-8272 followed for their system contracts. The verifier is "not special in any way beyond the public mempool recognizing it": consensus treats it as any contract, and only mempool policy and optional direct evaluation know its code hash. The same instinct drove EIP-8272 to drop its envelope field and opcode for a canonical frame, and lightclient to reject expiry as a frame mode. Protocol objects change only when a frame cannot express the feature.


Active Proposals That May Change the Comparison ​

As of October 21, 2026, these open PRs may extend the comparison table:

ProposalPRImpact
Signature-length commitment#12502Would hash each elided signature's length into compute_sig_hash and price elided bytes by length, closing the payer-padding grief from post #167. lightclient planned to merge it after Breakout #7
Single max_fee budget#12414Would replace the three fee fields with [max_fee, max_priority_fee_per_gas], an EIP-7999-style wei budget, and change TXPARAM(0x04-0x06). Contested; goes to ACDE #248
Floor pricing for entries#12559Would charge every frame and signature entry's encoded length at 64 gas per byte
Signer key authority#12505Would retire protocol-signature authority for signers that adopted regular code, adding EIP-8038 signer-read pricing
Set code from default code#12506Would let a codeless EOA adopt code in place through EIP-8298 SETCODEFROM in a SENDER frame
Early rejection and payer revalidation#12321Would reorder admission so cheap checks precede simulation and make payer balance changes accounting-only
MAX_VERIFY_GAS as a floor#12301Would make 100,000 a propagation floor rather than a cap; devnets already use 500,000
Canonical paymaster bytecode#12041Would pin an assembled reference runtime and code hash for the canonical paymaster
Expiry valid_after#12252Would grow expiry data to 16 bytes with a lower time bound; stale since August
Keyed-nonce concurrency#12039EIP-8250 change that would permit more than one pending transaction per sender
Frame returndata opcodesUnder discussion (post #137)Proposed FRAMERETURNDATASIZE/FRAMERETURNDATACOPY to enable multi-step flows, no PR yet