ethereum.constantinople.vm.instructions.storageethereum.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:
30
    """
31
    Loads to the stack, the value corresponding to a certain key from the
32
    storage of the current account.
33
34
    Parameters
35
    ----------
36
    evm :
37
        The current EVM frame.
38
39
    """
40
    # STACK
41
    key = pop(evm.stack).to_be_bytes32()
42
43
    # GAS
44
    charge_gas(evm, GAS_SLOAD)
45
46
    # OPERATION
47
    value = get_storage(evm.env.state, evm.message.current_target, key)
48
49
    push(evm.stack, value)
50
51
    # PROGRAM COUNTER
52
    evm.pc += 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:
56
    """
57
    Stores a value at a certain key in the current context's storage.
58
59
    Parameters
60
    ----------
61
    evm :
62
        The current EVM frame.
63
64
    """
65
    # STACK
66
    key = pop(evm.stack).to_be_bytes32()
67
    new_value = pop(evm.stack)
68
    if evm.gas_left <= GAS_CALL_STIPEND:
69
        raise OutOfGasError
70
68
    # GAS
71
    original_value = get_storage_original(
72
        evm.env.state, evm.message.current_target, key
73
    )
74
    current_value = get_storage(evm.env.state, evm.message.current_target, key)
70
    if new_value != 0 and current_value == 0:
71
        gas_cost = GAS_STORAGE_SET
75
76
    if original_value == current_value and current_value != new_value:
77
        if original_value == 0:
78
            gas_cost = GAS_STORAGE_SET
79
        else:
80
            gas_cost = GAS_STORAGE_UPDATE
81
    else:
73
        gas_cost = GAS_STORAGE_UPDATE
82
        gas_cost = GAS_SLOAD
83
75
    if new_value == 0 and current_value != 0:
76
        evm.refund_counter += GAS_STORAGE_CLEAR_REFUND
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 += int(GAS_STORAGE_CLEAR_REFUND)
89
90
        if original_value != 0 and current_value == 0:
91
            # Gas refund issued earlier to be reversed
92
            evm.refund_counter -= int(GAS_STORAGE_CLEAR_REFUND)
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(GAS_STORAGE_SET - GAS_SLOAD)
99
            else:
100
                # Slot was originally non-empty and was UPDATED earlier
101
                evm.refund_counter += int(GAS_STORAGE_UPDATE - GAS_SLOAD)
102
103
    charge_gas(evm, gas_cost)
104
    if evm.message.is_static:
105
        raise WriteInStaticContext
106
    set_storage(evm.env.state, evm.message.current_target, key, new_value)
107
108
    # PROGRAM COUNTER
109
    evm.pc += 1