evm v0.1.4 EVM.Operation.StackMemoryStorageAndFlow
Link to this section Summary
Functions
Encodes signed ints using twos compliment
Get the amount of available gas, including the corresponding reduction for the cost of this instruction
Alter the program counter
Mark a valid destination for jumps
Conditionally alter the program counter
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
Encodes signed ints using twos compliment
Examples
iex> EVM.Helpers.encode_signed(1)
1
iex> EVM.Helpers.encode_signed(-1)
EVM.max_int() - 1
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.
TODO: Implement opcode
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.gas([], %{stack: []})
:unimplemented
jump(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Alter the program counter.
This is a no-op as it’s handled elsewhere in the VM.
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.jump([], %{stack: []})
: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
Conditionally alter the program counter.
This is a no-op as it’s handled elsewhere in the VM.
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.jumpi([], %{stack: []})
: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>>}})
%{machine_state: %EVM.MachineState{stack: [0x55, 1], memory: <<0x55::256, 0xff>>, active_words: 1}}
iex> EVM.Operation.StackMemoryStorageAndFlow.mload([1], %{machine_state: %EVM.MachineState{stack: [], memory: <<0x55::256, 0xff>>}})
%{machine_state: %EVM.MachineState{stack: [22015], memory: <<0x55::256, 0xff>>, active_words: 2}}
# 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
TODO: Implement opcode
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.msize([], %{stack: []})
:unimplemented
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.
pc(Operation.stack_args, Operation.vm_map) :: Operation.op_result
Get the value of the program counter prior to the increment corresponding to this instruction.
TODO: Implement opcode
Examples
iex> EVM.Operation.StackMemoryStorageAndFlow.pc([], %{stack: []})
:unimplemented
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> db = MerklePatriciaTree.Test.random_ets_db()
iex> state = EVM.Operation.StackMemoryStorageAndFlow.sstore([0x11223344556677889900, 0x111222333444555], %{state: MerklePatriciaTree.Trie.new(db)})[:state]
iex> EVM.Operation.StackMemoryStorageAndFlow.sload([0x11223344556677889900], %{state: state, stack: []})
%{
stack: [0x111222333444555]
}
iex> db = MerklePatriciaTree.Test.random_ets_db()
iex> state = EVM.Operation.StackMemoryStorageAndFlow.sstore([0x11223344556677889900, 0x111222333444555], %{state: MerklePatriciaTree.Trie.new(db)})[:state]
iex> EVM.Operation.StackMemoryStorageAndFlow.sload([0x1234], %{state: state, stack: []})
%{
stack: [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> db = MerklePatriciaTree.Test.random_ets_db(:store_word_test)
iex> EVM.Operation.StackMemoryStorageAndFlow.sstore([0x11223344556677889900, 0x111222333444555], %{state: MerklePatriciaTree.Trie.new(db)})
%{
state: %MerklePatriciaTree.Trie{db: {MerklePatriciaTree.DB.ETS, :store_word_test}, root_hash: <<128, 58, 53, 102, 7, 182, 120, 131, 145, 91, 222, 83, 56, 42, 251, 168, 203, 138, 130, 246, 76, 122, 110, 218, 183, 131, 33, 205, 154, 136, 194, 212>>}
}
iex> db = MerklePatriciaTree.Test.random_ets_db()
iex> EVM.Operation.StackMemoryStorageAndFlow.sstore([0x11223344556677889900, 0x111222333444555], %{state: MerklePatriciaTree.Trie.new(db)})[:state] |> MerklePatriciaTree.Trie.Inspector.all_values()
[
{<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17, 34, 51, 68, 85, 102, 119, 136, 153, 0>>,
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 17, 34, 35, 51, 68, 69, 85>>
}
]
iex> db = MerklePatriciaTree.Test.random_ets_db()
iex> EVM.Operation.StackMemoryStorageAndFlow.sstore([0x0, 0x0], %{state: MerklePatriciaTree.Trie.new(db)})[:state] |> MerklePatriciaTree.Trie.Inspector.all_values()
[
]