ethereum.forks.bpo5.vm.gasethereum.forks.amsterdam.vm.gas

Ethereum Virtual Machine (EVM) Gas.

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

Introduction

EVM gas constants and calculators.

GAS_JUMPDEST

28
GAS_JUMPDEST = Uint(1)

GAS_BASE

29
GAS_BASE = Uint(2)

GAS_VERY_LOW

30
GAS_VERY_LOW = Uint(3)

GAS_STORAGE_SET

31
GAS_STORAGE_SET = Uint(20000)

GAS_STORAGE_UPDATE

32
GAS_STORAGE_UPDATE = Uint(5000)

REFUND_STORAGE_CLEAR

33
REFUND_STORAGE_CLEAR = 4800

GAS_LOW

34
GAS_LOW = Uint(5)

GAS_MID

35
GAS_MID = Uint(8)

GAS_HIGH

36
GAS_HIGH = Uint(10)

GAS_EXPONENTIATION

37
GAS_EXPONENTIATION = Uint(10)

GAS_EXPONENTIATION_PER_BYTE

38
GAS_EXPONENTIATION_PER_BYTE = Uint(50)

GAS_MEMORY

39
GAS_MEMORY = Uint(3)

GAS_KECCAK256

40
GAS_KECCAK256 = Uint(30)

GAS_KECCAK256_PER_WORD

41
GAS_KECCAK256_PER_WORD = Uint(6)

GAS_COPY

42
GAS_COPY = Uint(3)

GAS_BLOCK_HASH

43
GAS_BLOCK_HASH = Uint(20)

GAS_LOG

44
GAS_LOG = Uint(375)

GAS_LOG_DATA_PER_BYTE

45
GAS_LOG_DATA_PER_BYTE = Uint(8)

GAS_LOG_TOPIC

46
GAS_LOG_TOPIC = Uint(375)

GAS_CREATE

47
GAS_CREATE = Uint(32000)

GAS_CODE_DEPOSIT_PER_BYTE

48
GAS_CODE_DEPOSIT_PER_BYTE = Uint(200)

GAS_ZERO

49
GAS_ZERO = Uint(0)

GAS_NEW_ACCOUNT

50
GAS_NEW_ACCOUNT = Uint(25000)

GAS_CALL_VALUE

51
GAS_CALL_VALUE = Uint(9000)

GAS_CALL_STIPEND

52
GAS_CALL_STIPEND = Uint(2300)

GAS_SELF_DESTRUCT

53
GAS_SELF_DESTRUCT = Uint(5000)

GAS_SELF_DESTRUCT_NEW_ACCOUNT

54
GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000)

GAS_ECRECOVER

55
GAS_ECRECOVER = Uint(3000)

GAS_P256VERIFY

56
GAS_P256VERIFY = Uint(6900)

GAS_SHA256

57
GAS_SHA256 = Uint(60)

GAS_SHA256_WORD

58
GAS_SHA256_WORD = Uint(12)

GAS_RIPEMD160

59
GAS_RIPEMD160 = Uint(600)

GAS_RIPEMD160_WORD

60
GAS_RIPEMD160_WORD = Uint(120)

GAS_IDENTITY

61
GAS_IDENTITY = Uint(15)

GAS_IDENTITY_WORD

62
GAS_IDENTITY_WORD = Uint(3)

GAS_RETURN_DATA_COPY

63
GAS_RETURN_DATA_COPY = Uint(3)

GAS_FAST_STEP

64
GAS_FAST_STEP = Uint(5)

GAS_BLAKE2_PER_ROUND

65
GAS_BLAKE2_PER_ROUND = Uint(1)

GAS_COLD_SLOAD

66
GAS_COLD_SLOAD = Uint(2100)

GAS_COLD_ACCOUNT_ACCESS

67
GAS_COLD_ACCOUNT_ACCESS = Uint(2600)

GAS_WARM_ACCESS

68
GAS_WARM_ACCESS = Uint(100)

GAS_CODE_INIT_PER_WORD

69
GAS_CODE_INIT_PER_WORD = Uint(2)

GAS_BLOBHASH_OPCODE

70
GAS_BLOBHASH_OPCODE = Uint(3)

GAS_POINT_EVALUATION

71
GAS_POINT_EVALUATION = Uint(50000)

GAS_PER_BLOB

73
GAS_PER_BLOB = U64(2**17)

BLOB_SCHEDULE_TARGET

74
BLOB_SCHEDULE_TARGET = U64(14)

BLOB_TARGET_GAS_PER_BLOCK

75
BLOB_TARGET_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET

BLOB_BASE_COST

