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