EIP 2542: New opcodes TXGASLIMIT and CALLGASLIMIT Source

AuthorAlex Forshtat
Discussions-Tohttps://ethereum-magicians.org/t/eip-2542-add-txgaslimit-callgaslimit-txgasrefund-opcodes
StatusDraft
TypeStandards Track
CategoryCore
Created2020-02-29

Simple Summary

A mechanism to allow smart contracts to access information on gas limits for the current transaction and execution frame.

Abstract

Currently, there is an existing opcode 0x45 GASLIMIT that provides access to the block gas limit. While this information may be useful in some cases, it is probably not a value that smart contract developers may be concerned about. The opcode 0x5a GAS provides the remaining gas, not the initial one. Also, it is worth noting how existing 0x32 ORIGIN, 0x33 CALLER, 0x34 CALLVALUE and 0x3a GASPRICE opcodes set a pattern of having access to both the transaction and current execution frame state. TBD: as 0x30 opcode range is exhausted, the proposed opcodes can be added to 0x50 range, or a new range can be added.

Motivation

As concepts of relaying, meta-transactions, gas fees, and account abstraction gain popularity, it becomes critical for some contracts to be able to track gas expenditure with absolute precision. Without access to this data on an EVM level, such contracts resort to approximation, mimicking EVM logic on-chain, and some use-cases even become infeasible.

Specification

If block.number >= TBD, add three new opcodes:

TXGASLIMIT: 0x5c

Pushes the gas limit of the entire transaction onto the stack. This is a value of the ‘startgas’ parameter signed by the externally owned account.
Gas costs: 2 (same as GASLIMIT)

CALLGASLIMIT: 0x5d

Pushes the gas limit of the current execution frame onto the stack. This is the ‘callGas’ value that was obtained after the application of the EIP-150 “all but one 64th” rule.
Gas costs: 2 (same as GASLIMIT)

Also, consider renaming 0x45 GASLIMIT to BLOCKGASLIMIT to avoid confusion.

Rationale

Consider a solidity smart contract that wants to know how much gas the entire transaction or a part of it had consumed. It is not entirely possible with the current EVM. With proposed changes, using a pseudo-Solidity syntax, this information would be easily available:

function keepTrackOfGas(string memory message, uint256 number) public {
    ...
    uint gasUsed = msg.gasLimit - gasleft();
}

This is an extremely common use case, and multiple implementations suffer from not taking the non-accessible expenses into consideration. The state-of-the-art solution for the gasUsed problem is to access ‘gasleft()’ as the first line of your smart contract.
Note how variable transaction input size means the gas used by the transaction depends on the number of zero and non-zero bytes of input, as well GTXDATANONZERO. Another issue is that Solidity handles public methods by loading the entire input from calldata to memory, spending an unpredictable amount of gas.

Another application is for a method to have a requirement for a gas limit given to it. This situation arises quite commonly in the context of meta-transactions, where the msg.sender’s account holder may not be too interested in the inner transaction’s success. Exaggerated pseudocode:

function verifyGasLimit(uint256 desiredGasLimit, bytes memory signature, address signer, bytes memory someOtherData) public {
    require(ecrecover(abi.encodePacked(desiredGasLimit, someOtherData), signature) == signer, "Signature does not match");
    require(tx.gasLimit == desiredGasLimit, "Transaction limit does not match the signed value. The signer did not authorize that.");
    ...
}

In this situation it is not possible to rely on ‘gasleft()’ value, because it is dynamic, depends on opcode and calldata pricing, and cannot be signed.

Backwards Compatibility

This proposal introduces two new opcodes and renames an existing one, but stays fully backwards compatible apart from that.

Forwards Compatibility

A major consideration for this proposal is its alignment with one or many possible future modifications to the EVM:

  1. EIP-2489 Deprecate the GAS opcode (a.k.a. 39-UNGAS proposal)
    There is a sentiment that the ability of smart contracts to perform “gas introspection” leads to the contracts being dependent on current opcode pricing.
    While criticizing said misconception is beyond the scope of this EIP, in case there is a need to make a breaking change to the behavior of the existing 0x5a GAS opcode, the same considerations will apply to the proposed opcodes. This means this EIP does not add any new restraints on EMV evolution.

  2. Stateless Ethereum
    The UNGAS proposal is said to be related to the ongoing project of Stateless Ethereum. It’s not strictly necessary for stateless Ethereum, but it is an idea for how to make future breaking changes to gas schedules easier.
    As long as the concept of ‘gas limit’ is part of the EVM, the author sees no reason proposed opcodes would conflict with Stateless Ethereum. Gas schedules are not exposed by this proposal.

  3. Comparison with other controversial opcodes
    There are opcodes that are not proposed for deprecation but face criticism. Examples include 0x32 ORIGIN being misused by smart contract developers, or 0x46 CHAINID making some smart-contracts ‘unforkable’.
    This EIP neither encourages nor enables any bad security practices, and does not introduce any concepts that are new for EVM either.

Security considerations

Existing smart contracts are not affected by this change.
Smart contracts that will use proposed opcodes must not use them for the core of any security features, but only as a source of information about their execution environment.

Implementation

The implementations must be completed before any EIP is given status “Final”, but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of “rough consensus and running code” is still useful when it comes to resolving many discussions of API details.

Copyright and related rights waived via CC0.