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