ethereum.istanbul.vm.instructions.storageethereum.muir_glacier.vm.instructions.storage

Ethereum Virtual Machine (EVM) Storage Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. contents:: Table of Contents :backlinks: none :local:

Introduction

Implementations of the EVM storage related instructions.

sload

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:
32
    """
33
    Loads to the stack, the value corresponding to a certain key from the
34
    storage of the current account.
35
36
    Parameters
37
    ----------
38
    evm :
39
        The current EVM frame.
40
41
    """
42
    # STACK
43
    key = pop(evm.stack).to_be_bytes32()
44
45
    # GAS
46
    charge_gas(evm, GAS_SLOAD)
47
48
    # OPERATION
49
    value = get_storage(
50
        evm.message.block_env.state, evm.message.current_target, key
51
    )
52
53
    push(evm.stack, value)
54
55
    # PROGRAM COUNTER
56
    evm.pc += Uint(1)

sstore

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

Parameters

evm : The current EVM frame.

def sstore(evm: Evm) -> None:
60
    """
61
    Stores a value at a certain key in the current context's storage.
62
63
    Parameters
64
    ----------
65
    evm :
66
        The current EVM frame.
67
68
    """
69
    # STACK
70
    key = pop(evm.stack).to_be_bytes32()
71
    new_value = pop(evm.stack)
72
    if evm.gas_left <= GAS_CALL_STIPEND:
73
        raise OutOfGasError
74
75
    state = evm.message.block_env.state
76
    original_value = get_storage_original(
77
        state, evm.message.current_target, key
78
    )
79
    current_value = get_storage(state, evm.message.current_target, key)
80
81
    if original_value == current_value and current_value != new_value:
82
        if original_value == 0:
83
            gas_cost = GAS_STORAGE_SET
84
        else:
85
            gas_cost = GAS_STORAGE_UPDATE
86
    else:
87
        gas_cost = GAS_SLOAD
88
89
    # Refund Counter Calculation
90
    if current_value != new_value:
91
        if original_value != 0 and current_value != 0 and new_value == 0:
92
            # Storage is cleared for the first time in the transaction
93
            evm.refund_counter += int(GAS_STORAGE_CLEAR_REFUND)
94
95
        if original_value != 0 and current_value == 0:
96
            # Gas refund issued earlier to be reversed
97
            evm.refund_counter -= int(GAS_STORAGE_CLEAR_REFUND)
98
99
        if original_value == new_value:
100
            # Storage slot being restored to its original value
101
            if original_value == 0:
102
                # Slot was originally empty and was SET earlier
103
                evm.refund_counter += int(GAS_STORAGE_SET - GAS_SLOAD)
104
            else:
105
                # Slot was originally non-empty and was UPDATED earlier
106
                evm.refund_counter += int(GAS_STORAGE_UPDATE - GAS_SLOAD)
107
108
    charge_gas(evm, gas_cost)
109
    if evm.message.is_static:
110
        raise WriteInStaticContext
111
    set_storage(state, evm.message.current_target, key, new_value)
112
113
    # PROGRAM COUNTER
114
    evm.pc += Uint(1)