evm v0.1.14 EVM.MachineCode

Functions for helping read a contract’s machine code.

Link to this section Summary

Functions

Builds machine code for a given set of instructions and data

Returns the current instruction being executed. In the Yellow Paper, this is often referred to as w, and is defined in Eq.(125) and again in Eq.(221)

Decompiles machine code

Returns true if the given new program_counter is a valid jump destination for the machine code, false otherwise

Returns the legal jump locations in the given machine code

Link to this section Types

Link to this type t()
t() :: binary

Link to this section Functions

Link to this function compile(code)
compile([atom | integer]) :: binary

Builds machine code for a given set of instructions and data.

Examples

iex> EVM.MachineCode.compile([:push1, 3, :push1, 5, :add, :return])
<<0x60, 0x03, 0x60, 0x05, 0x01, 0xf3>>

iex> EVM.MachineCode.compile([])
<<>>
Link to this function current_operation(machine_state, exec_env)

Returns the current instruction being executed. In the Yellow Paper, this is often referred to as w, and is defined in Eq.(125) and again in Eq.(221).

Examples

iex> EVM.MachineCode.current_operation(%EVM.MachineState{program_counter: 0}, %EVM.ExecEnv{machine_code: <<0x15::8, 0x11::8, 0x12::8>>})
%EVM.Operation.Metadata{args: [], description: "Simple not operator.", fun: nil, group: :comparison_and_bitwise_logic, id: 21, input_count: 1, machine_code_offset: 0, output_count: 1, sym: :iszero}

iex> EVM.MachineCode.current_operation(%EVM.MachineState{program_counter: 1}, %EVM.ExecEnv{machine_code: <<0x15::8, 0x11::8, 0x12::8>>})
%EVM.Operation.Metadata{args: [], description: "Greater-than comparision.", fun: nil, group: :comparison_and_bitwise_logic, id: 17, input_count: 2, machine_code_offset: 0, output_count: 1, sym: :gt}

iex> EVM.MachineCode.current_operation(%EVM.MachineState{program_counter: 2}, %EVM.ExecEnv{machine_code: <<0x15::8, 0x11::8, 0x12::8>>})
%EVM.Operation.Metadata{args: [], description: "Signed less-than comparision.", fun: nil, group: :comparison_and_bitwise_logic, id: 18, input_count: 2, machine_code_offset: 0, output_count: 1, sym: :slt}
Link to this function decompile(arg)
decompile(binary) :: [atom | integer]

Decompiles machine code.

Examples

iex> EVM.MachineCode.decompile(<<0x60, 0x03, 0x60, 0x05, 0x01, 0xf3>>)
[:push1, 3, :push1, 5, :add, :return]

iex> EVM.MachineCode.decompile(<<97, 0, 4, 128, 97, 0, 14, 96, 0, 57, 97, 0, 18, 86, 96, 0, 53, 255, 91, 96, 0, 243>>)
[:push2, 0, 4, :dup1, :push2, 0, 14, :push1, 0, :codecopy, :push2, 0, 18, :jump, :push1, 0, :calldataload, :suicide, :jumpdest, :push1, 0, :return]

iex> EVM.MachineCode.decompile(<<>>)
[]
Link to this function valid_jump_dest?(program_counter, machine_code)
valid_jump_dest?(EVM.MachineState.program_counter, t) :: boolean

Returns true if the given new program_counter is a valid jump destination for the machine code, false otherwise.

TODO: Memoize

Examples

iex> EVM.MachineCode.valid_jump_dest?(0, EVM.MachineCode.compile([:push1, 3, :push1, 5, :jumpdest, :add, :return, :jumpdest, :stop]))
false

iex> EVM.MachineCode.valid_jump_dest?(4, EVM.MachineCode.compile([:push1, 3, :push1, 5, :jumpdest, :add, :return, :jumpdest, :stop]))
true

iex> EVM.MachineCode.valid_jump_dest?(6, EVM.MachineCode.compile([:push1, 3, :push1, 5, :jumpdest, :add, :return, :jumpdest, :stop]))
false

iex> EVM.MachineCode.valid_jump_dest?(7, EVM.MachineCode.compile([:push1, 3, :push1, 5, :jumpdest, :add, :return, :jumpdest, :stop]))
true

iex> EVM.MachineCode.valid_jump_dest?(100, EVM.MachineCode.compile([:push1, 3, :push1, 5, :jumpdest, :add, :return, :jumpdest, :stop]))
false
Link to this function valid_jump_destinations(machine_code)
valid_jump_destinations(t) :: [EVM.MachineState.program_counter]

Returns the legal jump locations in the given machine code.

TODO: Memoize

Example

iex> EVM.MachineCode.valid_jump_destinations(EVM.MachineCode.compile([:push1, 3, :push1, 5, :jumpdest, :add, :return, :jumpdest, :stop]))
[4, 7]