Ethereum Virtual Machine (EVM) Storage Instructions

Introduction

Implementations of the EVM storage related instructions.

Module Contents

Functions

sload

Loads to the stack, the value corresponding to a certain key from the

sstore

Stores a value at a certain key in the current context’s storage.

Module Details

sload

sload(evm)

Loads to the stack, the value corresponding to a certain key from the storage of the current account.

Parameters

evm – The current EVM frame.

def sload(evm: Evm) -> None:
    # STACK
    key = pop(evm.stack).to_be_bytes32()

    # GAS
    charge_gas(evm, GAS_SLOAD)

    # OPERATION
    value = get_storage(evm.env.state, evm.message.current_target, key)

    push(evm.stack, value)

    # PROGRAM COUNTER
    evm.pc += 1

sstore

sstore(evm)

Stores a value at a certain key in the current context’s storage.

Parameters

evm – The current EVM frame.

def sstore(evm: Evm) -> None:
    # STACK
    key = pop(evm.stack).to_be_bytes32()
    new_value = pop(evm.stack)

    # GAS
    ensure(evm.gas_left > GAS_CALL_STIPEND, OutOfGasError)

    original_value = get_storage_original(
        evm.env.state, evm.message.current_target, key
    )
    current_value = get_storage(evm.env.state, evm.message.current_target, key)
    if original_value == current_value and current_value != new_value:
        if original_value == 0:
            gas_cost = GAS_STORAGE_SET
        else:
            gas_cost = GAS_STORAGE_UPDATE
    else:
        gas_cost = GAS_SLOAD

    # Refund Counter Calculation
    if current_value != new_value:
        if original_value != 0 and current_value != 0 and new_value == 0:
            # Storage is cleared for the first time in the transaction
            evm.refund_counter += int(GAS_STORAGE_CLEAR_REFUND)

        if original_value != 0 and current_value == 0:
        gas_cost = GAS_STORAGE_SET# Gas refund issued earlier to be reversed
            evm.refund_counter -= int(GAS_STORAGE_CLEAR_REFUND)

        if original_value == new_value:
            # Storage slot being restored to its original value
            if original_value == 0:
                # Slot was originally empty and was SET earlier
                evm.refund_counter += int(GAS_STORAGE_SET - GAS_SLOAD)
    else:
        gas_cost = GAS_STORAGE_UPDATE

    if new_value == 0# Slot was originally non-empty and current_value != 0:was UPDATED earlier
        evm.refund_counter += GAS_STORAGE_CLEAR_REFUNDint(GAS_STORAGE_UPDATE - GAS_SLOAD)

    charge_gas(evm, gas_cost)

    # OPERATION
    ensure(not evm.message.is_static, WriteInStaticContext)
    set_storage(evm.env.state, evm.message.current_target, key, new_value)

    # PROGRAM COUNTER
    evm.pc += 1