EIP-2718: Typed Transaction Envelope

0x32: ORIGIN: tx.origin

Smart contract developers have been told for a long time to avoid using the ORIGIN opcode and static analysis tools tend to warn when it is used. Most uses of it are people attempting to author contracts that disallow contract callers, which goes against the ethos of Ethereum (IMO) and goes against the idea that contracts can own and manage money. Contracts that disallow contract callers discourage the usage of smart wallets, which tend to have enhanced security features for end users thus preventing their usage decreases end-user security.

With the introduction of multiple types of transactions, it is possible that the definition of ORIGIN may change over time, or differ between transaction types. EIP-2711 for example will likely assert that ORIGIN is the GAS_PAYER, rather than the SENDER. One can imagine a multisig transaction type where multiple signatures control the operation of a single account, or rich transactions where an account with a private key can have a contract gating its operations. In these cases, what ORIGIN means may vary slightly, and currently the EVM doesn’t have insight into the type of transaction.

Potential Solution

Change opcode 0x32 to be TRANSACTION_DATA, where the first 32 bits are the transaction type, and the remaining 224 bits are defined per TransactionType. For TransactionType 0 (wrapped legacy transactions), this would be backward compatible since currently TRANSACTION_DATA would be an address, which has 96 leading 0 bits. For TransactionType 1 (EIP-2177), the value would be something like 0x000000010000000000000000cafebabecafebabecafebabecafebabecafebabecafebabe where the first 32-bits is the TransactionType (1 in this case) and the remaining 224 bytes would be an Ethereum address representing GAS_PAYER. This would allow the EVM to both identify what type of transaction is running, and also have a small amount of transaction-type specific data available to it. Some transaction types may have no data, in which case it would just be 32 high bits containing the transaction type and the rest of the bits would be 0.

Backward Compatibility

This does potentially have a backward compatibility issue with existing contracts that reference tx.origin, but since the high bits are the transaction type we don’t have to worry about collisions with actual addresses for anything other than legacy transactions, which would retain the old semantics of ORIGIN means transaction signer.

For new type transactions, they’ll just fail all comparisons of tx.origin and any Ethereum address. There is potential that there are contracts which store tx.origin of some original caller and then require the same tx.origin later. If a non-0 type transaction was used for the first and a 0 type transaction was used for follow-ups this won’t match. Also, if you do something like an EIP 7211 transaction you may end up with different GAS_PAYERs and would not match.

Personally, I have lobbied long and hard against contracts that use tx.origin for basically anything, so I don’t have a problem finally breaking people who have failed repeatedly to heed the warnings. Also, such contracts CAN just tell their users to only use legacy type transactions and they will continue to work, so it isn’t like we would be sticking people’s funds in a way that was unpreventable for existing contracts.

1 Like