ethereum.forks.cancun.vm.gas

Ethereum Virtual Machine (EVM) Gas.

.. contents:: Table of Contents :backlinks: none :local:

Introduction

EVM gas constants and calculators.

GasCosts

Constant gas values for the EVM.

class GasCosts:

BASE

35
    BASE = Uint(2)

VERY_LOW

36
    VERY_LOW = Uint(3)

LOW

37
    LOW = Uint(5)

MID

38
    MID = Uint(8)

HIGH

39
    HIGH = Uint(10)

WARM_ACCESS

42
    WARM_ACCESS = Uint(100)

COLD_ACCOUNT_ACCESS

43
    COLD_ACCOUNT_ACCESS = Uint(2600)

COLD_STORAGE_ACCESS

44
    COLD_STORAGE_ACCESS = Uint(2100)

STORAGE_SET

47
    STORAGE_SET = Uint(20000)

COLD_STORAGE_WRITE

48
    COLD_STORAGE_WRITE = Uint(5000)

CALL_VALUE

51
    CALL_VALUE = Uint(9000)

CALL_STIPEND

52
    CALL_STIPEND = Uint(2300)

NEW_ACCOUNT

53
    NEW_ACCOUNT = Uint(25000)

CODE_DEPOSIT_PER_BYTE

56
    CODE_DEPOSIT_PER_BYTE = Uint(200)

CODE_INIT_PER_WORD

57
    CODE_INIT_PER_WORD = Uint(2)

ZERO

60
    ZERO = Uint(0)

MEMORY_PER_WORD

61
    MEMORY_PER_WORD = Uint(3)

FAST_STEP

62
    FAST_STEP = Uint(5)

REFUND_STORAGE_CLEAR

65
    REFUND_STORAGE_CLEAR = 4800

PRECOMPILE_ECRECOVER

68
    PRECOMPILE_ECRECOVER = Uint(3000)

PRECOMPILE_SHA256_BASE

69
    PRECOMPILE_SHA256_BASE = Uint(60)

PRECOMPILE_SHA256_PER_WORD

70
    PRECOMPILE_SHA256_PER_WORD = Uint(12)

PRECOMPILE_RIPEMD160_BASE

71
    PRECOMPILE_RIPEMD160_BASE = Uint(600)

PRECOMPILE_RIPEMD160_PER_WORD

72
    PRECOMPILE_RIPEMD160_PER_WORD = Uint(120)

PRECOMPILE_IDENTITY_BASE

73
    PRECOMPILE_IDENTITY_BASE = Uint(15)

PRECOMPILE_IDENTITY_PER_WORD

74
    PRECOMPILE_IDENTITY_PER_WORD = Uint(3)

PRECOMPILE_BLAKE2F_PER_ROUND

75
    PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1)

PRECOMPILE_POINT_EVALUATION

76
    PRECOMPILE_POINT_EVALUATION = Uint(50000)

PRECOMPILE_ECADD

77
    PRECOMPILE_ECADD = Uint(150)

PRECOMPILE_ECMUL

78
    PRECOMPILE_ECMUL = Uint(6000)

PRECOMPILE_ECPAIRING_BASE

79
    PRECOMPILE_ECPAIRING_BASE = Uint(45000)

PRECOMPILE_ECPAIRING_PER_POINT

80
    PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000)

PER_BLOB

83
    PER_BLOB = U64(2**17)

BLOB_TARGET_GAS_PER_BLOCK

84
    BLOB_TARGET_GAS_PER_BLOCK = U64(393216)

BLOB_MIN_GASPRICE

85
    BLOB_MIN_GASPRICE = Uint(1)

BLOB_BASE_FEE_UPDATE_FRACTION

86
    BLOB_BASE_FEE_UPDATE_FRACTION = Uint(3338477)

TX_BASE

89
    TX_BASE = Uint(21000)

TX_CREATE

90
    TX_CREATE = Uint(32000)

TX_DATA_PER_ZERO

91
    TX_DATA_PER_ZERO = Uint(4)

TX_DATA_PER_NON_ZERO

92
    TX_DATA_PER_NON_ZERO = Uint(16)

TX_ACCESS_LIST_ADDRESS

93
    TX_ACCESS_LIST_ADDRESS = Uint(2400)

TX_ACCESS_LIST_STORAGE_KEY

94
    TX_ACCESS_LIST_STORAGE_KEY = Uint(1900)

