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

27
GAS_JUMPDEST = Uint(1)

GAS_BASE

28
GAS_BASE = Uint(2)

GAS_VERY_LOW

29
GAS_VERY_LOW = Uint(3)

GAS_STORAGE_SET

30
GAS_STORAGE_SET = Uint(20000)

GAS_STORAGE_UPDATE

31
GAS_STORAGE_UPDATE = Uint(5000)

GAS_STORAGE_CLEAR_REFUND

32
GAS_STORAGE_CLEAR_REFUND = Uint(4800)

GAS_LOW

33
GAS_LOW = Uint(5)

GAS_MID

34
GAS_MID = Uint(8)

GAS_HIGH

35
GAS_HIGH = Uint(10)

GAS_EXPONENTIATION

36
GAS_EXPONENTIATION = Uint(10)

GAS_EXPONENTIATION_PER_BYTE

37
GAS_EXPONENTIATION_PER_BYTE = Uint(50)

GAS_MEMORY

38
GAS_MEMORY = Uint(3)

GAS_KECCAK256

39
GAS_KECCAK256 = Uint(30)

GAS_KECCAK256_WORD

40
GAS_KECCAK256_WORD = Uint(6)

GAS_COPY

41
GAS_COPY = Uint(3)

GAS_BLOCK_HASH

42
GAS_BLOCK_HASH = Uint(20)

GAS_LOG

43
GAS_LOG = Uint(375)

GAS_LOG_DATA

44
GAS_LOG_DATA = Uint(8)

GAS_LOG_TOPIC

45
GAS_LOG_TOPIC = Uint(375)

GAS_CREATE

46
GAS_CREATE = Uint(32000)

GAS_CODE_DEPOSIT

47
GAS_CODE_DEPOSIT = Uint(200)

GAS_ZERO

48
GAS_ZERO = Uint(0)

GAS_NEW_ACCOUNT

49
GAS_NEW_ACCOUNT = Uint(25000)

GAS_CALL_VALUE

50
GAS_CALL_VALUE = Uint(9000)

GAS_CALL_STIPEND

51
GAS_CALL_STIPEND = Uint(2300)

GAS_SELF_DESTRUCT

52
GAS_SELF_DESTRUCT = Uint(5000)

GAS_SELF_DESTRUCT_NEW_ACCOUNT

53
GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000)

GAS_ECRECOVER

54
GAS_ECRECOVER = Uint(3000)

GAS_P256VERIFY

55
GAS_P256VERIFY = Uint(6900)

GAS_SHA256

56
GAS_SHA256 = Uint(60)

GAS_SHA256_WORD

57
GAS_SHA256_WORD = Uint(12)

GAS_RIPEMD160

58
GAS_RIPEMD160 = Uint(600)

GAS_RIPEMD160_WORD

59
GAS_RIPEMD160_WORD = Uint(120)

GAS_IDENTITY

60
GAS_IDENTITY = Uint(15)

GAS_IDENTITY_WORD

61
GAS_IDENTITY_WORD = Uint(3)

GAS_RETURN_DATA_COPY

62
GAS_RETURN_DATA_COPY = Uint(3)

GAS_FAST_STEP

63
GAS_FAST_STEP = Uint(5)

GAS_BLAKE2_PER_ROUND

64
GAS_BLAKE2_PER_ROUND = Uint(1)

GAS_COLD_SLOAD

65
GAS_COLD_SLOAD = Uint(2100)

GAS_COLD_ACCOUNT_ACCESS

66
GAS_COLD_ACCOUNT_ACCESS = Uint(2600)

GAS_WARM_ACCESS

67
GAS_WARM_ACCESS = Uint(100)

GAS_INIT_CODE_WORD_COST

68
GAS_INIT_CODE_WORD_COST = Uint(2)

GAS_BLOBHASH_OPCODE

69
GAS_BLOBHASH_OPCODE = Uint(3)

GAS_POINT_EVALUATION

70
GAS_POINT_EVALUATION = Uint(50000)

GAS_PER_BLOB

72
GAS_PER_BLOB = U64(2**17)

BLOB_SCHEDULE_TARGET

73
BLOB_SCHEDULE_TARGET = U64(14)

TARGET_BLOB_GAS_PER_BLOCK

74
TARGET_BLOB_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET

BLOB_BASE_COST

75
BLOB_BASE_COST = Uint(2**13)

BLOB_SCHEDULE_MAX

76
BLOB_SCHEDULE_MAX = U64(21)

MIN_BLOB_GASPRICE

77
MIN_BLOB_GASPRICE = Uint(1)

BLOB_BASE_FEE_UPDATE_FRACTION

78
BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671)

GAS_BLS_G1_ADD

80
GAS_BLS_G1_ADD = Uint(375)

GAS_BLS_G1_MUL

81
GAS_BLS_G1_MUL = Uint(12000)

GAS_BLS_G1_MAP

82
GAS_BLS_G1_MAP = Uint(5500)

GAS_BLS_G2_ADD

83
GAS_BLS_G2_ADD = Uint(600)

GAS_BLS_G2_MUL

84
GAS_BLS_G2_MUL = Uint(22500)

GAS_BLS_G2_MAP

85
GAS_BLS_G2_MAP = Uint(23800)

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

88
@dataclass
class ExtendMemory:

cost

99
    cost: Uint

expand_by

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

103
@dataclass
class MessageCallGas:

cost

117
    cost: Uint

sub_call

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

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