EIP-2780 - Resource-based intrinsic transaction gas

Created 2020-07-11
Status Draft
Category Core
Type Standards Track
Authors
Requires

Abstract

This EIP decomposes the flat 21,000 intrinsic transaction cost into explicit primitives, each priced to match the resources a transaction actually consumes:

A plain ETH transfer to an existing account still costs 12,000 + 3,000 + 4,244 + 1,756 = 21,000 gas. The headline number is unchanged, but it is now built from measured components rather than a single legacy constant, so each transaction pays for the work it does and nothing it does not.

Transactions that grow the state — value transfers that create a new account and contract-creation transactions — additionally pay STATE_BYTES_PER_NEW_ACCOUNT × CPSB in state gas, per EIP-8037. These transactions therefore cost more than 21,000, internalizing the cost of state growth that the flat base previously left unpriced.

This EIP does not change calldata, access-list, or authorization metering.

Motivation

The flat 21,000 intrinsic cost charges every transaction the same amount regardless of what it does. A zero-value transaction to an existing account and a value transfer that creates a new account both pay 21,000, even though the latter touches an extra account, writes an extra balance, emits a log, and permanently grows the state. The single constant both over-prices the simplest paths and under-prices the ones that consume real, lasting resources.

This EIP replaces the constant with a decomposition into named primitives, each priced to the resource it represents. The goal is to make every transaction's intrinsic cost reflect its actual work:

Specification

Parameters

Name Value Definition
TX_BASE_COST 12,000 Sender cost: ECDSA recovery, the sender's account access, and the sender's account write
TX_VALUE_COST 4,244 Recipient balance write performed by a value transfer
TRANSFER_LOG_COST 1,756 EIP-7708 transfer log: GAS_LOG + 3 × GAS_LOG_TOPIC + 32 × GAS_LOG_DATA_PER_BYTE

The following values are referenced from other EIPs and are not final:

Regular-gas and state-gas semantics are defined by EIP-8037.

Intrinsic gas costs

A transaction's intrinsic base cost is decomposed into the following explicit primitives:

The tx.sender, tx.to, and (where applicable) delegation-target charges above are always at the cold rate. Access lists do not warm these transaction-level accounts; access-list warming applies only to subsequent execution-level touches.

These charges replace the contract-creation transaction charges. All other intrinsic costs (calldata, access list, and authorizations) remain unchanged.

Transaction's top-level gas costs

During execution, before any opcode is executed, the recipient account is loaded and the following gas costs are charged:

These charges are evaluated after EIP-7702 authorizations are applied. A tx.to whose account is materialized by an authorization in the same transaction is therefore no longer EIP-161-empty when this phase runs, so the new-account state charge does not fire; that account's creation is already priced by the authorization's PER_EMPTY_ACCOUNT_COST.

If a contract-creation transaction's initcode reverts, the transaction remains valid. In that case STATE_BYTES_PER_NEW_ACCOUNT × CPSB is not charged and is refilled to the state_gas_reservoir, per EIP-8037. A plain value transfer to a new account executes no code and so cannot revert; its new-account state charge is therefore never rolled back this way.

Transaction reference cases

Costs are split into regular gas and state gas, per EIP-8037. "execution" denotes contract execution charged at the standard schedule.

Case Regular gas State gas Regular gas value State gas value
ETH transfer to self TX_BASE_COST 0 12,000 0
No-transfer to EOA / empty account TX_BASE_COST + COLD_ACCOUNT_ACCESS 0 15,000 0
No-transfer to contract TX_BASE_COST + COLD_ACCOUNT_ACCESS + execution 0 15,000 + execution 0
ETH transfer to existing EOA TX_BASE_COST + COLD_ACCOUNT_ACCESS + TX_VALUE_COST + TRANSFER_LOG_COST 0 21,000 0
ETH transfer to contract TX_BASE_COST + COLD_ACCOUNT_ACCESS + TX_VALUE_COST + TRANSFER_LOG_COST + execution 0 21,000 + execution 0
No-transfer to 7702 delegated TX_BASE_COST + 2 × COLD_ACCOUNT_ACCESS + execution 0 18,000 + execution 0
ETH transfer to 7702 delegated TX_BASE_COST + 2 × COLD_ACCOUNT_ACCESS + TX_VALUE_COST + TRANSFER_LOG_COST + execution 0 24,000 + execution 0
ETH transfer creating new account TX_BASE_COST + COLD_ACCOUNT_ACCESS + TX_VALUE_COST + TRANSFER_LOG_COST STATE_BYTES_PER_NEW_ACCOUNT × CPSB 21,000 183,600
Create transaction, tx.value = 0 TX_BASE_COST + CREATE_ACCESS STATE_BYTES_PER_NEW_ACCOUNT × CPSB 23,000 183,600
Create transaction, tx.value > 0 TX_BASE_COST + CREATE_ACCESS + TRANSFER_LOG_COST STATE_BYTES_PER_NEW_ACCOUNT × CPSB 24,756 183,600

Interactions with other EIPs

Rationale

Pricing only the work each transaction does

The decomposition charges each primitive once, where the resource is consumed: signature recovery and the sender's access and write in TX_BASE_COST; the recipient touch in COLD_ACCOUNT_ACCESS; the recipient balance write in TX_VALUE_COST; the transfer log in TRANSFER_LOG_COST; and durable state creation in STATE_BYTES_PER_NEW_ACCOUNT × CPSB. A zero-value transaction pays only for the touches it makes, while a value transfer that creates an account pays for the new leaf it adds. This removes the cross-subsidy in the flat base, where simple transactions overpaid and state-creating ones underpaid.