LIMIT_ADJUSTMENT_FACTOR

97
    LIMIT_ADJUSTMENT_FACTOR = Uint(1024)

LIMIT_MINIMUM

98
    LIMIT_MINIMUM = Uint(5000)

OPCODE_ADD

101
    OPCODE_ADD = VERY_LOW

OPCODE_SUB

102
    OPCODE_SUB = VERY_LOW

OPCODE_MUL

103
    OPCODE_MUL = LOW

OPCODE_DIV

104
    OPCODE_DIV = LOW

OPCODE_SDIV

105
    OPCODE_SDIV = LOW

OPCODE_MOD

106
    OPCODE_MOD = LOW

OPCODE_SMOD

107
    OPCODE_SMOD = LOW

OPCODE_ADDMOD

108
    OPCODE_ADDMOD = MID

OPCODE_MULMOD

109
    OPCODE_MULMOD = MID

OPCODE_SIGNEXTEND

110
    OPCODE_SIGNEXTEND = LOW

OPCODE_LT

111
    OPCODE_LT = VERY_LOW

OPCODE_GT

112
    OPCODE_GT = VERY_LOW

OPCODE_SLT

113
    OPCODE_SLT = VERY_LOW

OPCODE_SGT

114
    OPCODE_SGT = VERY_LOW

OPCODE_EQ

115
    OPCODE_EQ = VERY_LOW

OPCODE_ISZERO

116
    OPCODE_ISZERO = VERY_LOW

OPCODE_AND

117
    OPCODE_AND = VERY_LOW

OPCODE_OR

118
    OPCODE_OR = VERY_LOW

OPCODE_XOR

119
    OPCODE_XOR = VERY_LOW

OPCODE_NOT

120
    OPCODE_NOT = VERY_LOW

OPCODE_BYTE

121
    OPCODE_BYTE = VERY_LOW

OPCODE_SHL

122
    OPCODE_SHL = VERY_LOW

OPCODE_SHR

123
    OPCODE_SHR = VERY_LOW

OPCODE_SAR

124
    OPCODE_SAR = VERY_LOW

OPCODE_JUMP

125
    OPCODE_JUMP = MID

OPCODE_JUMPI

126
    OPCODE_JUMPI = HIGH

OPCODE_JUMPDEST

127
    OPCODE_JUMPDEST = Uint(1)

OPCODE_CALLDATALOAD

128
    OPCODE_CALLDATALOAD = VERY_LOW

OPCODE_BLOCKHASH

129
    OPCODE_BLOCKHASH = Uint(20)

OPCODE_COINBASE

130
    OPCODE_COINBASE = BASE

OPCODE_POP

131
    OPCODE_POP = BASE

OPCODE_MSIZE

132
    OPCODE_MSIZE = BASE

OPCODE_PC

133
    OPCODE_PC = BASE

OPCODE_GAS

134
    OPCODE_GAS = BASE

OPCODE_ADDRESS

135
    OPCODE_ADDRESS = BASE

OPCODE_ORIGIN

136
    OPCODE_ORIGIN = BASE

OPCODE_CALLER

137
    OPCODE_CALLER = BASE

OPCODE_CALLVALUE

138
    OPCODE_CALLVALUE = BASE

OPCODE_CALLDATASIZE

139
    OPCODE_CALLDATASIZE = BASE

OPCODE_CODESIZE

140
    OPCODE_CODESIZE = BASE

OPCODE_GASPRICE

141
    OPCODE_GASPRICE = BASE

OPCODE_TIMESTAMP

142
    OPCODE_TIMESTAMP = BASE

OPCODE_NUMBER

143
    OPCODE_NUMBER = BASE

OPCODE_GASLIMIT

144
    OPCODE_GASLIMIT = BASE

OPCODE_PREVRANDAO

145
    OPCODE_PREVRANDAO = BASE

OPCODE_RETURNDATASIZE

146
    OPCODE_RETURNDATASIZE = BASE

OPCODE_CHAINID

147
    OPCODE_CHAINID = BASE

OPCODE_BASEFEE

148
    OPCODE_BASEFEE = BASE

OPCODE_BLOBBASEFEE

149
    OPCODE_BLOBBASEFEE = BASE

OPCODE_BLOBHASH

150
    OPCODE_BLOBHASH = Uint(3)

OPCODE_PUSH

151
    OPCODE_PUSH = VERY_LOW

OPCODE_PUSH0

