ethereum.forks.istanbul.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:
27
    """
28
    Loads to the stack, the value corresponding to a certain key from the
29
    storage of the current account.
30
31
    Parameters
32
    ----------
33
    evm :
34
        The current EVM frame.
35
36
    """
37
    # STACK
38
    key = pop(evm.stack).to_be_bytes32()
39
40
    # GAS
41
    charge_gas(evm, GasCosts.SLOAD)
42
43
    # OPERATION
44
    value = get_storage(
45
        evm.message.block_env.state, evm.message.current_target, key
46
    )
47
48
    push(evm.stack, value)
49
50
    # PROGRAM COUNTER
51
    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:
55
    """
56
    Stores a value at a certain key in the current context's storage.
57
58
    Parameters
59
    ----------
60
    evm :
61
        The current EVM frame.
62
63
    """
64
    # STACK
65
    key = pop(evm.stack).to_be_bytes32()
66
    new_value = pop(evm.stack)
67
    if evm.gas_left <= GasCosts.CALL_STIPEND:
68
        raise OutOfGasError
69
70
    state = evm.message.block_env.state
71
    original_value = get_storage_original(
72
        state, evm.message.current_target, key
73
    )
74
    current_value = get_storage(state, evm.message.current_target, key)
75
76
    if original_value == current_value and current_value != new_value:
77
        if original_value == 0:
78
            gas_cost = GasCosts.STORAGE_SET
79
        else:
80
            gas_cost = GasCosts.COLD_STORAGE_WRITE
81
    else:
82
        gas_cost = GasCosts.SLOAD
83
84
    # Refund Counter Calculation
85
    if current_value != new_value:
86
        if original_value != 0 and current_value != 0 and new_value == 0:
87
            # Storage is cleared for the first time in the transaction
88
            evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR
89
90
        if original_value != 0 and current_value == 0:
91
            # Gas refund issued earlier to be reversed
92
            evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR
93
94
        if original_value == new_value:
95
            # Storage slot being restored to its original value
96
            if original_value == 0:
97
                # Slot was originally empty and was SET earlier
98
                evm.refund_counter += int(
99
                    GasCosts.STORAGE_SET - GasCosts.SLOAD
100
                )
101
            else:
102
                # Slot was originally non-empty and was UPDATED earlier
103
                evm.refund_counter += int(
104
                    GasCosts.COLD_STORAGE_WRITE - GasCosts.SLOAD
105
                )
106
107
    charge_gas(evm, gas_cost)
108
    if evm.message.is_static:
109
        raise WriteInStaticContext
110
    set_storage(state, evm.message.current_target, key, new_value)
111
112
    # PROGRAM COUNTER
113
    evm.pc += Uint(1)