ethereum.forks.frontier.vm.gasethereum.forks.homestead.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_SLOAD
| 30 | GAS_SLOAD = Uint(50) |
|---|
GAS_STORAGE_SET
| 31 | GAS_STORAGE_SET = Uint(20000) |
|---|
GAS_STORAGE_UPDATE
| 32 | GAS_STORAGE_UPDATE = Uint(5000) |
|---|
GAS_STORAGE_CLEAR_REFUND
| 33 | GAS_STORAGE_CLEAR_REFUND = Uint(15000) |
|---|
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(10) |
|---|
GAS_MEMORY
| 39 | GAS_MEMORY = Uint(3) |
|---|
GAS_KECCAK256
| 40 | GAS_KECCAK256 = Uint(30) |
|---|
GAS_KECCAK256_WORD
| 41 | GAS_KECCAK256_WORD = Uint(6) |
|---|
GAS_COPY
| 42 | GAS_COPY = Uint(3) |
|---|
GAS_BLOCK_HASH
| 43 | GAS_BLOCK_HASH = Uint(20) |
|---|
GAS_EXTERNAL
| 44 | GAS_EXTERNAL = Uint(20) |
|---|
GAS_BALANCE
| 45 | GAS_BALANCE = Uint(20) |
|---|
GAS_LOG
| 46 | GAS_LOG = Uint(375) |
|---|
GAS_LOG_DATA
| 47 | GAS_LOG_DATA = Uint(8) |
|---|
GAS_LOG_TOPIC
| 48 | GAS_LOG_TOPIC = Uint(375) |
|---|
GAS_CREATE
| 49 | GAS_CREATE = Uint(32000) |
|---|
GAS_CODE_DEPOSIT
| 50 | GAS_CODE_DEPOSIT = Uint(200) |
|---|
GAS_ZERO
| 51 | GAS_ZERO = Uint(0) |
|---|
GAS_CALL
| 52 | GAS_CALL = Uint(40) |
|---|
GAS_NEW_ACCOUNT
| 53 | GAS_NEW_ACCOUNT = Uint(25000) |
|---|
GAS_CALL_VALUE
| 54 | GAS_CALL_VALUE = Uint(9000) |
|---|
GAS_CALL_STIPEND
| 55 | GAS_CALL_STIPEND = Uint(2300) |
|---|
REFUND_SELF_DESTRUCT
| 56 | REFUND_SELF_DESTRUCT = Uint(24000) |
|---|
GAS_ECRECOVER
| 57 | GAS_ECRECOVER = Uint(3000) |
|---|
GAS_SHA256
| 58 | GAS_SHA256 = Uint(60) |
|---|
GAS_SHA256_WORD
| 59 | GAS_SHA256_WORD = Uint(12) |
|---|
GAS_RIPEMD160
| 60 | GAS_RIPEMD160 = Uint(600) |
|---|
GAS_RIPEMD160_WORD
| 61 | GAS_RIPEMD160_WORD = Uint(120) |
|---|
GAS_IDENTITY
| 62 | GAS_IDENTITY = Uint(15) |
|---|
GAS_IDENTITY_WORD
| 63 | GAS_IDENTITY_WORD = Uint(3) |
|---|
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
| 66 | @dataclass |
|---|
class ExtendMemory:
cost
| 77 | cost: Uint |
|---|
expand_by
| 78 | 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.
| 81 | @dataclass |
|---|
class MessageCallGas:
cost
| 95 | cost: Uint |
|---|
sub_call
| 96 | 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:
| 100 | """ |
|---|---|
| 101 | Subtracts `amount` from `evm.gas_left`. |
| 102 | |
| 103 | Parameters |
| 104 | ---------- |
| 105 | evm : |
| 106 | The current EVM. |
| 107 | amount : |
| 108 | The amount of gas the current operation requires. |
| 109 | |
| 110 | """ |
| 111 | evm_trace(evm, GasAndRefund(int(amount))) |
| 112 | |
| 113 | if evm.gas_left < amount: |
| 114 | raise OutOfGasError |
| 115 | else: |
| 116 | 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:
| 120 | """ |
|---|---|
| 121 | Calculates the gas cost for allocating memory |
| 122 | to the smallest multiple of 32 bytes, |
| 123 | such that the allocated size is at least as big as the given size. |
| 124 | |
| 125 | Parameters |
| 126 | ---------- |
| 127 | size_in_bytes : |
| 128 | The size of the data in bytes. |
| 129 | |
| 130 | Returns |
| 131 | ------- |
| 132 | total_gas_cost : `ethereum.base_types.Uint` |
| 133 | The gas cost for storing data in memory. |
| 134 | |
| 135 | """ |
| 136 | size_in_words = ceil32(size_in_bytes) // Uint(32) |
| 137 | linear_cost = size_in_words * GAS_MEMORY |
| 138 | quadratic_cost = size_in_words ** Uint(2) // Uint(512) |
| 139 | total_gas_cost = linear_cost + quadratic_cost |
| 140 | try: |
| 141 | return total_gas_cost |
| 142 | except ValueError as e: |
| 143 | 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:
| 149 | """ |
|---|---|
| 150 | Calculates the gas amount to extend memory. |
| 151 | |
| 152 | Parameters |
| 153 | ---------- |
| 154 | memory : |
| 155 | Memory contents of the EVM. |
| 156 | extensions: |
| 157 | List of extensions to be made to the memory. |
| 158 | Consists of a tuple of start position and size. |
| 159 | |
| 160 | Returns |
| 161 | ------- |
| 162 | extend_memory: `ExtendMemory` |
| 163 | |
| 164 | """ |
| 165 | size_to_extend = Uint(0) |
| 166 | to_be_paid = Uint(0) |
| 167 | current_size = Uint(len(memory)) |
| 168 | for start_position, size in extensions: |
| 169 | if size == 0: |
| 170 | continue |
| 171 | before_size = ceil32(current_size) |
| 172 | after_size = ceil32(Uint(start_position) + Uint(size)) |
| 173 | if after_size <= before_size: |
| 174 | continue |
| 175 | |
| 176 | size_to_extend += after_size - before_size |
| 177 | already_paid = calculate_memory_gas_cost(before_size) |
| 178 | total_cost = calculate_memory_gas_cost(after_size) |
| 179 | to_be_paid += total_cost - already_paid |
| 180 | |
| 181 | current_size = after_size |
| 182 | |
| 183 | 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:
| 189 | """ |
|---|---|
| 190 | Calculates the gas amount for executing Opcodes `CALL` and `CALLCODE`. |
| 191 | |
| 192 | Parameters |
| 193 | ---------- |
| 194 | state : |
| 195 | The current state. |
| 196 | gas : |
| 197 | The amount of gas provided to the message-call. |
| 198 | to: |
| 199 | The address of the recipient account. |
| 200 | value: |
| 201 | The amount of `ETH` that needs to be transferred. |
| 202 | |
| 203 | Returns |
| 204 | ------- |
| 205 | message_call_gas: `MessageCallGas` |
| 206 | |
| 207 | """ |
| 208 | create_gas_cost = Uint(0) if account_exists(state, to) else GAS_NEW_ACCOUNT |
| 209 | transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE |
| 210 | cost = GAS_CALL + gas + create_gas_cost + transfer_gas_cost |
| 211 | stipend = gas if value == 0 else GAS_CALL_STIPEND + gas |
| 212 | return MessageCallGas(cost, stipend) |