ethereum.forks.dao_fork.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)

SLOAD

42
    SLOAD = Uint(50)

STORAGE_SET

45
    STORAGE_SET = Uint(20000)

COLD_STORAGE_WRITE

46
    COLD_STORAGE_WRITE = Uint(5000)

CALL_VALUE

49
    CALL_VALUE = Uint(9000)

CALL_STIPEND

50
    CALL_STIPEND = Uint(2300)

NEW_ACCOUNT

51
    NEW_ACCOUNT = Uint(25000)

CODE_DEPOSIT_PER_BYTE

54
    CODE_DEPOSIT_PER_BYTE = Uint(200)

ZERO

57
    ZERO = Uint(0)

MEMORY_PER_WORD

58
    MEMORY_PER_WORD = Uint(3)

REFUND_STORAGE_CLEAR

61
    REFUND_STORAGE_CLEAR = 15000

REFUND_SELF_DESTRUCT

62
    REFUND_SELF_DESTRUCT = Uint(24000)

PRECOMPILE_ECRECOVER

65
    PRECOMPILE_ECRECOVER = Uint(3000)

PRECOMPILE_SHA256_BASE

66
    PRECOMPILE_SHA256_BASE = Uint(60)

PRECOMPILE_SHA256_PER_WORD

67
    PRECOMPILE_SHA256_PER_WORD = Uint(12)

PRECOMPILE_RIPEMD160_BASE

68
    PRECOMPILE_RIPEMD160_BASE = Uint(600)

PRECOMPILE_RIPEMD160_PER_WORD

69
    PRECOMPILE_RIPEMD160_PER_WORD = Uint(120)

PRECOMPILE_IDENTITY_BASE

70
    PRECOMPILE_IDENTITY_BASE = Uint(15)

PRECOMPILE_IDENTITY_PER_WORD

71
    PRECOMPILE_IDENTITY_PER_WORD = Uint(3)

TX_BASE

74
    TX_BASE = Uint(21000)

TX_CREATE

75
    TX_CREATE = Uint(32000)

TX_DATA_PER_ZERO

76
    TX_DATA_PER_ZERO = Uint(4)

TX_DATA_PER_NON_ZERO

77
    TX_DATA_PER_NON_ZERO = Uint(68)

LIMIT_ADJUSTMENT_FACTOR

80
    LIMIT_ADJUSTMENT_FACTOR = Uint(1024)

LIMIT_MINIMUM

81
    LIMIT_MINIMUM = Uint(5000)

OPCODE_ADD

84
    OPCODE_ADD = VERY_LOW

OPCODE_SUB

85
    OPCODE_SUB = VERY_LOW

OPCODE_MUL

86
    OPCODE_MUL = LOW

OPCODE_DIV

87
    OPCODE_DIV = LOW

OPCODE_SDIV

88
    OPCODE_SDIV = LOW

OPCODE_MOD

89
    OPCODE_MOD = LOW

OPCODE_SMOD

90
    OPCODE_SMOD = LOW

OPCODE_ADDMOD

91
    OPCODE_ADDMOD = MID

OPCODE_MULMOD

92
    OPCODE_MULMOD = MID

OPCODE_SIGNEXTEND

93
    OPCODE_SIGNEXTEND = LOW

OPCODE_LT

94
    OPCODE_LT = VERY_LOW

OPCODE_GT

95
    OPCODE_GT = VERY_LOW

OPCODE_SLT

96
    OPCODE_SLT = VERY_LOW

OPCODE_SGT

97
    OPCODE_SGT = VERY_LOW

OPCODE_EQ

98
    OPCODE_EQ = VERY_LOW

OPCODE_ISZERO

99
    OPCODE_ISZERO = VERY_LOW

OPCODE_AND

100
    OPCODE_AND = VERY_LOW

OPCODE_OR

101
    OPCODE_OR = VERY_LOW

OPCODE_XOR

102
    OPCODE_XOR = VERY_LOW

