evm v0.1.14 EVM.Operation.StackMemoryStorageAndFlow
Link to this section Summary
Functions
Get the amount of available gas, including the corresponding reduction for the cost of this instruction
Jumps are handled by EVM.ProgramCounter.next
. This is a noop
Mark a valid destination for jumps
Jumps are handled by EVM.ProgramCounter.next
. This is a noop
Load word from memory
Get the size of active memory in bytes
Save word to memory
Save byte to memory
Get the value of the program counter prior to the increment corresponding to this instruction
Remove item from stack
Load word from storage
Save word to storage
Link to this section Functions
gas(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Get the amount of available gas, including the corresponding reduction for the cost of this instruction.
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.gas([], %{machine_state: %{gas: 99}})
99
jump(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Jumps are handled by EVM.ProgramCounter.next
. This is a noop.
jumpdest(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Mark a valid destination for jumps.
This is a no-op.
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.jumpdest([], %{stack: []})
:noop
jumpi(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Jumps are handled by EVM.ProgramCounter.next
. This is a noop.
mload(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Load word from memory
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.mload([0], %{machine_state: %EVM.MachineState{stack: [1], memory: <<0x55::256, 0xff>>}})
%EVM.MachineState{stack: [0x55, 1], active_words: 1, gas: nil, memory: <<0x55::256, 0xff>>, program_counter: 0, previously_active_words: 0}
iex> EVM.Operation.StackMemoryStorageAndFlow.mload([1], %{machine_state: %EVM.MachineState{stack: [], memory: <<0x55::256, 0xff>>}})
%EVM.MachineState{stack: [22015], active_words: 2, gas: nil, memory: <<0x55::256, 0xff>>, program_counter: 0, previously_active_words: 0}
# TODO: Add a test for overflow, etc.
# TODO: Handle sign?
msize(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Get the size of active memory in bytes
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.msize([], %{machine_state: %EVM.MachineState{active_words: 1}})
32
mstore(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Save word to memory.
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.mstore([0, 0x55], %{machine_state: %EVM.MachineState{stack: [], memory: <<>>}})
%{machine_state: %EVM.MachineState{stack: [], memory: <<0x55::256>>, active_words: 1}}
iex> EVM.Operation.StackMemoryStorageAndFlow.mstore([1, 0x55], %{machine_state: %EVM.MachineState{stack: [], memory: <<>>}})
%{machine_state: %EVM.MachineState{stack: [], memory: <<0, 0x55::256>>, active_words: 2}}
# TODO: Add a test for overflow, etc.
# TODO: Handle sign?
mstore8(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Save byte to memory.
Get the value of the program counter prior to the increment corresponding to this instruction.
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.pc([], %{machine_state: %EVM.MachineState{program_counter: 99}})
99
pop(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Remove item from stack.
TODO: Implement opcode
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.pop([55], %{stack: []})
:noop
sload(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Load word from storage.
TODO: Handle signed values?
Examples
iex> address = 0x0000000000000000000000000000000000000001
iex> key = 0x11223344556677889900
iex> value = 0x111222333444555
iex> account_interface = EVM.Interface.Mock.MockAccountInterface.new()
iex> account_interface = EVM.Operation.StackMemoryStorageAndFlow.sstore([key, value], %{exec_env: %EVM.ExecEnv{address: address, account_interface: account_interface}})[:exec_env].account_interface
iex> EVM.Operation.StackMemoryStorageAndFlow.sload([key], %{exec_env: %EVM.ExecEnv{account_interface: account_interface, address: address}})
0x111222333444555
iex> address = 0x0000000000000000000000000000000000000001
iex> key = 0x11223344556677889900
iex> other_key = 0x1234
iex> value = 0x111222333444555
iex> account_interface = EVM.Interface.Mock.MockAccountInterface.new()
iex> account_interface = EVM.Operation.StackMemoryStorageAndFlow.sstore([key, value], %{exec_env: %EVM.ExecEnv{address: address, account_interface: account_interface}})[:exec_env].account_interface
iex> EVM.Operation.StackMemoryStorageAndFlow.sload([other_key], %{exec_env: %EVM.ExecEnv{account_interface: account_interface}})
0x0
sstore(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Save word to storage.
Defined as σ′[Ia]_s[μ_s[0]] ≡ μ_s[1]
TODO: Complex gas costs, including refund. TODO: Handle signed values
Examples
iex> address = 0x0000000000000000000000000000000000000001
iex> key = 0x11223344556677889900
iex> value = 0x111222333444555
iex> account_interface = EVM.Interface.Mock.MockAccountInterface.new()
iex> EVM.Operation.StackMemoryStorageAndFlow.sstore([key, value], %{exec_env: %EVM.ExecEnv{address: address, account_interface: account_interface}})[:exec_env].account_interface
...> |> EVM.Interface.AccountInterface.get_storage(address, key)
{:ok, 0x111222333444555}
iex> address = 0x0000000000000000000000000000000000000001
iex> account_interface = EVM.Interface.Mock.MockAccountInterface.new()
iex> EVM.Operation.StackMemoryStorageAndFlow.sstore([0x0, 0x0], %{exec_env: %EVM.ExecEnv{address: address, account_interface: account_interface}})[:exec_env].account_interface |> EVM.Interface.AccountInterface.dump_storage()
%{1 => %{}}