Skip to main content

Execution Gas

Gas is a sum of IntrinsicGas and ExecutionGas. In here, we would focus on how ExecutionGas is calculated.

note

Execution gas related hardfork changes can be found at the bottom of this page. Go to Hardfork Changes.

Overview

Execution gas is charged during executing a contract under three distinct circumstances. Sometimes, some policies may be omitted.

  • The first and most common is the constantGas. It's a fee intrinsic to the computation of the operation.
  • Second, gas may be deducted to form the payment for a subordinate message call or contract creation; this forms part of the payment for CREATE, CALL and CALLCODE.
  • Finally, gas may be charged due to an increase in memory usage.

Over an account's execution, the total fee payable for memory-usage payable is proportional to the smallest multiple of 32 bytes that are required to include all memory indices (whether for read or write) in the range. This fee is paid on a just-in-time basis; consequently, referencing an area of memory at least 32 bytes greater than any previously indexed memory will result in an additional memory usage fee. Due to this fee, it is highly unlikely that addresses will ever exceed the 32-bit bounds. That said, implementations must be able to manage this eventuality.

Storage fees have a slightly nuanced behavior. To incentivize minimization of the use of storage (which corresponds directly to a larger state database on all nodes), the execution fee for an operation that clears an entry from storage is not only waived but also elicits a qualified refund; in fact, this refund is effectively paid in advance because the initial usage of a storage location costs substantially more than normal usage.

Opcode Gas Schedule

The fee schedule G is a tuple of 37 scalar values corresponding to the relative costs, in gas, of a number of abstract operations that a transaction may incur. Also, there's gas items to calculate the gas of the precompiled contracts called by CALL_* opcodes.

Scalar values representing constantGas of an opcode

NameValueName in codeOpcodes
G_base2GasQuickStepADDRESS, ORIGIN, CALLER, CALLVALUE, CALLDATASIZE, CODESIZE, GASPRICE, COINBASE, TIMESTAMP, NUMBER, PREVRANDAO(originally it was DIFFICULTY), GASLIMIT, RETURNDATASIZE, POP, PC, MSIZE, GAS, CHAINID, BASEFEE, PUSH0, BLOBBASEFEE
G_verylow3GasFastestStepADD, SUB, LT, GT, SLT, SGT, EQ, ISZERO, AND, OR, XOR, NOT, BYTE, CALLDATALOAD, MLOAD, MSTORE, MSTORE8, PUSH, DUP, SWAP, BLOBHASH, MCOPY
G_low5GasFastStepMUL, DIV, SDIV, MOD, SMOD, SIGNEXTEND, SELFBALANCE
G_mid8GasMidStepADDMOD, MULMOD, JUMP
G_high10GasSlowStepJUMPI
G_selfdestruct5000SelfdestructGasSELFDESTRUCT
G_warmStorageReadCost100WarmStorageReadCostEIP2929EXTCODECOPY, EXTCODESIZE, EXTCODEHASH, BALANCE, CALL, CALLCODE, STATICCALL, DELEGATECALL, TSTORE, TLOAD
G_blockhash20GasExtStepBLOCKHASH
G_jumpdest1JumpdestGasJUMPDEST
G_sha330Sha3GasSHA3
G_create32000CreateGasCREATE, CREATE2

Scalar values used to calculate the gas based on memory and log usage

NameValueName in CodeDescription
G_memory3MemoryGasAmount of gas paid for every additional word when expanding memory
G_copy3CopyGasPartial payment for COPY operations, multiplied by words copied, rounded up
G_log375LogGasPartial payment for a LOG operation
G_logdata8LogDataGasAmount of gas paid for each byte in a LOG operation's data
G_logtopic375LogTopicGasAmount of gas paid for each topic of a LOG operation

Scalar values used to calculate the gas of the particular opcode