76
BLOB_BASE_COST = Uint(2**13)

BLOB_SCHEDULE_MAX

77
BLOB_SCHEDULE_MAX = U64(21)

BLOB_MIN_GASPRICE

78
BLOB_MIN_GASPRICE = Uint(1)

BLOB_BASE_FEE_UPDATE_FRACTION

79
BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671)

GAS_BLS_G1_ADD

81
GAS_BLS_G1_ADD = Uint(375)

GAS_BLS_G1_MUL

82
GAS_BLS_G1_MUL = Uint(12000)

GAS_BLS_G1_MAP

83
GAS_BLS_G1_MAP = Uint(5500)

GAS_BLS_G2_ADD

84
GAS_BLS_G2_ADD = Uint(600)

GAS_BLS_G2_MUL

85
GAS_BLS_G2_MUL = Uint(22500)

GAS_BLS_G2_MAP

86
GAS_BLS_G2_MAP = Uint(23800)

GAS_BLOCK_ACCESS_LIST_ITEM

88
GAS_BLOCK_ACCESS_LIST_ITEM = Uint(2000)

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

91
@dataclass
class ExtendMemory:

cost

102
    cost: Uint

expand_by

103
    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.

106
@dataclass
class MessageCallGas:

cost

120
    cost: Uint

sub_call

121
    sub_call: Uint

check_gas

Checks if amount gas is available without charging it. Raises OutOfGasError if insufficient gas.

Parameters

evm : The current EVM. amount : The amount of gas to check.

def check_gas(evm: Evm, ​​amount: Uint) -> None:
125
    """
126
    Checks if `amount` gas is available without charging it.
127
    Raises OutOfGasError if insufficient gas.
128
129
    Parameters
130
    ----------
131
    evm :
132
        The current EVM.
133
    amount :
134
        The amount of gas to check.
135
136
    """
137
    if evm.gas_left < amount:
138
        raise OutOfGasError

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:
142
    """
143
    Subtracts `amount` from `evm.gas_left`.
144
145
    Parameters
146
    ----------
147
    evm :
148
        The current EVM.
149
    amount :
150
        The amount of gas the current operation requires.
151
152
    """
153
    evm_trace(evm, GasAndRefund(int(amount)))
154
155
    if evm.gas_left < amount:
156
        raise OutOfGasError
157
    else:
158
        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:
162
    """
163
    Calculates the gas cost for allocating memory
164
    to the smallest multiple of 32 bytes,
165
    such that the allocated size is at least as big as the given size.
166
167
    Parameters
168
    ----------
169
    size_in_bytes :
170
        The size of the data in bytes.
171
172
    Returns
173
    -------
174
    total_gas_cost : `ethereum.base_types.Uint`
175
        The gas cost for storing data in memory.
176
177
    """
178
    size_in_words = ceil32(size_in_bytes) // Uint(32)
179
    linear_cost = size_in_words * GAS_MEMORY
180
    quadratic_cost = size_in_words ** Uint(2) // Uint(512)
181
    total_gas_cost = linear_cost + quadratic_cost
182
    try:
183
        return total_gas_cost
184
    except ValueError as e:
185
        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:
191
    """
192
    Calculates the gas amount to extend memory.
193
194
    Parameters
195
    ----------
196
    memory :
197
        Memory contents of the EVM.
198
    extensions:
199
        List of extensions to be made to the memory.
200
        Consists of a tuple of start position and size.
201
202
    Returns
203
    -------
204
    extend_memory: `ExtendMemory`
205
206
    """
207
    size_to_extend = Uint(0)
208
    to_be_paid = Uint(0)
209
    current_size = Uint(len(memory))
210
    for start_position, size in extensions:
211
        if size == 0:
212
            continue
213
        before_size = ceil32(current_size)
214
        after_size = ceil32(Uint(start_position) + Uint(size))
215
        if after_size <= before_size:
216
            continue
217
218
        size_to_extend += after_size - before_size
219
        already_paid = calculate_memory_gas_cost(before_size)
220
        total_cost = calculate_memory_gas_cost(after_size)
221
        to_be_paid += total_cost - already_paid
222
223
        current_size = after_size
224
225
    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:
236
    """
237
    Calculates the MessageCallGas (cost and gas made available to the sub-call)
238
    for executing call Opcodes.
239
240
    Parameters
241
    ----------
242
    value:
243
        The amount of `ETH` that needs to be transferred.
244
    gas :
245
        The amount of gas provided to the message-call.
246
    gas_left :
247
        The amount of gas left in the current frame.
248
    memory_cost :
249
        The amount needed to extend the memory in the current frame.
250
    extra_gas :
251
        The amount of gas needed for transferring value + creating a new
252
        account inside a message call.
253
    call_stipend :
254
        The amount of stipend provided to a message call to execute code while
255
        transferring value (ETH).
256
257
    Returns
258
    -------
259
    message_call_gas: `MessageCallGas`
260
261
    """
