ethereum.forks.prague.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_SHA256

55
GAS_SHA256 = Uint(60)

GAS_SHA256_WORD

56
GAS_SHA256_WORD = Uint(12)

GAS_RIPEMD160

57
GAS_RIPEMD160 = Uint(600)

GAS_RIPEMD160_WORD

58
GAS_RIPEMD160_WORD = Uint(120)

GAS_IDENTITY

59
GAS_IDENTITY = Uint(15)

GAS_IDENTITY_WORD

60
GAS_IDENTITY_WORD = Uint(3)

GAS_RETURN_DATA_COPY

61
GAS_RETURN_DATA_COPY = Uint(3)

GAS_FAST_STEP

62
GAS_FAST_STEP = Uint(5)

GAS_BLAKE2_PER_ROUND

63
GAS_BLAKE2_PER_ROUND = Uint(1)

GAS_COLD_SLOAD

64
GAS_COLD_SLOAD = Uint(2100)

GAS_COLD_ACCOUNT_ACCESS

65
GAS_COLD_ACCOUNT_ACCESS = Uint(2600)

GAS_WARM_ACCESS

66
GAS_WARM_ACCESS = Uint(100)

GAS_INIT_CODE_WORD_COST

67
GAS_INIT_CODE_WORD_COST = Uint(2)

GAS_BLOBHASH_OPCODE

68
GAS_BLOBHASH_OPCODE = Uint(3)

GAS_POINT_EVALUATION

69
GAS_POINT_EVALUATION = Uint(50000)

GAS_PER_BLOB

71
GAS_PER_BLOB = U64(2**17)

TARGET_BLOB_GAS_PER_BLOCK

72
TARGET_BLOB_GAS_PER_BLOCK = U64(786432)

MIN_BLOB_GASPRICE

73
MIN_BLOB_GASPRICE = Uint(1)

BLOB_BASE_FEE_UPDATE_FRACTION

74
BLOB_BASE_FEE_UPDATE_FRACTION = Uint(5007716)

GAS_BLS_G1_ADD

76
GAS_BLS_G1_ADD = Uint(375)

GAS_BLS_G1_MUL

77
GAS_BLS_G1_MUL = Uint(12000)

GAS_BLS_G1_MAP

78
GAS_BLS_G1_MAP = Uint(5500)

GAS_BLS_G2_ADD

79
GAS_BLS_G2_ADD = Uint(600)

GAS_BLS_G2_MUL

80
GAS_BLS_G2_MUL = Uint(22500)

GAS_BLS_G2_MAP

81
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

84
@dataclass
class ExtendMemory:

cost

95
    cost: Uint

expand_by

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

99
@dataclass
class MessageCallGas:

cost

113
    cost: Uint

sub_call

114
    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:
118
    """
119
    Subtracts `amount` from `evm.gas_left`.
120
121
    Parameters
122
    ----------
123
    evm :
124
        The current EVM.
125
    amount :
126
        The amount of gas the current operation requires.
127
128
    """
129
    evm_trace(evm, GasAndRefund(int(amount)))
130
131
    if evm.gas_left < amount:
132
        raise OutOfGasError
133
    else:
134
        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:
138
    """
139
    Calculates the gas cost for allocating memory
140
    to the smallest multiple of 32 bytes,
141
    such that the allocated size is at least as big as the given size.
142
143
    Parameters
144
    ----------
145
    size_in_bytes :
146
        The size of the data in bytes.
147
148
    Returns
149
    -------
150
    total_gas_cost : `ethereum.base_types.Uint`
151
        The gas cost for storing data in memory.
152
153
    """
154
    size_in_words = ceil32(size_in_bytes) // Uint(32)
155
    linear_cost = size_in_words * GAS_MEMORY
156
    quadratic_cost = size_in_words ** Uint(2) // Uint(512)
157
    total_gas_cost = linear_cost + quadratic_cost
158
    try:
159
        return total_gas_cost
160
    except ValueError as e:
161
        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:
167
    """
168
    Calculates the gas amount to extend memory.
169
170
    Parameters
171
    ----------
172
    memory :
173
        Memory contents of the EVM.
174
    extensions:
175
        List of extensions to be made to the memory.
176
        Consists of a tuple of start position and size.
177
178
    Returns
179
    -------
180
    extend_memory: `ExtendMemory`
181
182
    """
183
    size_to_extend = Uint(0)
184
    to_be_paid = Uint(0)
185
    current_size = Uint(len(memory))
186
    for start_position, size in extensions:
187
        if size == 0:
188
            continue
189
        before_size = ceil32(current_size)
190
        after_size = ceil32(Uint(start_position) + Uint(size))
191
        if after_size <= before_size:
192
            continue