NameValueName in CodeDescription
G_sset20000SstoreSetGasAmount of gas paid when the storage value when set storage
G_sreset5000SstoreResetGasAmount of gas paid when the storage value remains unchanged at zero or is set to zero
G_coldSloadCost2100ColdSloadCostEIP2929Amount of gas paid when the storage value is not in accessList
R_sclear15000SstoreClearsScheduleRefundEIP3529G_sreset - G_coldSloadCost + TxAccessListStorageKeyGas (1900)
G_exp10ExpGasPartial payment
G_expbyte50ExpBytePartial payment when multiplied by ceil(log_256(exponent))
G_selfdestruct5000SelfdestructGasAmount of gas paid for a SELFDESTRUCT operation
G_callvalue9000CallValueTransferGasAmount of gas paid for a nonzero value transfer
G_callstipend2300CallStipendFree gas given at beginning of call for a nonzero value transfer
G_newaccount25000CallNewAccountGasAmount of gas paid when creating an account. It is also be defined as CreateBySelfdestructGas with SELFDESTRUCT operation.
G_codedeposit200CreateDataGasAmount of gas paid per byte for a creating a contract that succeeds in placing code into state
G_sha3word6Sha3WordGasAmount of gas paid for each word (rounded up) for an SHA3 input data
G_InitCodeWord2InitCodeWordGasAmount of gas paid for each word of initcode for a CREATE,CREATE2

Precompiled contracts gas cost table

Precompiled contracts are special kind of contracts which usually perform complex cryptographic computations and are initiated by other contracts.

Below is the gas cost table for precompiled contracts in Klaytn. Input is a byte array input of a precompiled contract.

AddressPrecompiled contractsGas Cost
0x01ecrecover3,000
0x02sha256hashnumOfWords(input) * 12 + 60
0x03ripemd160hashnumOfWords(input) * 120 + 600
0x04dataCopynumOfWords(input) * 3 + 15
0x05bigModExpsee the code here
0x06bn256Add150
0x07bn256ScalarMul6,000
0x08bn256PairingnumOfPairings(input) * 34,000 + 45,000
0x09blake2fbigEndian(getRounds(input[0:4]))
0x0Akzg50,000
0x3FDvmLoglen(input) * 20 + 100
0x3FEfeePayer300
0x3FFvalidateSendernumOfSigs(input) * 5,000

Gas calculation logic for contract execution

The gas cost of one transaction is calculated through the methods described below. First, gas is added according to the transaction type and input. Then, if the contract is executed, opcodes are executed one by one until the execution ends or STOP operation appears. In the process, the cost is charged according to the constantGas defined for each opcode and the additionally defined gas calculation method.