262
    call_stipend = Uint(0) if value == 0 else call_stipend
263
    if gas_left < extra_gas + memory_cost:
264
        return MessageCallGas(gas + extra_gas, gas + call_stipend)
265
266
    gas = min(gas, max_message_call_gas(gas_left - memory_cost - extra_gas))
267
268
    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:
272
    """
273
    Calculates the maximum gas that is allowed for making a message call.
274
275
    Parameters
276
    ----------
277
    gas :
278
        The amount of gas provided to the message-call.
279
280
    Returns
281
    -------
282
    max_allowed_message_call_gas: `ethereum.base_types.Uint`
283
        The maximum gas allowed for making the message-call.
284
285
    """
286
    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:
290
    """
291
    Calculates the gas to be charged for the init code in CREATE*
292
    opcodes as well as create transactions.
293
294
    Parameters
295
    ----------
296
    init_code_length :
297
        The length of the init code provided to the opcode
298
        or a create transaction
299
300
    Returns
301
    -------
302
    init_code_gas: `ethereum.base_types.Uint`
303
        The gas to be charged for the init code.
304
305
    """
306
    return GAS_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: HeaderHeader | PreviousHeader) -> U64:
312
    """
313
    Calculates the excess blob gas for the current block based
314
    on the gas used in the parent block.
315
316
    Parameters
317
    ----------
318
    parent_header :
319
        The parent block of the current block.
320
321
    Returns
322
    -------
323
    excess_blob_gas: `ethereum.base_types.U64`
324
        The excess blob gas for the current block.
325
326
    """
327
    # At the fork block, these are defined as zero.
328
    excess_blob_gas = U64(0)
329
    blob_gas_used = U64(0)
330
    base_fee_per_gas = Uint(0)
331
332
    if isinstance(parent_header, Header):
333
        # After the fork block, read them from the parent header.
334
        excess_blob_gas = parent_header.excess_blob_gas
335
        blob_gas_used = parent_header.blob_gas_used
336
        base_fee_per_gas = parent_header.base_fee_per_gas
337
338
    parent_blob_gas = excess_blob_gas + blob_gas_used
339
    if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK:
340
        return U64(0)
341
342
    target_blob_gas_price = Uint(GAS_PER_BLOB)
343
    target_blob_gas_price *= calculate_blob_gas_price(excess_blob_gas)
344
345
    base_blob_tx_price = BLOB_BASE_COST * base_fee_per_gas
346
    if base_blob_tx_price > target_blob_gas_price:
347
        blob_schedule_delta = BLOB_SCHEDULE_MAX - BLOB_SCHEDULE_TARGET
348
        return (
349
            excess_blob_gas
350
            + blob_gas_used * blob_schedule_delta // BLOB_SCHEDULE_MAX
351
        )
352
353
    return parent_blob_gas - 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:
357
    """
358
    Calculate the total blob gas for a transaction.
359
360
    Parameters
361
    ----------
362
    tx :
363
        The transaction for which the blob gas is to be calculated.
364
365
    Returns
366
    -------
367
    total_blob_gas: `ethereum.base_types.Uint`
368
        The total blob gas for the transaction.
369
370
    """
371
    if isinstance(tx, BlobTransaction):
372
        return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes))
373
    else:
374
        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:
378
    """
379
    Calculate the blob gasprice for a block.
380
381
    Parameters
382
    ----------
383
    excess_blob_gas :
384
        The excess blob gas for the block.
385
386
    Returns
387
    -------
388
    blob_gasprice: `Uint`
389
        The blob gasprice.
390
391
    """
392
    return taylor_exponential(
393
        BLOB_MIN_GASPRICE,
394
        Uint(excess_blob_gas),
395
        BLOB_BASE_FEE_UPDATE_FRACTION,
396
    )

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:
400
    """
401
    Calculate the blob data fee for a transaction.
402
403
    Parameters
404
    ----------
405
    excess_blob_gas :
406
        The excess_blob_gas for the execution.
407
    tx :
408
        The transaction for which the blob data fee is to be calculated.
409
410
    Returns
411
    -------
412
    data_fee: `Uint`
413
        The blob data fee.
414
415
    """
416
    return Uint(calculate_total_blob_gas(tx)) * calculate_blob_gas_price(
417
        excess_blob_gas
418
    )