This EIP defines a signature scheme for native Simple Serialize (SSZ) encoded transactions.
EIP-6404 introduces SSZ transactions by converting from RLP transactions. Defining a signature scheme for native SSZ transactions further reduces required conversions and unlocks the forward compatibility benefits of SSZ StableContainer
.
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.
Native SSZ transactions are based on the TransactionPayload
and Transaction
types defined in EIP-6404 and emit an EIP-6466 Receipt
. To distinguish native SSZ transactions from those converted from RLP, native SSZ transactions do not set an RLP TransactionType
in their TransactionPayload
.
All native SSZ transactions follow an identical scheme based on hash_tree_root
to compute their signing hash (sig_hash
) and unique identifier (tx_hash
).
Additional information is mixed into sig_hash
to uniquely identify the underlying specification and avoid hash collisions across different signature kinds. Vendor-defined networks MUST use a different DomainType
for signing custom transaction types.
Name | Value | Description |
---|---|---|
DOMAIN_TX_SSZ |
DomainType('0x00000080) |
DomainType for signing native SSZ transactions compatible with this EIP |
class ExecutionSigningData(Container):
object_root: Root
domain_type: DomainType
def compute_ssz_sig_hash(payload: TransactionPayload) -> Hash32:
return Hash32(ExecutionSigningData(
object_root=payload.hash_tree_root(),
domain=DOMAIN_TX_SSZ,
).hash_tree_root())
def compute_ssz_tx_hash(tx: Transaction) -> Hash32:
assert tx.payload.type_ is None
return Hash32(tx.hash_tree_root())
Certain JSON-RPC endpoints such as eth_getTransactionByHash
indicate the corresponding EIP-2718 envelope type prefix in a type
field.
When representing native SSZ transactions on such endpoints, SSZ_TX_TYPE
SHOULD be indicated as their type
, as defined in EIP-6404. Omitting the type
is NOT RECOMMENDED as certain client applications could confuse the omission with untyped LegacyTransaction
.
Transaction
profilesNew EIP-7495 Profile
definitions are introduced to represent native SSZ transactions:
BasicTransaction
shares the functionality of EIP-1559 fee market transactionsBlobTransaction
shares the functionality of EIP-4844 blob transactionsclass BasicTransactionPayload(Profile[TransactionPayload]):
chain_id: ChainId
nonce: uint64
max_fees_per_gas: BasicFeesPerGas
gas: GasAmount
to: Optional[ExecutionAddress]
value: uint256
input_: ByteList[MAX_CALLDATA_SIZE]
access_list: List[AccessTuple, MAX_ACCESS_LIST_SIZE]
max_priority_fees_per_gas: BasicFeesPerGas
class BasicTransaction(Container):
payload: BasicTransactionPayload
signature: Secp256k1ExecutionSignature
class BlobTransactionPayload(Profile[TransactionPayload]):
chain_id: ChainId
nonce: uint64
max_fees_per_gas: BlobFeesPerGas
gas: GasAmount
to: ExecutionAddress
value: uint256
input_: ByteList[MAX_CALLDATA_SIZE]
access_list: List[AccessTuple, MAX_ACCESS_LIST_SIZE]
max_priority_fees_per_gas: BlobFeesPerGas
blob_versioned_hashes: List[VersionedHash, MAX_BLOB_COMMITMENTS_PER_BLOCK]
class BlobTransaction(Container):
payload: BlobTransactionPayload
signature: Secp256k1ExecutionSignature
The identify_transaction_profile
helper from EIP-6404 is updated to support native SSZ transactions.
def identify_transaction_profile(tx: Transaction) -> Type[Profile]:
if tx.payload.type_ is None:
if tx.payload.blob_versioned_hashes is not None:
return BlobTransaction
return BasicTransaction
else:
if tx.payload.type_ == BLOB_TX_TYPE:
return RlpBlobTransaction
if tx.payload.type_ == FEE_MARKET_TX_TYPE:
return RlpFeeMarketTransaction
if tx.payload.type_ == ACCESS_LIST_TX_TYPE:
return RlpAccessListTransaction
if tx.payload.type_ == LEGACY_TX_TYPE:
return RlpLegacyTransaction
raise Exception(f'Unsupported transaction: {tx}')
The SSZ signature scheme reduces hashing overhead and ensures that tx_hash
commitments are available on-chain. It also provides a flexible basis for future transaction functionality.
The new transaction signature scheme is solely used for SSZ transactions and is represented using a different EIP-2718 envelope type prefix as existing RLP transactions.
SSZ signatures MUST NOT collide with RLP transaction and message hashes.
As RLP messages are hashed using keccak256, and all SSZ objects are hashed using SHA256. These two hashing algorithms are both considered cryptographically secure and are based on fundamentally different approaches, minimizing the risk of hash collision between those two hashing algorithms.
Furthermore, RLP messages are hashed linearly across their serialization, while SSZ objects are hashed using a recursive Merkle tree. Having a different mechanism further reduce the risk of hash collisions.
Copyright and related rights waived via CC0.