EIP-2718: Typed Transaction Envelope


Before This EIP
Prior to EIP-2718, transactions were simply RLP-encoded data beginning with values in the range [0xc0, 0xfe]
, as specified in RLP encoding rules. There was no mechanism to distinguish between different transaction types or handle them uniquely, despite a clear need for such functionality. Without a way to differentiate transactions, establishing rules for their identification would have been complex and prone to errors.
How This EIP Works
With EIP-2718, a valid transaction is now structured as TransactionType || TransactionPayload
, and a valid transaction receipt is TransactionType || ReceiptPayload
.
[ ||
represents the concatenation operator ]
Here,
TransactionType
is a value in the range[0, 0x7f]
.TransactionPayload
andReceiptPayload
are RLP-encoded byte sequences.
Both the transaction type and its associated payload are specified in future EIPs whenever a new transaction type is introduced.
Now, clients (i.e., nodes) can differentiate transactions based on their starting byte:
If a transaction begins with a value in
[0, 0x7f]
, it is recognized as a typed transaction.If it starts with
[0xc0, 0xfe]
(per RLP encoding rules), it is treated as a legacy transaction.
Inside the Block
For Transactions:
patriciaTrie(rlp(Index) => Transaction)
Where:Index
is the transaction’s position within the block.Transaction
can be eitherTransactionType || TransactionPayload
(for typed transactions) orLegacyTransaction
(for legacy transactions).LegacyTransaction
is an RLP-encoded payload without a transaction type, starting with[0xc0, 0xfe]
as per RLP rules, i.e.,rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])
.
For Receipts:
patriciaTrie(rlp(Index) => Receipt)
Where:Index
is the receipt’s position in the receipt Merkle tree.Receipt
can be eitherTransactionType || ReceiptPayload
(for typed receipts) orLegacyReceipt
(for legacy receipts).LegacyReceipt
is encoded asrlp([status, cumulativeGasUsed, logsBloom, logs])
.
Additionally, the TransactionType
of a receipt must match the TransactionType
of the corresponding transaction with the same Index
.
Security Considerations
For any transaction compatible with EIP-2718, users must sign both the type and the payload together. If a user signs only the payload and prepends the type before broadcasting it to the network, the transaction could be interpreted as a legacy transaction. This is a critical requirement—signing both type and payload prevents compatibility with other transaction types, which could otherwise lead to a signature malleability attack.
Subscribe to my newsletter
Read articles from Anmol Dhiman directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Anmol Dhiman
Anmol Dhiman
Prev - @kleros || ETHBangkok'24 🏆 || ETHIndia'23 🏆 || SSIP AKAMH'22 🏆 || Blockchain Security Researcher