# `EEVM.Interpreter.Instructions.Helpers`
[🔗](https://github.com/mw2000/eevm/blob/v0.1.0/lib/eevm/interpreter/instructions/helpers.ex#L1)

Shared utilities for opcode implementations.

Provides:

- Stack-pop / push helpers for the common pop-pop-compute-push shape used
  by arithmetic, comparison, and bitwise opcodes.
- Two's-complement conversion (`to_signed/1`, `to_unsigned/1`) bridging
  the uint256 stack with signed opcodes (SLT, SGT, SDIV, SMOD, SAR).
- `mod_pow/3`, square-and-multiply modular exponentiation used by EXP.
- `pop_address/1` for opcodes that take an address operand.
- `touch_account/3`, which before EIP-161 creates the accounts a message
  call or fee credit touches. The transaction handler shares it.

# `bitwise_op`

```elixir
@spec bitwise_op(EEVM.Interpreter.MachineState.t(), (non_neg_integer(),
                                               non_neg_integer() -&gt;
                                                 non_neg_integer())) ::
  {:ok, EEVM.Interpreter.MachineState.t()}
  | {:error, atom(), EEVM.Interpreter.MachineState.t()}
```

Pops two values, applies a bitwise function, and pushes the result.

Used by AND (0x16), OR (0x17), and XOR (0x18). The function `fun` receives
`a` and `b` as uint256 values and must return a uint256.

# `comparison_op`

```elixir
@spec comparison_op(EEVM.Interpreter.MachineState.t(), (non_neg_integer(),
                                                  non_neg_integer() -&gt;
                                                    boolean())) ::
  {:ok, EEVM.Interpreter.MachineState.t()}
  | {:error, atom(), EEVM.Interpreter.MachineState.t()}
```

Pops two values from the stack, applies a comparison, and pushes 1 or 0.

Used by LT (0x10), GT (0x11), and EQ (0x14). The comparison function `fun`
receives `a` (first pop) and `b` (second pop) as unsigned integers.

# `mod_pow`

```elixir
@spec mod_pow(non_neg_integer(), non_neg_integer(), pos_integer()) ::
  non_neg_integer()
```

Computes `base^exp mod m` using square-and-multiply (binary exponentiation).

Used by EXP (0x0A). The naive approach of multiplying `base` by itself `exp`
times would be O(exp) — unusable for 256-bit exponents. Square-and-multiply
is O(log exp), making it practical even for large values.

# `pop_address`

```elixir
@spec pop_address(EEVM.Interpreter.Stack.t()) ::
  {:ok, non_neg_integer(), EEVM.Interpreter.Stack.t()} | {:error, atom()}
```

Pops an address operand: the top stack word truncated to its low 160 bits,
as BALANCE, EXTCODESIZE, EXTCODECOPY, EXTCODEHASH, the CALL family, and
SELFDESTRUCT read it (Yellow Paper Appendix H, `μs[0] mod 2^160`).

    iex> {:ok, stack} = EEVM.Interpreter.Stack.push(EEVM.Interpreter.Stack.new(), 2 ** 200 + 0xAB)
    iex> {:ok, address, _} = EEVM.Interpreter.Instructions.Helpers.pop_address(stack)
    iex> address
    0xAB

# `push_value`

```elixir
@spec push_value(EEVM.Interpreter.MachineState.t(), non_neg_integer()) ::
  {:ok, EEVM.Interpreter.MachineState.t()}
```

Pushes a value onto the stack and advances the program counter by 1.

This is the final step in almost every opcode: after computing a result,
push it and move to the next instruction.

# `signed_comparison_op`

```elixir
@spec signed_comparison_op(
  EEVM.Interpreter.MachineState.t(),
  (integer(), integer() -&gt; boolean())
) ::
  {:ok, EEVM.Interpreter.MachineState.t()}
  | {:error, atom(), EEVM.Interpreter.MachineState.t()}
```

Same as `comparison_op/2` but interprets both values as signed 256-bit integers.

Used by SLT (0x12) and SGT (0x13). Converts each uint256 operand to two's
complement before applying the comparison, then pushes 1 or 0.

# `to_signed`

```elixir
@spec to_signed(non_neg_integer()) :: integer()
```

Converts a uint256 value to a signed 256-bit integer (two's complement).

Any value with the 255th bit set (>= 2^255) is treated as negative. For
example, the uint256 representation of -1 is 2^256 - 1 (all bits set).

# `to_unsigned`

```elixir
@spec to_unsigned(integer()) :: non_neg_integer()
```

Converts a signed integer back to its uint256 (two's complement) representation.

Negative values are mapped to the upper half of the uint256 range. Positive
values (and zero) pass through unchanged.

# `touch_account`

```elixir
@spec touch_account(EEVM.Database.t(), non_neg_integer(), EEVM.HardforkConfig.t()) ::
  EEVM.Database.t()
```

Before EIP-161 (Spurious Dragon), touching an account that doesn't exist
creates it empty, even when no value moves: the target of every message
call, and the coinbase credited a zero fee (execution-specs Frontier
`process_message` calls `touch_account`; `process_transaction` sets the
coinbase balance). From EIP-161 the account is not created, and touched
empty accounts are deleted when the transaction ends.

## Example

    iex> alias EEVM.{Database, HardforkConfig}
    iex> alias EEVM.Interpreter.Instructions.Helpers
    iex> db = EEVM.Database.InMemory.new()
    iex> Database.account_exists?(Helpers.touch_account(db, 0xAB, HardforkConfig.new(:frontier)), 0xAB)
    true
    iex> Database.account_exists?(Helpers.touch_account(db, 0xAB, HardforkConfig.new(:spurious_dragon)), 0xAB)
    false

---

*Consult [api-reference.md](api-reference.md) for complete listing*