Here, I will briefly explain the gas calculation logic during contract execution using the fee schedule variables defined above. As this explanation assumes a general situation, the unusual situations such as revert appears is not considered.

  • add constantGas defined in each opcode to gas
    • e.g. if an opcode is MUL, add G_low to gas
    • e.g. if an opcode is CREATE2, add G_create to gas
  • add the gas which is calculated through additionally defined gas calculation method
    • For LOG'N', where N is [0,1,2,3,4], add G_log + memoryGasCost * g_logdata + N x G_logtopic to gas
    • For EXP, add G_exp + byteSize(stack.back(1)) x G_expbyte to gas
    • For CALLDATACOPY or CODECOPY or RETURNDATACOPY, add wordSize(stack.back(2)) x G_copy to gas
    • For EXTCODECOPY,
      • add wordSize(stack.back(3)) x G_copy to gas
      • [eip2929] If an address is not in AccessList, add it to accessList and add G_coldSloadCost - G_warmStorageReadCost to gas
    • For EXTCODESIZE or EXTCODEHASH or BALANCE,
      • [eip2929] If an address is not in AccessList, add it to accessList and add G_coldSloadCost - G_warmStorageReadCost to gas
    • For SHA3, add G_sha3 + wordSize(stack.back(1)) x G_sha3word to gas
    • For RETURN, REVERT, MLoad, MStore8, MStore, add memoryGasCost to gas
    • For CREATE, add memoryGasCost + size(contract.code) x G_codedeposit + wordsize(initcode) x G_InitCodeWord to gas
    • For CREATE2, add memoryGasCost + size(data) x G_sha3word + size(contract.code) x G_codedeposit + wordsize(initcode) x G_InitCodeWord to gas
    • For SSTORE,
      • [eip2929] If a slot(contractAddr, slot) is not in AccessList, add it to accessList and add G_coldSloadCost to gas
      • If it just reads the slot (no-op), add G_warmStorageReadCost to gas
      • If it creates a new slot, add G_sset to gas
      • If it deletes the slot, add G_sreset-G_coldSloadCost to gas and add R_sclear to refund
      • If it recreates the slot once exists before, add G_warmStorageReadCost to gas and subtract R_sclear from refund
      • If it deletes the slot once exists before, add R_sclear to refund
      • If it resets to the original inexistent slot, add G_warmStorageReadCost to gas and add G_sset - G_warmStorageReadCost to refund
      • IF it resets to the original existing slot, add G_warmStorageReadCost to gas and add G_sreset - G_coldSloadCost - G_warmStorageReadCost to refund
    • For SLOAD,
      • [eip2929] If a slot(contractAddr, slot) is not in AccessList, add it to accessList and add G_coldSloadCost to gas
      • [eip2929] If a slot(contractAddr, slot) is in AccessList, add G_warmStorageReadCost to gas
    • For CALL, CALLCODE, DELEGATECALL, STATICCALL,
      • [eip2929] If an address is not in AccessList, add it to accessList and add G_coldSloadCost to gas
      • if it is CALL and CALLCODE and if it transfers value, add G_callvalue to gas
      • if it is CALL and if it transfers value and if it is a new account, add G_newaccount to gas
      • if the callee contract is precompiled contracts, calculate precompiled contract gas cost and add it to gas
      • add memoryGasCost + availableGas - availableGas/64, where availableGas = contract.Gas - gas to gas
    • For SELFDESTRUCT,
      • [eip2929] If an address is not in AccessList, add it to accessList and add G_coldSloadCost to gas
      • if it transfers value and if is a new account, add G_newaccount to gas

Hardfork changes

HardforkNew ItemsChange
Cancun EVMBLOBBASEFEE (0x49) opcode
BLOBHASH (0x50) opcode
TSTORE (0x5C) opcode
TLOAD (0x5D) opcode
MCOPY(0x5E) opcode
kzg (0x0A) precompiled contract
accessList is fully supported, the storage
access which are added to accessList
put through tx args are became warm
Shanghai EVMPUSH0 (0x5F) opcodewarm coinbase so the gas cost accessing
coinbase is always warm

started to add 2 gas per word of the initcode
at Create, Create2 opcodes
Korereduction in refunds
- removes refund for SELFDESTRUCT (0xFF), SSTORE (0x55)
- capped the refund to gasUsed/5 (it was gasUsed/2)

increase gas cost for state access opcodes
- accessList is introduced here but it's not yet supported.
London EVMBASEFEE (0x48) opcodemodExp (0x05) precompiled contract
use new gas calculation logic.
Become more accurate.
Istanbul EVMCHAINID (0x46) opcode
SELFBALANCE (0x47) opcode
blake2f (0x09) precompiled contract
reduce the gas cost of BN256 precomiled contracts
- Bn256Add (0x06):500->150
- Bn256ScalarMul (0x07): 40,000->6,000
- BN256Pairing (0x08):
-- BaseGas: 100,000->45,000
-- PerPointGas: 80,000->34,000

new gas calculation logic of SSTORE (0x55).
- introduced cold storage.
- gas cost for the first access is increased.

increase the gas cost of heavy storage access
- SLOAD(0x54): 200->800
- BALANCE(0x31): 400->700
- EXTCODEHASH(0x3F): 400->700
Make this page better