ethereum.forks.osaka.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:
33
    """
34
    Loads to the stack, the value corresponding to a certain key from the
35
    storage of the current account.
36
37
    Parameters
38
    ----------
39
    evm :
40
        The current EVM frame.
41
42
    """
43
    # STACK
44
    key = pop(evm.stack).to_be_bytes32()
45
46
    # GAS
47
    if (evm.message.current_target, key) in evm.accessed_storage_keys:
48
        charge_gas(evm, GasCosts.WARM_ACCESS)
49
    else:
50
        evm.accessed_storage_keys.add((evm.message.current_target, key))
51
        charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS)
52
53
    # OPERATION
54
    tx_state = evm.message.tx_env.state
55
    value = get_storage(tx_state, evm.message.current_target, key)
56
57
    push(evm.stack, value)
58
59
    # PROGRAM COUNTER
60
    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:
64
    """
65
    Stores a value at a certain key in the current context's storage.
66
67
    Parameters
68
    ----------
69
    evm :
70
        The current EVM frame.
71
72
    """
73
    # STACK
74
    key = pop(evm.stack).to_be_bytes32()
75
    new_value = pop(evm.stack)
76
    if evm.gas_left <= GasCosts.CALL_STIPEND:
77
        raise OutOfGasError
78
79
    tx_state = evm.message.tx_env.state
80
    original_value = get_storage_original(
81
        tx_state, evm.message.current_target, key
82
    )
83
    current_value = get_storage(tx_state, evm.message.current_target, key)
84
85
    gas_cost = Uint(0)
86
87
    if (evm.message.current_target, key) not in evm.accessed_storage_keys:
88
        evm.accessed_storage_keys.add((evm.message.current_target, key))
89
        gas_cost += GasCosts.COLD_STORAGE_ACCESS
90
91
    if original_value == current_value and current_value != new_value:
92
        if original_value == 0:
93
            gas_cost += GasCosts.STORAGE_SET
94
        else:
95
            gas_cost += (
96
                GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS
97
            )
98
    else:
99
        gas_cost += GasCosts.WARM_ACCESS
100
101
    # Refund Counter Calculation
102
    if current_value != new_value:
103
        if original_value != 0 and current_value != 0 and new_value == 0:
104
            evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR
105
106
        if original_value != 0 and current_value == 0:
107
            evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR
108
109
        if original_value == new_value:
110
            if original_value == 0:
111
                evm.refund_counter += int(
112
                    GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS
113
                )
114
            else:
115
                evm.refund_counter += int(
116
                    GasCosts.COLD_STORAGE_WRITE
117
                    - GasCosts.COLD_STORAGE_ACCESS
118
                    - GasCosts.WARM_ACCESS
119
                )
120
121
    charge_gas(evm, gas_cost)
122
    if evm.message.is_static:
123
        raise WriteInStaticContext
124
    set_storage(tx_state, evm.message.current_target, key, new_value)
125
126
    # PROGRAM COUNTER
127
    evm.pc += Uint(1)

tload

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

Parameters

evm : The current EVM frame.

def tload(evm: Evm) -> None:
131
    """
132
    Loads to the stack, the value corresponding to a certain key from the
133
    transient storage of the current account.
134
135
    Parameters
136
    ----------
137
    evm :
138
        The current EVM frame.
139
140
    """
141
    # STACK
142
    key = pop(evm.stack).to_be_bytes32()
143
144
    # GAS
145
    charge_gas(evm, GasCosts.WARM_ACCESS)
146
147
    # OPERATION
148
    value = get_transient_storage(
149
        evm.message.tx_env.state, evm.message.current_target, key
150
    )
151
    push(evm.stack, value)
152
153
    # PROGRAM COUNTER
154
    evm.pc += Uint(1)

tstore

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

Parameters

evm : The current EVM frame.

def tstore(evm: Evm) -> None:
158
    """
159
    Stores a value at a certain key in the current context's transient storage.
160
161
    Parameters
162
    ----------
163
    evm :
164
        The current EVM frame.
165
166
    """
167
    # STACK
168
    key = pop(evm.stack).to_be_bytes32()
169
    new_value = pop(evm.stack)
170
171
    # GAS
172
    charge_gas(evm, GasCosts.WARM_ACCESS)
173
    if evm.message.is_static:
174
        raise WriteInStaticContext
175
    set_transient_storage(
176
        evm.message.tx_env.state,
177
        evm.message.current_target,
178
        key,
179
        new_value,
180
    )
181
182
    # PROGRAM COUNTER
183
    evm.pc += Uint(1)