# `EEVM.Context.Contract`
[🔗](https://github.com/mw2000/eevm/blob/main/lib/eevm/context/contract.ex#L1)

Contract/message-level context — the current call frame's environment.
Each CALL / DELEGATECALL / STATICCALL / CREATE frame has its own.

### Fields

| Field | Opcode | Description |
|-------|--------|-------------|
| `address` | ADDRESS (0x30) | Address of the executing contract |
| `caller` | CALLER (0x33) | Direct caller of this frame (msg.sender) |
| `callvalue` | CALLVALUE (0x34) | ETH (wei) sent with this call |
| `calldata` | CALLDATALOAD/SIZE/COPY | Input data for this call |
| `balances` | BALANCE/SELFBALANCE | Account balance lookup |

### Caller vs Origin

- `caller` (CALLER/msg.sender) = who directly called this contract.
  Changes with each nested CALL.
- `origin` (ORIGIN/tx.origin, in `EEVM.Context.Transaction`) = the EOA that
  signed the transaction. Never changes.

Example: EOA -> Contract A -> Contract B; in B, `caller = A`, `origin = EOA`.

# `t`

```elixir
@type t() :: %EEVM.Context.Contract{
  address: non_neg_integer(),
  balances: %{required(non_neg_integer()) =&gt; non_neg_integer()},
  calldata: binary(),
  caller: non_neg_integer(),
  callvalue: non_neg_integer()
}
```

# `balance`

```elixir
@spec balance(t(), non_neg_integer()) :: non_neg_integer()
```

Returns the balance of an address. Returns 0 for unknown addresses.

# `calldata_load`

```elixir
@spec calldata_load(t(), non_neg_integer()) :: non_neg_integer()
```

Reads 32 bytes from calldata starting at the given byte offset.

Calldata shorter than offset+32 is right-padded with zeros, matching
EVM spec behavior. This is what CALLDATALOAD does.

## Elixir Learning Note

We use `binary_part/3` with bounds checking and manual zero-padding.
Elixir binaries are immutable byte sequences — slicing them is O(1).

# `new`

```elixir
@spec new() :: t()
```

Creates a new contract context with default values.

# `new`

```elixir
@spec new(keyword()) :: t()
```

Creates a new contract context with the given overrides.

## Example

    iex> contract = EEVM.Context.Contract.new(caller: 0xDEAD, callvalue: 1000)
    iex> contract.caller
    0xDEAD

---

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