Skip to content

Latest commit

 

History

History
132 lines (103 loc) · 4.74 KB

eip-2733.md

File metadata and controls

132 lines (103 loc) · 4.74 KB
eip title author discussions-to status type category created requires
2733
Transaction package
Matt Garnett (@lightclient)
Draft
Standards Track
Core
2020-06-16
2718

Simple Summary

Creates a new transaction type which executes a package of one or more transactions.

Abstract

After FORK_BLOCK, a new EIP-2718 transaction of type N is recognized. Transactions of type N will define a list of transactions, which must be executed serially by clients. Execution information (e.g. success, gas_used, etc.) will be propagated forward to the next transaction.

Motivation

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.

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_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)
RESULT = result as defined below for the previous transaction, empty if its the first tx in a package

Serialization

After FORK_BLOCK, a new EIP-2718 transaction type N will be interpreted as follows:

rlp([N, rlp([nonce, v, r, s, [inner_tx_0, ..., inner_tx_n]])

where inner_tx_n is defined as:

[chain_id, to, value, data, gas_limit, gas_price]

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.

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.

Name Type Description
success bool Status of the previous transaction
gas_used uint256 Total gas used by the previous transaction
cum_gas_used uint256 Cumulative gas used by previous transactions
return_size uint256 The size of the return value
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 transaction's first frame
  7. Execute the transaction
  8. Goto 3

Rationale

Non-recursive inner transactions

For simplicity, inner transactions are fully defined within this EIP. However, there is value in supporting recursive transaction definitions. For example, 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 to resolve the intended function if additional data is present. Another alternative is introducing new opcodes to expose the result data were not proposed.

Backwards Compatibility

Contracts which rely on ORIGIN (0x32) == CALLER (0x33) && RETURNDATASIZE (0x3D) == 0x00 will now always fail in transaction packages, unless they are the first executed transaction. It's unknown if any contracts conduct this check.

Test Cases

TBD

Implementation

TBD

Security Considerations

TBD

Copyright

Copyright and related rights waived via CC0.