EIP-8141: Frame Transactions
Status: Design phase. Gap analysis complete against the existing RIP-7560 AA implementation. Depends on: Modular Transaction Pipeline. Required by: Interop Bridge Phase 3+.
EIP-8141 implements protocol-native account abstraction directly in the EVM — no application-layer bundlers (ERC-4337) required. It introduces frame transactions (type 0x06): a transaction envelope containing an ordered sequence of execution frames, each running in a distinct execution context.
Erigon already has a complete RIP-7560 native AA implementation. EIP-8141 is built on top of it, reusing the existing ApplyFrame() engine, paymaster pattern, ERC-7562 opcode validation, and EIP-7702 delegation support.
Frame Execution Model
Each frame in a transaction runs in a distinct execution context:
| Frame type | Execution context | Purpose |
|---|---|---|
| VERIFY | Restricted opcodes; checks APPROVE result | Custom signature/authorization validation |
| SENDER | Restricted opcodes | Determines the effective sender (paymaster, sponsor, or delegated account) |
| DEFAULT | Normal EVM execution | The actual user operation |
Frames execute sequentially. If VERIFY fails, the entire transaction is invalid. There is a single transaction hash, a single receipt, and a single nonce increment. The APPROVE opcode is a new EVM instruction — only valid inside VERIFY frames — for custom signature validation.
This enables protocol-native account abstraction without application-layer bundling (ERC-4337).
Existing Foundation: RIP-7560
What EIP-8141 reuses from the existing RIP-7560 implementation:
| Capability | RIP-7560 location | Reusable for EIP-8141 |
|---|---|---|
| Frame execution engine | ApplyFrame() in state_transition.go | Yes — same sub-call-without-gas-buy pattern |
| Multi-frame sequencing | ValidateAATransaction + ExecuteAATransaction | Refactored into generic pipeline |
| Paymaster pattern | PaymasterFrame + PaymasterPostOp | SENDER frame with paymaster logic |
| ERC-7562 mempool validation | ethBackend.AAValidation() | Extended for APPROVE opcode |
| EIP-7702 delegation | Authorizations field | Same support |
| Block builder AA path | block_assembler.go:213 | Generalized |
Design: Frame Pipeline Engine
Rather than adding EIP-8141 as a parallel code path alongside RIP-7560, both are unified in a single frame pipeline engine:
// execution/protocol/frames/pipeline.go
type FramePipeline struct {
evm *vm.EVM
gasPool *GasPool
ibs *state.IntraBlockState
}
func (p *FramePipeline) Execute(frames []Frame) ([]FrameResult, error) {
results := make([]FrameResult, 0, len(frames))
for _, frame := range frames {
var result FrameResult
switch frame.Type {
case FrameVerify:
result = p.executeVerify(frame)
if !result.Approved {
return results, ErrVerifyFailed
}
case FrameSender:
result = p.executeSender(frame)
case FrameDefault:
result = p.executeDefault(frame)
}
results = append(results, result)
}
return results, nil
}
RIP-7560 transactions (type 5) are adapted via RIP7560ToFrames() — their implicit frame sequence is converted to an explicit []Frame and executed through the same pipeline. Zero behavior change for existing AA transactions.
EIP-8141 Transaction Type
const FrameTxType = 6
type FrameTransaction struct {
TransactionMisc
ChainID *uint256.Int
Nonce uint64
Tip *uint256.Int
FeeCap *uint256.Int
GasLimit uint64
Frames []TxFrame
AccessList AccessList
Authorizations []Authorization // EIP-7702 support
}
type TxFrame struct {
Type uint8 // 0=VERIFY, 1=SENDER, 2=DEFAULT
To common.Address
Data []byte
GasLimit uint64
Value *uint256.Int
}
APPROVE Opcode
A new EVM opcode — only valid inside VERIFY frames. If called outside a VERIFY context, it errors. The frame pipeline checks whether APPROVE was invoked to determine whether the VERIFY frame approved the transaction.
The opcode number and exact semantics are pending finalization of the EIP-8141 spec.
Gap Analysis
The gaps vs the existing RIP-7560 implementation:
| Gap | Description |
|---|---|
| Explicit frame array | RIP-7560 has implicit frames derived from fixed fields; EIP-8141 has a user-defined []Frame |
| APPROVE opcode | New EVM opcode — consensus change; must be hardfork-gated |
| Frame type dispatch | VERIFY and SENDER frames need opcode restrictions (ERC-7562-style); DEFAULT is unrestricted |
| Txpool parsing | Frame array must be parsed from RLP into TxnSlot with frame metadata |
| Mempool validation | Frame sequence well-formedness; APPROVE only in VERIFY; total gas limits |
| Receipt format | Per-frame gas usage and status |
Integration with Interop Bridge
The Interop Bridge's FrameTxAssembler constructs EIP-8141 transactions programmatically:
Cross-chain operation from wallet
→ VERIFY frame: validate merkle proof + signature
→ SENDER frame: CrossChainPaymaster.lockFunds()
→ DEFAULT frame: user's actual call
The bridge submits these via TxInjector.Submit() into the local mempool. The frame pipeline engine executes them during block building.
Implementation Phases
| Phase | Scope |
|---|---|
| 1 | Extract generic FramePipeline; refactor RIP-7560 to use it internally — zero external behavior change |
| 2 | FrameTransaction struct (type 6); RLP encoding; txpool parsing; state processor routing; block builder handling |
| 3 | APPROVE opcode; frame-context tracking in EVM; hardfork gate |
| 4 | Full mempool support — ERC-7562 opcode restrictions for VERIFY/SENDER frames; frame gas estimation; parallel execution support |
| 5 | Bridge service integration — FrameTxAssembler builds and submits frame transactions |