EIPs/EIPS/eip-2711.md
Micah Zoltu 42c9fe0e82
Automatically merged updates to draft EIP(s) 2711 (#2721)
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
2020-06-13 18:55:23 +12:00

11 KiB

eip title author discussions-to status type category created requires (*optional)
2711 Separate gas payer from msg.sender Micah Zoltu (@MicahZoltu) https://ethereum-magicians.org/t/eip-2711-separate-gas-payer-from-msg-sender/4353 Draft Standards Track Core 2020-06-11 2718

Simple Summary

Creates a new transaction type that allows for a second transaction signer who pays for gas, which is separate from the transaction signer who represents the msg.sender of the transaction.

Abstract

An EIP-2718 transactions with the type number 1 is a transaction that includes an additional signature from which the account that will pay for gas (GAS_PAYER) can be recovered. The transaction will otherwise operate the same as other transaction, except the GAS_PAYER will cover all gas costs, while the inner transaction signer will be the msg.sender for the transaction.

Motivation

With the advent of tokens and especially stable coins, it has become common for users to not hold ETH in an account while they may have other assets of value in that account. Some users don't want to be exposed to the perceived volatility of ETH and instead would prefer to transact using other assets. Unfortunately, since gas MUST be paid for with ETH, this prevents the user from transacting with their assets without first acquiring some ETH using some other means, and then using that ETH to pay fees.

This EIP proposes a mechanism by which we can allow people to transact without ever having to own any ETH by allowing someone else to cover gas costs. The arrangements that enable the covering of gas costs is out of scope for this EIP but it could be an extra-protocol monthly subscription, payment could occur as part of the transaction being submitted, the recpient may be willing to cover gas costs, or it could be a free service offered as a value-ad by a company that you are working with.

While it is possible to implement these sort of mechanisms at the individual contract layer, such solutions require integration by just about every contract and those solutions also end up depending on gas costs being stable with time in order to appropriately bake them into contracts without putting either party at risk of malicious participants in the system. For this reason, it is deemed beneficial that separating out GAS_PAYER from msg.sender at the protocol layer is valuable.

Specification

As of FORK_BLOCK_NUMBER an EIP-2718 transaction with a TransactionType of 1 will be interpreted as follows based on the value of the first item in the decoded RLP array:

  • [0, nonce, to, value, data, chainId, gasLimit, gasPrice, senderV, senderR, senderS, gasPayerV, gasPayerR, gasPayerS]
  • [1, nonce, to, value, data, chainId, gasLimit, senderV, senderR, senderS, gasPrice, gasPayerV, gasPayerR, gasPayerS]
  • [2, nonce, to, value, data, chainId, senderV, senderR, senderS, gasLimit, gasPrice, gasPayerV, gasPayerR, gasPayerS]
  • [3, nonce, to, value, data, senderV, senderR, senderS, gasLimit, gasPrice, gasPayerV, gasPayerR, gasPayerS]

senderV, senderR, senderS is a signature of an RLP array of the items preceding the sender signature items. The address recovered from this signature is the address returned by the CALLER opcode (0x33, aka msg.sender) for the first level of the transaction, and the address whose nonce is used, and the address whose ETH is deducted if any value is attached to the transaction. gasPayerV, gasPayerR, gasPayerS is a signature of an RLP array of the items preceding the gas payer signature items. The address recovered from this signature is the address returned by the ORIGIN opcode (0x32, aka tx.origin) for the transaction, and the address whose ETH balance the gas costs for the transaction are deducted from.

Both signatures for this transaction type have a v value that is either 0 or 1 and represents the parity of the y value of the ECDSA signing process.

Example

rlp([
	// EIP-2718 TransactionType
	1,
	[
		// EIP-2711 subtype
		1,
		// `SENDER` nonce
		3,
		// Destination of the transaction (`to` field)
		0xbaadf00dbaadf00dbaadf00dbaadf00dbaadf00d,
		// ETH attached to the transaction (will be transferred from the `SENDER` to the `to`)
		0,
		// Data attached to the transaction (`data` field)
		0x,
		// Chain ID that the transaction is valid on.  Transaction is invalid on any other chain.
		1,
		// The maximum amount of gas that this transaction can use
		500000,
		// The `y` parity bit (known as `v`) of the `SENDER`s signature of `rlp([0, 3, 0xbaadf00dbaadf00dbaadf00dbaadf00dbaadf00d, 0, 0x, 500000, 1])`
		0,
		// The `r` value of the `SENDER`s signature of `rlp([0, 3, 0xbaadf00dbaadf00dbaadf00dbaadf00dbaadf00d, 0, 0x, 500000, 1])`
		0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef,
		// The `s` value of the `SENDER`s signature of `rlp([0, 3, 0xbaadf00dbaadf00dbaadf00dbaadf00dbaadf00d, 0, 0x, 500000, 1])`
		0xcafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe,
		// The price per gas used by this transaction.
		1000000000,
		// The `y` parity bit (known as `v`) of the `SENDER`'s signature of `rlp([0, 3, 0xbaadf00dbaadf00dbaadf00dbaadf00dbaadf00d, 0, 0x, 500000, 1, 0, 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef, 0xcafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe, 1000000000])`
		1,
		// The `r` value of the `SENDER`'s signature of `rlp([0, 3, 0xbaadf00dbaadf00dbaadf00dbaadf00dbaadf00d, 0, 0x, 500000, 1, 0, 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef, 0xcafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe, 1000000000])`
		0xbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead,
		// The `s` value of the `SENDER`'s signature of `rlp([0, 3, 0xbaadf00dbaadf00dbaadf00dbaadf00dbaadf00d, 0, 0x, 500000, 1, 0, 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef, 0xcafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe, 1000000000])`
		0xbabecafebabecafebabecafebabecafebabecafebabecafebabecafebabecafe
	]
])

Rationale

ChainID not encoded with v

While we could save one byte in the common case by bundling the y-parity bit of the signature with the Chain ID like in EIP-155, this adds complexity to signing tools that the authors deem not worth it given the size (in bytes) of the transaction overall.

Optional ChainID for subtype 3

Sometimes it is useful to have a transaction that can be replayed on multiple chains. An example of this is when you construct a vanity signature for a transaction and have the from be whatever address that signature recovers to. With the ability to have someone else be a gas payer (setting both the gas limit and the gas price), one can have transactions that deploy contracts which live at the same address on every chain. While this can be accomplished with CREATE2 using legacy transactions, we have the opportunity here to simplify the process and enable potentially other future uses of deterministic transactions by making ChainID optional.

SENDER sets gasLimit and gasPrice

This type of transaction is useful when the transaction may execute differently depending on what these values are set to. By having the SENDER set both, we ensure that the SENDER has full control over the transaction details.

SENDER sets gasLimit, GAS_PAYER sets gasPrice

This type of transaction is useful when the transaction may execute differently depending on how much gas it is allowed (e.g., number of loops) but where the SENDER would like to give the GAS_PAYER the ability to price the transaction to maximize chances of inclusion.

GAS_PAYER sets gasLimit and gasPrice

This type of transaction allows the SENDER to define what they want to do, and leaves all worry about gas to the GAS_PAYER. This is useful for transactions where the sender doesn't care how much gas is used or the price that is paid and also either trusts the GAS_PAYER to be non-malicious or doesn't care if the SENDER's nonce is increased. Such situations are useful when you have extra-protocol trust between the SENDER and GAS_PAYER and you want to separate concerns (what to do vs how to get included) for security or complexity reasons.

Nonces

The inner transaction needs a nonce to protect themselves from replay attacks. Since the inner transaction has a nonce, we get replay protection on the outer transaction as well, so it is not critical for security to have multiple parties provide a nonce.

We could have the GAS_PAYER provide a second nonce, but this would increase the payload size and require GAS_PAYER to do replace-by-fee (noisy for gossip) if they want to slip in a new (different inner) transaction with a higher gas price. It would also create the possibility of a deadlock if the SENDER nonces aren't ordered the same as the GAS_PAYER nonces, and if the SENDER nonce isn't the lowest valid nonce for the SENDER then the GAS_PAYER can't sign and submit yet. Finally, client complexity increases slightly if a transaction has two nonces because you have to protect yourself from deadlocks and do more work to determine validity.

Backwards Compatibility

The ORIGIN opcode currently has a note in the Yellow Paper that reads:

This is the sender of original transaction; it is never an account withnon-empty associated code.

The "sender of the original transaction" is a bit more ambiguous as of this EIP. While we call the account whose nonce is used and whose ETH balance value is withdrawn from the SENDER, that is merely a colloquiale term and no longer normative as of this EIP since a transaction of this type has two signers. It is possible that there are deployed contracts who expect ORIGIN to be the same as the CALLER of the first call frame, and that would no longer be true for these transactions.

Test Cases

Implementation

Security Considerations

Copyright and related rights waived via CC0.