OPCODE_NOT

103
    OPCODE_NOT = VERY_LOW

OPCODE_BYTE

104
    OPCODE_BYTE = VERY_LOW

OPCODE_JUMP

105
    OPCODE_JUMP = MID

OPCODE_JUMPI

106
    OPCODE_JUMPI = HIGH

OPCODE_JUMPDEST

107
    OPCODE_JUMPDEST = Uint(1)

OPCODE_CALLDATALOAD

108
    OPCODE_CALLDATALOAD = VERY_LOW

OPCODE_BLOCKHASH

109
    OPCODE_BLOCKHASH = Uint(20)

OPCODE_COINBASE

110
    OPCODE_COINBASE = BASE

OPCODE_POP

111
    OPCODE_POP = BASE

OPCODE_MSIZE

112
    OPCODE_MSIZE = BASE

OPCODE_PC

113
    OPCODE_PC = BASE

OPCODE_GAS

114
    OPCODE_GAS = BASE

OPCODE_ADDRESS

115
    OPCODE_ADDRESS = BASE

OPCODE_ORIGIN

116
    OPCODE_ORIGIN = BASE

OPCODE_CALLER

117
    OPCODE_CALLER = BASE

OPCODE_CALLVALUE

118
    OPCODE_CALLVALUE = BASE

OPCODE_CALLDATASIZE

119
    OPCODE_CALLDATASIZE = BASE

OPCODE_CODESIZE

120
    OPCODE_CODESIZE = BASE

OPCODE_GASPRICE

121
    OPCODE_GASPRICE = BASE

OPCODE_TIMESTAMP

122
    OPCODE_TIMESTAMP = BASE

OPCODE_NUMBER

123
    OPCODE_NUMBER = BASE

OPCODE_GASLIMIT

124
    OPCODE_GASLIMIT = BASE

OPCODE_DIFFICULTY

125
    OPCODE_DIFFICULTY = BASE

OPCODE_PUSH

126
    OPCODE_PUSH = VERY_LOW

OPCODE_DUP

127
    OPCODE_DUP = VERY_LOW

OPCODE_SWAP

128
    OPCODE_SWAP = VERY_LOW

OPCODE_CALLDATACOPY_BASE

131
    OPCODE_CALLDATACOPY_BASE = VERY_LOW

OPCODE_CODECOPY_BASE

132
    OPCODE_CODECOPY_BASE = VERY_LOW

OPCODE_MLOAD_BASE

133
    OPCODE_MLOAD_BASE = VERY_LOW

OPCODE_MSTORE_BASE

134
    OPCODE_MSTORE_BASE = VERY_LOW

OPCODE_MSTORE8_BASE

135
    OPCODE_MSTORE8_BASE = VERY_LOW

OPCODE_COPY_PER_WORD

136
    OPCODE_COPY_PER_WORD = Uint(3)

OPCODE_CREATE_BASE

137
    OPCODE_CREATE_BASE = Uint(32000)

OPCODE_EXP_BASE

138
    OPCODE_EXP_BASE = Uint(10)

OPCODE_EXP_PER_BYTE

139
    OPCODE_EXP_PER_BYTE = Uint(10)

OPCODE_KECCAK256_BASE

140
    OPCODE_KECCAK256_BASE = Uint(30)

OPCODE_KECCACK256_PER_WORD

141
    OPCODE_KECCACK256_PER_WORD = Uint(6)

OPCODE_LOG_BASE

142
    OPCODE_LOG_BASE = Uint(375)

OPCODE_LOG_DATA_PER_BYTE

143
    OPCODE_LOG_DATA_PER_BYTE = Uint(8)

OPCODE_LOG_TOPIC

144
    OPCODE_LOG_TOPIC = Uint(375)

OPCODE_EXTERNAL_BASE

145
    OPCODE_EXTERNAL_BASE = Uint(20)

OPCODE_BALANCE

146
    OPCODE_BALANCE = Uint(20)

