diff --git a/EIPS/eip-2733.md b/EIPS/eip-2733.md index 2bad51d8..da021a4a 100644 --- a/EIPS/eip-2733.md +++ b/EIPS/eip-2733.md @@ -12,7 +12,7 @@ requires: 2718 ## Simple Summary Creates a new transaction type which executes a package of one or more -transactions. +transactions, while passing status information to subsequent transactions. ## Abstract After `FORK_BLOCK`, a new [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) @@ -25,18 +25,23 @@ the next transaction. Meta-transaction relay contracts have historically been designed to catch reversions in their inner transactions by only passing a portion of the available gas to the subcall. This has been considered bad practice for a long -time, but in the case of untrust subcalls -- it is the only available solution. -Transaction packages are an alternative solution which allow multiple -transactions to be bundled into one package and executed atomically. +time, but in the case of untrusted subcalls, like the ones relay contracts +make, it is the only available solution. Transaction packages are an +alternative that allow multiple transactions to be bundled into one package and +executed atomically, similarly to how relay contracts operate. Transactions are +able to pass their result to subsequent transactions. This allows for +conditional workflows based on the outcome of previous transactions. Although +this functionality is already possible as described above, workflows using +transaction packages are more robust, because they are protected from future +changes to the gas schedule. ## Specification ### Definitions - ``` N = TBD transaction type number INTRINSIC_COST = TBD -TOTAL_COST = INTRINSIC_COST + inner_txs.reduce(|itx, acc| acc += itx.value + itx.gas_price * itx.gas_limit) +TOTAL_COST = INTRINSIC_COST + inner_txs.reduce(|itx, acc| acc += itx.value + tx.gas_price * itx.gas_limit) TOTAL_GAS_LIMIT = inner_txs.reduce(|itx, acc| acc += itx.gas_limit) TX_HASH = hash of transaction as defined below SENDER = ecrecover(hash, v, r, s) @@ -47,21 +52,22 @@ RESULT = result as defined below for the previous transaction, empty if its the After `FORK_BLOCK`, a new [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) transaction type `N` will be interpreted as follows: -`rlp([N, rlp([nonce, v, r, s, [inner_tx_0, ..., inner_tx_n]])` +`rlp([N, [v, r, s, chain_id, nonce, gas_price, [inner_tx_0, ..., inner_tx_n]])` where `inner_tx_n` is defined as: -`[chain_id, to, value, data, gas_limit, gas_price]` +`[to, value, data, gas_limit]` ### Hashing The hash of transaction type `N` is defined to be the Keccak-256 hash of the -rlp encoding of the entire transaction with `v`, `r`, and `s` values omitted. +rlp encoding of the entire transaction with `v`, `r`, and `s` values set to +zero. ### Results Subsequent transactions will be able to receive the result of the previous transaction via `RETURNDATACOPY (0x3E)` in first frame of exeuction, before -making any subcalls. Each element except the last will be `0`-padded left to 32 -bytes. +making any subcalls. Each element, except the last, will be `0`-padded left to +32 bytes. | Name | Type | Description | |---|---|---| @@ -72,27 +78,25 @@ bytes. | `return_value` | bytes | The return value of the previous transaction ### Validation - * (v, r, s) are a valid signature of the hash of the transaction * The nonce is one greater than recovered address' current nonce * The recovered address has a balance of at least `TOTAL_COST` * The `TOTAL_GAS_LIMIT` is less than the current block's `gas_limit` ### Execution - Transaction packages should be executed as follows: 1. Deduct `TOTAL_COST` from `SENDER`'s balance 2. Execute the first inner transaction in the list 3. Refund any unused `gas` -4. If there are no more transaction, stop -5. Compute `RESULT` for the previously executed transaction -6. Prepare `RESULT` to be available via return opcodes in the next +4. Record all state changes, logs, and the receipt +5. If there are no more transaction, stop +6. Compute `RESULT` for the previously executed transaction +7. Prepare `RESULT` to be available via return opcodes in the next transaction's first frame -7. Execute the transaction +8. Execute the next transaction 9. Goto `3` - ## Rationale #### Non-recursive inner transactions @@ -102,16 +106,12 @@ suppose there is a transaction type which can become invalid after a certain block number. It would be beneficial to support those types of transactions within a package, but the complexity of this EIP would dramatically increase. - #### Appending result data to transaction input data An alternative to using return opcodes to propagate `RESULT` would be to append the `RESULT` to the subsequent transaction's `data` field. Unfortunately, in many cases contracts generated using Solidity [will fail](https://solidity.readthedocs.io/en/v0.6.0/contracts.html#overload-resolution-and-argument-matching) -to resolve the intended function if additional data is present. Another -alternative is introducing new opcodes to expose the result data were not -proposed. - +to resolve the intended function if additional data is present. ## Backwards Compatibility Contracts which rely on `ORIGIN (0x32) == CALLER (0x33) && RETURNDATASIZE