The new-account state charge does not apply to CREATE/CREATE2: the GAS_CREATE opcode base already prices internal account creation, and top-level contract-creation transactions pay CREATE_ACCESS plus the same state-gas charge directly. Charging the state-growth cost on top-level value transfers that create accounts aligns them with the CALL-based creation path, which has always paid for the new leaf.

Deriving the decomposition from client runtimes

The values of TX_BASE_COST and TX_VALUE_COST are not set by intuition; they are derived from measured client execution times, using the same approach as EIP-8038.

The derivation uses the EELS test_ether_transfers_onchain_receivers benchmark, executed across all major execution-layer clients (Besu, Erigon, Geth, Nethermind, Reth). The benchmark fills blocks with ether transfers to four kinds of receiver, each exercising a different work path:

For each (client, receiver) pair, a non-negative least-squares (NNLS) model fits measured block runtime as a linear function of the number of transfers and the number of value-bearing transfers. The two fitted coefficients are the per-transfer base runtime and the additional runtime of moving value. Each coefficient is converted to gas at a fixed throughput anchor of 100 Mgas/s (gas = ceil(100,000 × runtime_ms)).

For any candidate target, the analysis surfaces each client's worst case across receiver types, separating clients that already meet the target from those that must optimize to reach it. The proposed TX_BASE_COST and TX_VALUE_COST are set as such targets: they align intrinsic cost with the resource usage of well-optimized clients while leaving slower clients a defined optimization goal.

The two empirical coefficients map onto the decomposition as follows:

COLD_ACCOUNT_ACCESS is taken directly from EIP-8038, since the recipient touch is the same cold-account access priced there, and TRANSFER_LOG_COST is fixed by the EIP-7708 log shape (see Transfer log cost). TX_BASE_COST and TX_VALUE_COST are the residual parameters this EIP introduces.

As in EIP-8038, these numbers are provisional. At the 100 Mgas/s anchor some clients are currently slower than the target on the heaviest paths and must optimize to meet it; the values will be refined as client optimizations land and the benchmarks mature.

Transfer log cost

TRANSFER_LOG_COST assumes a 32-byte log data payload because that is exactly the EIP-7708 transfer-log shape, not an arbitrary choice. The log is LOG3-shaped: three indexed topics (keccak256("Transfer(address,address,uint256)"), from, to) and a data field carrying a single uint256 wei amount. Indexed topics do not count as data bytes, so the only data payload is the 32-byte amount — always a full word, never variable length. Hence:

TRANSFER_LOG_COST = GAS_LOG + 3 × GAS_LOG_TOPIC + 32 × GAS_LOG_DATA_PER_BYTE = 375 + 3 × 375 + 32 × 8 = 1,756

Not metering the transaction envelope as calldata

Only tx.data bytes are metered at the calldata schedule; the envelope RLP (nonce, gas*, to, value, v, r, s) is not. Pricing full-transaction bytes would make intrinsic gas depend on gas_limit and variable-length signature elements — creating a fixed-point estimation problem, since gas_limit would depend on the signature, which itself encodes gas_limit — and would couple the fee to one serialization, weakening EIP-2718 type neutrality and future encodings. Treating calldata as opaque bytes avoids both issues. A plain ETH transfer carries empty tx.data and so pays zero calldata gas regardless.

Self-transfers

A self-transfer (tx.sender == tx.to) charges neither the recipient touch nor the value cost: the account is already accessed and written as the sender, and EIP-7708 emits no transfer log when sender and recipient coincide. Only TX_BASE_COST applies.

Backwards Compatibility

This EIP is not backward compatible. It is a consensus gas repricing that must be activated at a network upgrade. Wallets, RPCs, gas estimators, and any logic that assumes a flat 21,000 intrinsic base must update, particularly to account for the state-gas charge on transactions that create new accounts.

Test Cases

Intrinsic and top-level gas, by case:

  1. Self-transfer (from == to): 12,000.
  2. Zero-value transaction to any address (existing, empty, or contract): 15,000 regular (12,000 + COLD_ACCOUNT_ACCESS), 0 state. A self-target is 12,000.
  3. Value transfer to an existing EOA: 21,000 regular, 0 state.
  4. Value transfer creating a new account (empty per EIP-161): 21,000 regular, 183,600 state.
  5. Value transfer to a 7702-delegated account: 24,000 regular plus execution.
  6. Contract-creation transaction, value = 0: 23,000 regular, 183,600 state.
  7. Contract-creation transaction, value > 0: 24,756 regular, 183,600 state.
  8. EIP-7702 transaction: TX_BASE_COST is unchanged even when the sender assumes code; access-list and authorization costs are unchanged.
  9. Contract-creation transaction whose initcode reverts (value-bearing or not): the transaction remains valid; the 183,600 new-account state-gas charge is refilled to the reservoir.

Blocks of pure ETH transfers should be tested across all EL clients (e.g. on Perfnet) to confirm the pricing matches measured runtimes at the chosen throughput anchor.

Security Considerations

The decomposed charges sum to at least the legacy 21,000 for any transaction that moves value to a distinct account, and add state gas for transactions that grow the state. No path is cheaper than under the flat base in a way that increases per-block resource consumption; the change reallocates cost to match resources and prices state growth that was previously unpriced.

The semantics of SELFDESTRUCT are unchanged. Per EIP-6780, only contracts created within the same transaction may be fully deleted; this EIP does not reprice or modify any SELFDESTRUCT side effects.

Copyright

Copyright and related rights waived via CC0.