OPCODE_CALL_BASE

147
    OPCODE_CALL_BASE = Uint(40)

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

150
@dataclass
class ExtendMemory:

cost

161
    cost: Uint

expand_by

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

165
@dataclass
class MessageCallGas:

cost

179
    cost: Uint

sub_call

180
    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:
184
    """
185
    Subtracts `amount` from `evm.gas_left`.
186
187
    Parameters
188
    ----------
189
    evm :
190
        The current EVM.
191
    amount :
192
        The amount of gas the current operation requires.
193
194
    """
195
    evm_trace(evm, GasAndRefund(int(amount)))
196
197
    if evm.gas_left < amount:
198
        raise OutOfGasError
199
    else:
200
        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:
204
    """
205
    Calculates the gas cost for allocating memory
206
    to the smallest multiple of 32 bytes,
207
    such that the allocated size is at least as big as the given size.
208
209
    Parameters
210
    ----------
211
    size_in_bytes :
212
        The size of the data in bytes.
213
214
    Returns
215
    -------
216
    total_gas_cost : `ethereum.base_types.Uint`
217
        The gas cost for storing data in memory.
218
219
    """
220
    size_in_words = ceil32(size_in_bytes) // Uint(32)
221
    linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD
222
    quadratic_cost = size_in_words ** Uint(2) // Uint(512)
223
    total_gas_cost = linear_cost + quadratic_cost
224
    try:
225
        return total_gas_cost
226
    except ValueError as e:
227
        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:
233
    """
234
    Calculates the gas amount to extend memory.
235
236
    Parameters
237
    ----------
238
    memory :
239
        Memory contents of the EVM.
240
    extensions:
241
        List of extensions to be made to the memory.
242
        Consists of a tuple of start position and size.
243
244
    Returns
245
    -------
246
    extend_memory: `ExtendMemory`
247
248
    """
249
    size_to_extend = Uint(0)
250
    to_be_paid = Uint(0)
251
    current_size = ulen(memory)
252
    for start_position, size in extensions:
253
        if size == 0:
254
            continue
255
        before_size = ceil32(current_size)
256
        after_size = ceil32(Uint(start_position) + Uint(size))
257
        if after_size <= before_size:
258
            continue
259
260
        size_to_extend += after_size - before_size
261
        already_paid = calculate_memory_gas_cost(before_size)
262
        total_cost = calculate_memory_gas_cost(after_size)
263
        to_be_paid += total_cost - already_paid
264
265
        current_size = after_size
266
267
    return ExtendMemory(to_be_paid, size_to_extend)

calculate_message_call_gas

Calculates the gas amount for executing Opcodes CALL and CALLCODE.

Parameters

state : The current state. gas : The amount of gas provided to the message-call. to: The address of the recipient account. value: The amount of ETH that needs to be transferred.

Returns

message_call_gas: MessageCallGas

def calculate_message_call_gas(state: State, ​​gas: Uint, ​​to: Address, ​​value: U256) -> MessageCallGas:
273
    """
274
    Calculates the gas amount for executing Opcodes `CALL` and `CALLCODE`.
275
276
    Parameters
277
    ----------
278
    state :
279
        The current state.
280
    gas :
281
        The amount of gas provided to the message-call.
282
    to:
283
        The address of the recipient account.
284
    value:
285
        The amount of `ETH` that needs to be transferred.
286
287
    Returns
288
    -------
289
    message_call_gas: `MessageCallGas`
290
291
    """
292
    create_gas_cost = (
293
        Uint(0) if account_exists(state, to) else GasCosts.NEW_ACCOUNT
294
    )
295
    transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE
296
    cost = (
297
        GasCosts.OPCODE_CALL_BASE + gas + create_gas_cost + transfer_gas_cost
298
    )
299
    stipend = gas if value == 0 else GasCosts.CALL_STIPEND + gas
300
    return MessageCallGas(cost, stipend)