Hi, I'm a bot! This change was automatically merged because: - It only modifies existing Draft or Last Call EIP(s) - The PR was approved or written by at least one author of each modified EIP - The build is passing
6.3 KiB
eip | title | author | discussions-to | status | type | category | created | requires (*optional) |
---|---|---|---|---|---|---|---|---|
2718 | Typed Transaction Envelope | Micah Zoltu (@MicahZoltu) | https://ethereum-magicians.org/t/eip-2718-typed-transaction-envelope/4355 | Draft | Standards Track | Core | 2020-06-13 | 155 |
Simple Summary
Defines a new transaction type that is an envelope for future transaction types.
Abstract
As of FORK_BLOCK_NUMBER
, rlp([TransactionType, Payload])
will be a valid transaction where TransactionType
is a number identifying the format of the transaction and payload
is the transaction, whose definition is defined in future EIPs. The first new transaction type will be a wrapped legacy transaction with the format rlp([0, rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])])
.
Motivation
In the past, when we have wanted to add new transaction types we have had to ensure they were backward compatible with all other transactions, meaning that you could differentiate them based only on the encoded payload, and it was not possible to have a transaction that matched both types. This was seen in EIP-155 where the new value was bit-packed into one of the encoded fields. There are multiple proposals in discussion that define new transaction types such as one that allows EOA accounts to execute code directly within their context, one that enables someone besides msg.sender
to pay for gas, and proposals related to layer 0 multi-sig transactions. These all need to be defined in a way that is mutually compatible, which quickly becomes burdensome to EIP authors and to clients who now have to follow complex rules for differentiating transaction type.
By introducing an envolope transaction type, we only need to ensure backward compatibility with existing transactions and from then on we just need to solve the much simpler problem of ensuring there is no numbering conflict between TransactionType
s.
Specification
As of FORK_BLOCK_NUMBER
, rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])
(legacy transaction) will no longer be a valid Ethereum transaction over the devp2p protocol or in a block.
As of FORK_BLOCK_NUMBER
, all transactions sent over devp2p or included in a block MUST be of the form rlp([TransactionType, Payload])
where TransactionType
is a number that represents the type of the transcation and Payload
is an opaque value (byte array) whose interpretation is dependent on the TransactionType
. Transactions SHOULD include the TransactionType
in any signatures they include to minimize the chance of unintentional replay attacks between different transaction types.
As of FORK_BLOCK_NUMBER
, rlp([0, rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])])
will be a valid transaction where the Payload
will be processed/handled exactly the same as legacy transactions were processed/handled.
Rationale
TransactionType high bit
Setting the high bit of the TransactionType
so that a decoder could identify transaction type early on in the decoding process was discussed, but decided against. The problem with this solution is that due to the way RLP encoding works, this would result in the TransactionType
being 5 bytes long rather than 1 byte long. RLP decoders also do not need to know the shape of the result before decoding, and thus in most (possibly all) clients it will be just be a matter of first decoding the RLP transaction, and then checking to see if the decoded result is a 2 item array or a 9 item array, which is likely simpler than checking the high bit of the first item.
TransactionType selection algorithm
There was discussion about defining the TransactionType
identifier assignment/selection algorithm in this standard. While it would be nice to have a standardized mechanism for assignment, at the time of writing of this standard there is not a strong need for it so it was deemed out of scope. A future EIP may introduce a standard for TransactionType identifier assignment if it is deemed necessary.
Opaque second item rather than an array
By having the second item of the array just be opaque bytes, rather than a list, we can support different encoding formats for the transaction payload in the future, such as SSZ or a fixed width format.
n
-item list instead of 2-item list
We could have chosen the format rlp([TransactionType, ...])
where ...
represents whatever items the transaction wants. This format however would require us to remain vigilant in the future about using the shape of the transaction to identify its type, as it is possible that there could be an overlap between an EIP-2718 transaction type and a legacy transaction type with a nonce that matches the TransactionType
. By having a strict 2-item array with the second item potentially being an encoded list, we avoid needing to worry about any conflict between TransactionTypes beyond choosing uinque numbers.
ORIGIN and CALLER
There was discussion about having ORIGIN and CALLER opcodes be dependent on the transaction type, so that each transaction type could define what those opcodes returned. However, there is a desire to make transaction type opaque to the contracts to discourage contracts treating different different types of transactions differently and there also were concerns over backward compatibility with existing contracts which make assumptions about ORIGIN and CALLER opcodes. Going forward, we will assume that all transaction types will have an address that reasonably represents a CALLER
of the first EVM frame and ORIGIN
will be the same address in all cases. If a transaction type needs to supply additional information to contracts, they will need a new opcode.
Backwards Compatibility
Clients can differentiate between the transaction types by noting that the RLP decoded transaction has 2 elements rather than 9.
Test Cases
TBD
Implementation
TBD
Security Considerations
Due to the way RLP encoding works, the risk of a new transaction being mis-interpreted as a legacy transaction is deemed low. The authors of this EIP consider it unlikely that there are any transaction decoders in production that will accept a transaction with not enough elements (perhaps reading off the end of the array).
Copyright
Copyright and related rights waived via CC0.