Linear hashing: The signing hash (sig_hash) and unique identifier (tx_hash) of an RLP transaction are computed by linear keccak256 hashes across its serialization. Even if only partial data is of interest, linear hashes require the full transaction data to be present, including potentially large calldata or access lists. This also applies when computing the from address of a transaction based on the sig_hash.
Inefficient inclusion proofs: The Merkle-Patricia Trie (MPT) backing the execution block header’s transactions_root is constructed from the serialized transactions, internally prepending a prefix to the transaction data before it is keccak256 hashed into the MPT. Due to this prefix, there is no on-chain commitment to the tx_hash and inclusion proofs require the full transaction data to be present.
Incompatible representation: As part of the consensus ExecutionPayload, the RLP serialization of transactions is hashed using SSZ merkleization. These SSZ hashes are incompatible with both the tx_hash and the MPT transactions_root.
Technical debt: All client applications and smart contracts handling RLP transactions have to correctly deal with caveats such as LegacyTransaction lacking a prefix byte, the inconsistent chain_id and v / y_parity semantics, and the introduction of max_priority_fee_per_gas between other fields instead of at the end. As existing transaction types tend to remain valid perpetually, this technical debt builds up over time.
Inappropriate opaqueness: The Consensus Layer treats RLP transaction data as opaque, but requires validation of consensus blob_kzg_commitments against transaction blob_versioned_hashes, resulting in a more complex than necessary engine API.
This EIP addresses these by defining a lossless conversion mechanism to normalize transaction representation across both Consensus Layer and Execution Layer while retaining support for processing RLP transaction types.
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Existing definitions
Definitions from existing specifications that are used throughout this document are replicated here for reference.
Transaction signatures are represented by their native, opaque representation. ECDSA signatures are no longer split up into r, s, and y_parity components.
RLP transactions are converted to a normalized SSZ representation. Their original RLP TransactionType is retained to enable recovery of their original RLP representation and associated sig_hash and historical tx_hash values.
In the engine API, the semantics of the transactions field in ExecutionPayload versions adopting this EIP are changed to emit transactions using SSZ serialization.
transactions - Array of DATA - Array of transaction objects, each object is a byte list (DATA) representing ssz.serialize(tx)
Consensus ExecutionPayload changes
When building a consensus ExecutionPayload, the transactions list is no longer opaque and uses the new Transaction type, aligning the transactions_root across execution blocks and execution payloads.
The proposed transaction design is extensible with new fee types, new signature types, and entirely new transaction features (e.g., CREATE2), while retaining compatibility with the proposed transactions.
Verifier improvements
Future RPC could expose an SSZ based tx_root on top of the tx_hash, against which proofs can be validated. The transactions_root can now be reconstructed from the list of tx_root. Further, partial data becomes provable, such as destination / amount without requiring the full calldata. This can reduce gas cost or zk proving cost when verifying L2 chain data in an L1 smart contract.
Consensus client improvements
Consensus Layer implementations may drop invalid blocks early if consensus blob_kzg_commitments do not validate against transaction blob_versioned_hashes and no longer need to query the Execution Layer for that validation. Future versions of the engine API could be simplified to drop the transfers of blob_kzg_commitments to the EL.
Backwards Compatibility
Applications that rely on the replaced MPT transactions_root in the block header require migration to the SSZ transactions_root.
While there is no on-chain commitment of the tx_hash, it is widely used in JSON-RPC and the Ethereum Wire Protocol to uniquely identify transactions. The conversion from RLP transactions to SSZ is lossless. The original RLP sig_hash and tx_hash can be recovered from the SSZ representation.
RLP and SSZ transactions may clash when encoded. It is essential to use only a single format within one channel.