193
194
        size_to_extend += after_size - before_size
195
        already_paid = calculate_memory_gas_cost(before_size)
196
        total_cost = calculate_memory_gas_cost(after_size)
197
        to_be_paid += total_cost - already_paid
198
199
        current_size = after_size
200
201
    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:
212
    """
213
    Calculates the MessageCallGas (cost and gas made available to the sub-call)
214
    for executing call Opcodes.
215
216
    Parameters
217
    ----------
218
    value:
219
        The amount of `ETH` that needs to be transferred.
220
    gas :
221
        The amount of gas provided to the message-call.
222
    gas_left :
223
        The amount of gas left in the current frame.
224
    memory_cost :
225
        The amount needed to extend the memory in the current frame.
226
    extra_gas :
227
        The amount of gas needed for transferring value + creating a new
228
        account inside a message call.
229
    call_stipend :
230
        The amount of stipend provided to a message call to execute code while
231
        transferring value(ETH).
232
233
    Returns
234
    -------
235
    message_call_gas: `MessageCallGas`
236
237
    """
238
    call_stipend = Uint(0) if value == 0 else call_stipend
239
    if gas_left < extra_gas + memory_cost:
240
        return MessageCallGas(gas + extra_gas, gas + call_stipend)
241
242
    gas = min(gas, max_message_call_gas(gas_left - memory_cost - extra_gas))
243
244
    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:
248
    """
249
    Calculates the maximum gas that is allowed for making a message call.
250
251
    Parameters
252
    ----------
253
    gas :
254
        The amount of gas provided to the message-call.
255
256
    Returns
257
    -------
258
    max_allowed_message_call_gas: `ethereum.base_types.Uint`
259
        The maximum gas allowed for making the message-call.
260
261
    """
262
    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:
266
    """
267
    Calculates the gas to be charged for the init code in CREATE*
268
    opcodes as well as create transactions.
269
270
    Parameters
271
    ----------
272
    init_code_length :
273
        The length of the init code provided to the opcode
274
        or a create transaction
275
276
    Returns
277
    -------
278
    init_code_gas: `ethereum.base_types.Uint`
279
        The gas to be charged for the init code.
280
281
    """
282
    return GAS_INIT_CODE_WORD_COST * ceil32(init_code_length) // Uint(32)

calculate_excess_blob_gas

Calculated 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:
286
    """
287
    Calculated the excess blob gas for the current block based
288
    on the gas used in the parent block.
289
290
    Parameters
291
    ----------
292
    parent_header :
293
        The parent block of the current block.
294
295
    Returns
296
    -------
297
    excess_blob_gas: `ethereum.base_types.U64`
298
        The excess blob gas for the current block.
299
300
    """
301
    # At the fork block, these are defined as zero.
302
    excess_blob_gas = U64(0)
303
    blob_gas_used = U64(0)
304
305
    if isinstance(parent_header, Header):
306
        # After the fork block, read them from the parent header.
307
        excess_blob_gas = parent_header.excess_blob_gas
308
        blob_gas_used = parent_header.blob_gas_used
309
310
    parent_blob_gas = excess_blob_gas + blob_gas_used
311
    if parent_blob_gas < TARGET_BLOB_GAS_PER_BLOCK:
312
        return U64(0)
313
314
    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:
318
    """
319
    Calculate the total blob gas for a transaction.
320
321
    Parameters
322
    ----------
323
    tx :
324
        The transaction for which the blob gas is to be calculated.
325
326
    Returns
327
    -------
328
    total_blob_gas: `ethereum.base_types.Uint`
329
        The total blob gas for the transaction.
330
331
    """
332
    if isinstance(tx, BlobTransaction):
333
        return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes))
334
    else:
335
        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:
339
    """
340
    Calculate the blob gasprice for a block.
341
342
    Parameters
343
    ----------
344
    excess_blob_gas :
345
        The excess blob gas for the block.
346
347
    Returns
348
    -------
349
    blob_gasprice: `Uint`
350
        The blob gasprice.
351
352
    """
353
    return taylor_exponential(
354
        MIN_BLOB_GASPRICE,
355
        Uint(excess_blob_gas),
356
        BLOB_BASE_FEE_UPDATE_FRACTION,
357
    )

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:
361
    """
362
    Calculate the blob data fee for a transaction.
363
364
    Parameters
365
    ----------
366
    excess_blob_gas :
367
        The excess_blob_gas for the execution.
368
    tx :
369
        The transaction for which the blob data fee is to be calculated.
370
371
    Returns
372
    -------
373
    data_fee: `Uint`
374
        The blob data fee.
375
376
    """
377
    return Uint(calculate_total_blob_gas(tx)) * calculate_blob_gas_price(
378
        excess_blob_gas
379
    )