Ethereum Virtual Machine (EVM) Gas

Introduction

EVM gas constants and calculators.

Module Contents

Classes

ExtendMemory

Define the parameters for memory extension in opcodes

MessageCallGas

Define the gas cost and stipend for executing the call opcodes.

Functions

charge_gas

Subtracts amount from evm.gas_left.

calculate_memory_gas_cost

Calculates the gas cost for allocating memory

calculate_gas_extend_memory

Calculates the gas amount to extend memory

calculate_message_call_gas

Calculates the MessageCallGas (cost and stipend) for

max_message_call_gas

Calculates the maximum gas that is allowed for making a message call

Attributes

GAS_JUMPDEST

GAS_BASE

GAS_VERY_LOW

GAS_SLOAD

GAS_STORAGE_SET

GAS_STORAGE_UPDATE

GAS_STORAGE_CLEAR_REFUND

GAS_LOW

GAS_MID

GAS_HIGH

GAS_EXPONENTIATION

GAS_EXPONENTIATION_PER_BYTE

GAS_MEMORY

GAS_KECCAK256

GAS_KECCAK256_WORD

GAS_COPY

GAS_BLOCK_HASH

GAS_EXTERNAL

GAS_BALANCE

GAS_LOG

GAS_LOG_DATA

GAS_LOG_TOPIC

GAS_CREATE

GAS_CODE_DEPOSIT

GAS_ZERO

GAS_CALL

GAS_NEW_ACCOUNT

GAS_CALL_VALUE

GAS_CALL_STIPEND

GAS_SELF_DESTRUCT

GAS_SELF_DESTRUCT_NEW_ACCOUNT

REFUND_SELF_DESTRUCT

GAS_ECRECOVER

GAS_SHA256

GAS_SHA256_WORD

GAS_RIPEMD160

GAS_RIPEMD160_WORD

GAS_IDENTITY

GAS_IDENTITY_WORD

GAS_RETURN_DATA_COPY

GAS_CODE_HASH

GAS_FAST_STEP

GAS_BLAKE2_PER_ROUND

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(800)

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(700)

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)

GAS_CODE_HASH

GAS_CODE_HASH
GAS_CODE_HASH = Uint(700)

GAS_FAST_STEP

GAS_FAST_STEP
GAS_FAST_STEP = Uint(5)

GAS_BLAKE2_PER_ROUND

GAS_BLAKE2_PER_ROUND
GAS_BLAKE2_PER_ROUND = Uint(1)

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

class ExtendMemory
cost :ethereum.base_types.Uint
expand_by :ethereum.base_types.Uint

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

class MessageCallGas
cost :ethereum.base_types.Uint
stipend :ethereum.base_types.Uint

charge_gas

charge_gas(evm: ethereum.istanbul.vm.Evm, amount: ethereum.base_types.Uint)None

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:
    if evm.gas_left < amount:
        raise OutOfGasError
    else:
        evm.gas_left -= U256(amount)

calculate_memory_gas_cost

calculate_memory_gas_cost(size_in_bytes: ethereum.base_types.Uint)ethereum.base_types.Uint

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: bytearray, extensions: List[Tuple[ethereum.base_types.U256, ethereum.base_types.U256]])ExtendMemory

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: ethereum.base_types.U256, gas: ethereum.base_types.Uint, gas_left: ethereum.base_types.Uint, memory_cost: ethereum.base_types.Uint, extra_gas: ethereum.base_types.Uint, call_stipend: ethereum.base_types.Uint = GAS_CALL_STIPEND)MessageCallGas

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: ethereum.base_types.Uint)ethereum.base_types.Uint

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)