152
    OPCODE_PUSH0 = BASE

OPCODE_DUP

153
    OPCODE_DUP = VERY_LOW

OPCODE_SWAP

154
    OPCODE_SWAP = VERY_LOW

OPCODE_RETURNDATACOPY_BASE

157
    OPCODE_RETURNDATACOPY_BASE = VERY_LOW

OPCODE_RETURNDATACOPY_PER_WORD

158
    OPCODE_RETURNDATACOPY_PER_WORD = Uint(3)

OPCODE_CALLDATACOPY_BASE

159
    OPCODE_CALLDATACOPY_BASE = VERY_LOW

OPCODE_CODECOPY_BASE

160
    OPCODE_CODECOPY_BASE = VERY_LOW

OPCODE_MCOPY_BASE

161
    OPCODE_MCOPY_BASE = VERY_LOW

OPCODE_MLOAD_BASE

162
    OPCODE_MLOAD_BASE = VERY_LOW

OPCODE_MSTORE_BASE

163
    OPCODE_MSTORE_BASE = VERY_LOW

OPCODE_MSTORE8_BASE

164
    OPCODE_MSTORE8_BASE = VERY_LOW

OPCODE_COPY_PER_WORD

165
    OPCODE_COPY_PER_WORD = Uint(3)

OPCODE_CREATE_BASE

166
    OPCODE_CREATE_BASE = Uint(32000)

OPCODE_EXP_BASE

167
    OPCODE_EXP_BASE = Uint(10)

OPCODE_EXP_PER_BYTE

168
    OPCODE_EXP_PER_BYTE = Uint(50)

OPCODE_KECCAK256_BASE

169
    OPCODE_KECCAK256_BASE = Uint(30)

OPCODE_KECCACK256_PER_WORD

170
    OPCODE_KECCACK256_PER_WORD = Uint(6)

OPCODE_LOG_BASE

171
    OPCODE_LOG_BASE = Uint(375)

OPCODE_LOG_DATA_PER_BYTE

172
    OPCODE_LOG_DATA_PER_BYTE = Uint(8)

OPCODE_LOG_TOPIC

173
    OPCODE_LOG_TOPIC = Uint(375)

OPCODE_SELFDESTRUCT_BASE

174
    OPCODE_SELFDESTRUCT_BASE = Uint(5000)

OPCODE_SELFDESTRUCT_NEW_ACCOUNT

175
    OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000)

ExtendMemory

Define the parameters for memory extension in opcodes.

cost: ethereum.base_types.Uint The gas required to perform the extension expand_by: ethereum.base_types.Uint The size by which the memory will be extended

178
@dataclass
class ExtendMemory:

cost

189
    cost: Uint

expand_by

190
    expand_by: Uint

MessageCallGas

Define the gas cost and gas given to the sub-call for executing the call opcodes.

cost: ethereum.base_types.Uint The gas required to execute the call opcode, excludes memory expansion costs. sub_call: ethereum.base_types.Uint The portion of gas available to sub-calls that is refundable if not consumed.

193
@dataclass
class MessageCallGas:

cost

207
    cost: Uint

sub_call

208
    sub_call: Uint

charge_gas

Subtracts amount from evm.gas_left.

Parameters

evm : The current EVM. amount : The amount of gas the current operation requires.

def charge_gas(evm: Evm, ​​amount: Uint) -> None:
212
    """
213
    Subtracts `amount` from `evm.gas_left`.
214
215
    Parameters
216
    ----------
217
    evm :
218
        The current EVM.
219
    amount :
220
        The amount of gas the current operation requires.
221
222
    """
223
    evm_trace(evm, GasAndRefund(int(amount)))
224
225
    if evm.gas_left < amount:
226
        raise OutOfGasError
227
    else:
228
        evm.gas_left -= amount

calculate_memory_gas_cost

Calculates the gas cost for allocating memory to the smallest multiple of 32 bytes, such that the allocated size is at least as big as the given size.

Parameters

size_in_bytes : The size of the data in bytes.

Returns

total_gas_cost : ethereum.base_types.Uint The gas cost for storing data in memory.

def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint:
232
    """
233
    Calculates the gas cost for allocating memory
234
    to the smallest multiple of 32 bytes,
235
    such that the allocated size is at least as big as the given size.
236
237
    Parameters
238
    ----------
239
    size_in_bytes :
240
        The size of the data in bytes.
241
242
    Returns
243
    -------
244
    total_gas_cost : `ethereum.base_types.Uint`
245
        The gas cost for storing data in memory.
246
247
    """
