Ethereum Virtual Machine (EVM) Gas
Table of Contents
Introduction
EVM gas constants and calculators.
Module Contents
Classes
Define the parameters for memory extension in opcodes |
|
Define the gas cost and stipend for executing the call opcodes. |
Functions
Subtracts amount from evm.gas_left. |
|
Calculates the gas cost for allocating memory |
|
Calculates the gas amount to extend memory |
|
Calculates the MessageCallGas (cost and stipend) for |
|
Calculates the maximum gas that is allowed for making a message call |
Attributes
Module Details
GAS_JUMPDEST
- GAS_JUMPDEST
GAS_JUMPDEST = Uint(1)
GAS_BASE
- GAS_BASE
GAS_BASE = Uint(2)
GAS_VERY_LOW
- GAS_VERY_LOW
GAS_VERY_LOW = Uint(3)
GAS_SLOAD
- GAS_SLOAD
GAS_SLOAD = Uint(200)
GAS_STORAGE_SET
- GAS_STORAGE_SET
GAS_STORAGE_SET = Uint(20000)
GAS_STORAGE_UPDATE
- GAS_STORAGE_UPDATE
GAS_STORAGE_UPDATE = Uint(5000)
GAS_STORAGE_CLEAR_REFUND
- GAS_STORAGE_CLEAR_REFUND
GAS_STORAGE_CLEAR_REFUND = Uint(15000)
GAS_LOW
- GAS_LOW
GAS_LOW = Uint(5)
GAS_MID
- GAS_MID
GAS_MID = Uint(8)
GAS_HIGH
- GAS_HIGH
GAS_HIGH = Uint(10)
GAS_EXPONENTIATION
- GAS_EXPONENTIATION
GAS_EXPONENTIATION = Uint(10)
GAS_EXPONENTIATION_PER_BYTE
- GAS_EXPONENTIATION_PER_BYTE
GAS_EXPONENTIATION_PER_BYTE = Uint(50)
GAS_MEMORY
- GAS_MEMORY
GAS_MEMORY = Uint(3)
GAS_KECCAK256
- GAS_KECCAK256
GAS_KECCAK256 = Uint(30)
GAS_KECCAK256_WORD
- GAS_KECCAK256_WORD
GAS_KECCAK256_WORD = Uint(6)
GAS_COPY
- GAS_COPY
GAS_COPY = Uint(3)
GAS_BLOCK_HASH
- GAS_BLOCK_HASH
GAS_BLOCK_HASH = Uint(20)
GAS_EXTERNAL
- GAS_EXTERNAL
GAS_EXTERNAL = Uint(700)
GAS_BALANCE
- GAS_BALANCE
GAS_BALANCE = Uint(400)
GAS_LOG
- GAS_LOG
GAS_LOG = Uint(375)
GAS_LOG_DATA
- GAS_LOG_DATA
GAS_LOG_DATA = Uint(8)
GAS_LOG_TOPIC
- GAS_LOG_TOPIC
GAS_LOG_TOPIC = Uint(375)
GAS_CREATE
- GAS_CREATE
GAS_CREATE = Uint(32000)
GAS_CODE_DEPOSIT
- GAS_CODE_DEPOSIT
GAS_CODE_DEPOSIT = Uint(200)
GAS_ZERO
- GAS_ZERO
GAS_ZERO = Uint(0)
GAS_CALL
- GAS_CALL
GAS_CALL = Uint(700)
GAS_NEW_ACCOUNT
- GAS_NEW_ACCOUNT
GAS_NEW_ACCOUNT = Uint(25000)
GAS_CALL_VALUE
- GAS_CALL_VALUE
GAS_CALL_VALUE = Uint(9000)
GAS_CALL_STIPEND
- GAS_CALL_STIPEND
GAS_CALL_STIPEND = Uint(2300)
GAS_SELF_DESTRUCT
- GAS_SELF_DESTRUCT
GAS_SELF_DESTRUCT = Uint(5000)
GAS_SELF_DESTRUCT_NEW_ACCOUNT
- GAS_SELF_DESTRUCT_NEW_ACCOUNT
GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000)
REFUND_SELF_DESTRUCT
- REFUND_SELF_DESTRUCT
REFUND_SELF_DESTRUCT = Uint(24000)
GAS_ECRECOVER
- GAS_ECRECOVER
GAS_ECRECOVER = Uint(3000)
GAS_SHA256
- GAS_SHA256
GAS_SHA256 = Uint(60)
GAS_SHA256_WORD
- GAS_SHA256_WORD
GAS_SHA256_WORD = Uint(12)
GAS_RIPEMD160
- GAS_RIPEMD160
GAS_RIPEMD160 = Uint(600)
GAS_RIPEMD160_WORD
- GAS_RIPEMD160_WORD
GAS_RIPEMD160_WORD = Uint(120)
GAS_IDENTITY
- GAS_IDENTITY
GAS_IDENTITY = Uint(15)
GAS_IDENTITY_WORD
- GAS_IDENTITY_WORD
GAS_IDENTITY_WORD = Uint(3)
GAS_RETURN_DATA_COPY
- GAS_RETURN_DATA_COPY
GAS_RETURN_DATA_COPY = 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
MessageCallGas
Define the gas cost and stipend for executing the call opcodes.
- cost: ethereum.base_types.Uint
The non-refundable portion of gas reserved for executing the call opcode.
- stipend: ethereum.base_types.Uint
The portion of gas available to sub-calls that is refundable if not consumed
charge_gas
- charge_gas(evm, amount)
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:
evm_trace(evm, GasAndRefund(amount))
if evm.gas_left < amount:
raise OutOfGasError
else:
evm.gas_left -= U256(amount)
calculate_memory_gas_cost
- calculate_memory_gas_cost(size_in_bytes)
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 – The gas cost for storing data in memory.
- Return type
ethereum.base_types.Uint
def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint:
size_in_words = ceil32(size_in_bytes) // 32
linear_cost = size_in_words * GAS_MEMORY
quadratic_cost = size_in_words**2 // 512
total_gas_cost = linear_cost + quadratic_cost
try:
return total_gas_cost
except ValueError:
raise OutOfGasError
calculate_gas_extend_memory
- calculate_gas_extend_memory(memory, extensions)
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
- Return type
ExtendMemory
def calculate_gas_extend_memory(
memory: bytearray, extensions: List[Tuple[U256, U256]]
) -> ExtendMemory:
size_to_extend = Uint(0)
to_be_paid = Uint(0)
current_size = Uint(len(memory))
for start_position, size in extensions:
if size == 0:
continue
before_size = ceil32(current_size)
after_size = ceil32(Uint(start_position) + Uint(size))
if after_size <= before_size:
continue
size_to_extend += after_size - before_size
already_paid = calculate_memory_gas_cost(before_size)
total_cost = calculate_memory_gas_cost(after_size)
to_be_paid += total_cost - already_paid
current_size = after_size
return ExtendMemory(to_be_paid, size_to_extend)
calculate_message_call_gas
- calculate_message_call_gas(value, gas, gas_left, memory_cost, extra_gas, call_stipend=GAS_CALL_STIPEND)
Calculates the MessageCallGas (cost and stipend) 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
- Return type
MessageCallGas
def calculate_message_call_gas(
value: U256,
gas: Uint,
gas_left: Uint,
memory_cost: Uint,
extra_gas: Uint,
call_stipend: Uint = GAS_CALL_STIPEND,
) -> MessageCallGas:
call_stipend = Uint(0) if value == 0 else call_stipend
if gas_left < extra_gas + memory_cost:
return MessageCallGas(gas + extra_gas, gas + call_stipend)
gas = min(gas, max_message_call_gas(gas_left - memory_cost - extra_gas))
return MessageCallGas(gas + extra_gas, gas + call_stipend)
max_message_call_gas
- max_message_call_gas(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 – The maximum gas allowed for making the message-call.
- Return type
ethereum.base_types.Uint
def max_message_call_gas(gas: Uint) -> Uint:
return gas - (gas // 64)