evm v0.1.14 EVM.Memory
Functions to help us handle memory operations in the MachineState of the VM.
Link to this section Summary
Functions
When calling instructions, we may adjust the number
of active words in the machine state. These functions
provide a simple way to determine the number of words
after an instruction would be called. This wraps anywhere
you might see μ'_i
in the Yellow Paper
Returns the highest active word from the given inputs
Reads a word out of memory, and also decides whether or not we should increment number of active words in our machine state
Read zeroed memory will read bytes from a certain offset in the memory binary. Any bytes extending beyond memory’s size will be defauled to zero
Writes data to memory, and also decides whether or not we should increment number of active words in our machine state
Link to this section Types
Link to this section Functions
active_words_after(EVM.Operation.instruction, EVM.state, EVM.MachineState.t, EVM.ExecEnv.t) :: integer
When calling instructions, we may adjust the number
of active words in the machine state. These functions
provide a simple way to determine the number of words
after an instruction would be called. This wraps anywhere
you might see μ'_i
in the Yellow Paper.
Returns the highest active word from the given inputs.
Examples
iex> EVM.Memory.get_active_words(0) # TODO: We may actually want this to start at 1, even for zero bytes read
0
iex> EVM.Memory.get_active_words(80)
3
iex> EVM.Memory.get_active_words(321)
11
read(EVM.MachineState.t, EVM.val, EVM.val) :: {binary, EVM.MachineState.t}
Reads a word out of memory, and also decides whether or not we should increment number of active words in our machine state.
Examples
iex> EVM.Memory.read(%EVM.MachineState{memory: <<1::256, 2::256, 3::256, 4::256>>, active_words: 0}, 0, 0)
{<<>>, %EVM.MachineState{memory: <<1::256, 2::256, 3::256, 4::256>>, active_words: 0}}
iex> EVM.Memory.read(%EVM.MachineState{memory: <<1::256, 2::256, 3::256, 4::256>>, active_words: 0}, 0, 30)
{<<0::240>>, %EVM.MachineState{memory: <<1::256, 2::256, 3::256, 4::256>>, active_words: 1}}
iex> EVM.Memory.read(%EVM.MachineState{memory: <<1::256, 2::256, 3::256, 4::256>>, active_words: 0}, 0, 35)
{<<1::256, 0::24>>, %EVM.MachineState{memory: <<1::256, 2::256, 3::256, 4::256>>, active_words: 2}}
iex> EVM.Memory.read(%EVM.MachineState{memory: <<1::256, 2::256, 3::256, 4::256>>, active_words: 0}, 32, 35)
{<<2::256, 0::24>>, %EVM.MachineState{memory: <<1::256, 2::256, 3::256, 4::256>>, active_words: 3}}
iex> EVM.Memory.read(%EVM.MachineState{memory: <<1::256>>, active_words: 0}, 0, 35)
{<<1::256, 0::24>>, %EVM.MachineState{memory: <<1::256>>, active_words: 2}}
Read zeroed memory will read bytes from a certain offset in the memory binary. Any bytes extending beyond memory’s size will be defauled to zero.
Examples
iex> EVM.Memory.read_zeroed_memory(nil, 1, 4)
<<0, 0, 0, 0>>
iex> EVM.Memory.read_zeroed_memory(<<1, 2, 3>>, 1, 4)
<<2, 3, 0, 0>>
iex> EVM.Memory.read_zeroed_memory(<<1, 2, 3>>, 1, 2)
<<2, 3>>
iex> EVM.Memory.read_zeroed_memory(<<16, 17, 18, 19>>, 100, 1)
<<0>>
write(EVM.MachineState.t, EVM.val, binary, integer) :: EVM.MachineState.t
Writes data to memory, and also decides whether or not we should increment number of active words in our machine state.
Note: we will fill in zeros if the memory extends beyond our previous memory bounds. This could (very easily) overflow our memory by making a single byte write to a far-away location. The gas might be high, but it’s still not desirable to have a system crash. The easiest mitigation will likely be to load in pages of memory as needed. These pages could have an offset and thus a far away page will only add a few bytes of memory.
For now, we’ll simply extend our memory and perform a simple write operation.
Note: we also may just use a different data structure all-together for this.
Examples
iex> EVM.Memory.write(%EVM.MachineState{memory: <<>>, active_words: 0}, 5, <<1, 1>>)
%EVM.MachineState{memory: <<0, 0, 0, 0, 0, 1, 1>>, active_words: 1}
iex> EVM.Memory.write(%EVM.MachineState{memory: <<0, 1, 2, 3, 4>>, active_words: 0}, 1, <<6, 6>>)
%EVM.MachineState{memory: <<0, 6, 6, 3, 4>>, active_words: 1}
iex> EVM.Memory.write(%EVM.MachineState{memory: <<0, 1, 2, 3, 4>>, active_words: 0}, 0, <<10, 11, 12, 13, 14, 15>>)
%EVM.MachineState{memory: <<10, 11, 12, 13, 14, 15>>, active_words: 1}
iex> EVM.Memory.write(%EVM.MachineState{memory: <<1, 1, 1>>, active_words: 0}, 5, <<1::80>>)
%EVM.MachineState{memory: <<1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1>>, active_words: 1}