248
    size_in_words = ceil32(size_in_bytes) // Uint(32)
249
    linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD
250
    quadratic_cost = size_in_words ** Uint(2) // Uint(512)
251
    total_gas_cost = linear_cost + quadratic_cost
252
    try:
253
        return total_gas_cost
254
    except ValueError as e:
255
        raise OutOfGasError from e

calculate_gas_extend_memory

Calculates the gas amount to extend memory.

Parameters

memory : Memory contents of the EVM. extensions: List of extensions to be made to the memory. Consists of a tuple of start position and size.

Returns

extend_memory: ExtendMemory

def calculate_gas_extend_memory(memory: bytearray, ​​extensions: List[Tuple[U256, U256]]) -> ExtendMemory:
261
    """
262
    Calculates the gas amount to extend memory.
263
264
    Parameters
265
    ----------
266
    memory :
267
        Memory contents of the EVM.
268
    extensions:
269
        List of extensions to be made to the memory.
270
        Consists of a tuple of start position and size.
271
272
    Returns
273
    -------
274
    extend_memory: `ExtendMemory`
275
276
    """
277
    size_to_extend = Uint(0)
278
    to_be_paid = Uint(0)
279
    current_size = ulen(memory)
280
    for start_position, size in extensions:
281
        if size == 0:
282
            continue
283
        before_size = ceil32(current_size)
284
        after_size = ceil32(Uint(start_position) + Uint(size))
285
        if after_size <= before_size:
286
            continue
287
288
        size_to_extend += after_size - before_size
289
        already_paid = calculate_memory_gas_cost(before_size)
290
        total_cost = calculate_memory_gas_cost(after_size)
291
        to_be_paid += total_cost - already_paid
292
293
        current_size = after_size
294
295
    return ExtendMemory(to_be_paid, size_to_extend)

calculate_message_call_gas

Calculates the MessageCallGas (cost and gas made available to the sub-call) for executing call Opcodes.

Parameters

value: The amount of ETH that needs to be transferred. gas : The amount of gas provided to the message-call. gas_left : The amount of gas left in the current frame. memory_cost : The amount needed to extend the memory in the current frame. extra_gas : The amount of gas needed for transferring value + creating a new account inside a message call. call_stipend : The amount of stipend provided to a message call to execute code while transferring value (ETH).

Returns

message_call_gas: MessageCallGas

def calculate_message_call_gas(value: U256, ​​gas: Uint, ​​gas_left: Uint, ​​memory_cost: Uint, ​​extra_gas: Uint, ​​call_stipend: Uint) -> MessageCallGas:
306
    """
307
    Calculates the MessageCallGas (cost and gas made available to the sub-call)
308
    for executing call Opcodes.
309
310
    Parameters
311
    ----------
312
    value:
313
        The amount of `ETH` that needs to be transferred.
314
    gas :
315
        The amount of gas provided to the message-call.
316
    gas_left :
317
        The amount of gas left in the current frame.
318
    memory_cost :
319
        The amount needed to extend the memory in the current frame.
320
    extra_gas :
321
        The amount of gas needed for transferring value + creating a new
322
        account inside a message call.
323
    call_stipend :
324
        The amount of stipend provided to a message call to execute code while
325
        transferring value (ETH).
326
327
    Returns
328
    -------
329
    message_call_gas: `MessageCallGas`
330
331
    """
332
    call_stipend = Uint(0) if value == 0 else call_stipend
333
    if gas_left < extra_gas + memory_cost:
334
        return MessageCallGas(gas + extra_gas, gas + call_stipend)
335
336
    gas = min(gas, max_message_call_gas(gas_left - memory_cost - extra_gas))
337
338
    return MessageCallGas(gas + extra_gas, gas + call_stipend)

max_message_call_gas

Calculates the maximum gas that is allowed for making a message call.

Parameters

gas : The amount of gas provided to the message-call.

Returns

max_allowed_message_call_gas: ethereum.base_types.Uint The maximum gas allowed for making the message-call.

def max_message_call_gas(gas: Uint) -> Uint:
342
    """
343
    Calculates the maximum gas that is allowed for making a message call.
344
345
    Parameters
346
    ----------
347
    gas :
348
        The amount of gas provided to the message-call.
349
350
    Returns
351
    -------
352
    max_allowed_message_call_gas: `ethereum.base_types.Uint`
353
        The maximum gas allowed for making the message-call.
354
355
    """
356
    return gas - (gas // Uint(64))

init_code_cost

Calculates the gas to be charged for the init code in CREATE* opcodes as well as create transactions.

Parameters

init_code_length : The length of the init code provided to the opcode or a create transaction

Returns

init_code_gas: ethereum.base_types.Uint The gas to be charged for the init code.

def init_code_cost(init_code_length: Uint) -> Uint:
360
    """
361
    Calculates the gas to be charged for the init code in CREATE*
362
    opcodes as well as create transactions.
363
364
    Parameters
365
    ----------
366
    init_code_length :
367
        The length of the init code provided to the opcode
368
        or a create transaction
369
370
    Returns
371
    -------
372
    init_code_gas: `ethereum.base_types.Uint`
373
        The gas to be charged for the init code.
374
375
    """
376
    return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32)

calculate_excess_blob_gas

Calculates the excess blob gas for the current block based on the gas used in the parent block.

Parameters

parent_header : The parent block of the current block.

Returns

excess_blob_gas: ethereum.base_types.U64 The excess blob gas for the current block.

def calculate_excess_blob_gas(parent_header: Header) -> U64:
380
    """
381
    Calculates the excess blob gas for the current block based
382
    on the gas used in the parent block.
383
384
    Parameters
385
    ----------
386
    parent_header :
387
        The parent block of the current block.
388
389
    Returns
390
    -------
391
    excess_blob_gas: `ethereum.base_types.U64`
392
        The excess blob gas for the current block.
393
394
    """
395
    # At the fork block, these are defined as zero.
396
    excess_blob_gas = U64(0)
397
    blob_gas_used = U64(0)
398
399
    if isinstance(parent_header, Header):
400
        # After the fork block, read them from the parent header.
401
        excess_blob_gas = parent_header.excess_blob_gas
402
        blob_gas_used = parent_header.blob_gas_used
403
404
    parent_blob_gas = excess_blob_gas + blob_gas_used
405
    if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK:
406
        return U64(0)
407
408
    return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK

calculate_total_blob_gas

Calculate the total blob gas for a transaction.

Parameters

tx : The transaction for which the blob gas is to be calculated.

Returns

total_blob_gas: ethereum.base_types.Uint The total blob gas for the transaction.

def calculate_total_blob_gas(tx: Transaction) -> U64:
412
    """
413
    Calculate the total blob gas for a transaction.
414
415
    Parameters
416
    ----------
417
    tx :
418
        The transaction for which the blob gas is to be calculated.
419
420
    Returns
421
    -------
422
    total_blob_gas: `ethereum.base_types.Uint`
423
        The total blob gas for the transaction.
424
425
    """
426
    if isinstance(tx, BlobTransaction):
427
        return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes))
428
    else:
429
        return U64(0)

calculate_blob_gas_price

Calculate the blob gasprice for a block.

Parameters

excess_blob_gas : The excess blob gas for the block.

Returns

blob_gasprice: Uint The blob gasprice.

def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint:
433
    """
434
    Calculate the blob gasprice for a block.
435
436
    Parameters
437
    ----------
438
    excess_blob_gas :
439
        The excess blob gas for the block.
440
441
    Returns
442
    -------
443
    blob_gasprice: `Uint`
444
        The blob gasprice.
445
446
    """
447
    return taylor_exponential(
448
        GasCosts.BLOB_MIN_GASPRICE,
449
        Uint(excess_blob_gas),
450
        GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION,
451
    )

calculate_data_fee

Calculate the blob data fee for a transaction.

Parameters

excess_blob_gas : The excess_blob_gas for the execution. tx : The transaction for which the blob data fee is to be calculated.

Returns

data_fee: Uint The blob data fee.

def calculate_data_fee(excess_blob_gas: U64, ​​tx: Transaction) -> Uint:
455
    """
456
    Calculate the blob data fee for a transaction.
457
458
    Parameters
459
    ----------
460
    excess_blob_gas :
461
        The excess_blob_gas for the execution.
462
    tx :
463
        The transaction for which the blob data fee is to be calculated.
464
465
    Returns
466
    -------
467
    data_fee: `Uint`
468
        The blob data fee.
469
470
    """
471
    return Uint(calculate_total_blob_gas(tx)) * calculate_blob_gas_price(
472
        excess_blob_gas
473
    )