> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chaintable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# leafage-py

> Leafage Python reference for blocks, account state, and contract return values.

Leafage reads on-chain state at a specified chain and block. Run these examples in a Chaintable Notebook. For Function usage, see [Data access](/guides/functions/data-access). The [source](https://github.com/Chaintable/leafage-py) contains the full implementation.

## Create a block context

```python theme={null}
from leafage import ChainState

block = ChainState.get_block_by_height('eth', 25939934)
chain = ChainState('eth', block['id'])
```

### `ChainState(chain_id, block_id)`

| Parameter  | Type  | Description                                  |
| ---------- | ----- | -------------------------------------------- |
| `chain_id` | `str` | Chain ID, such as `eth` for Ethereum mainnet |
| `block_id` | `str` | Block ID at which to read state              |

Returns a `ChainState` object. For consistent multiple reads, first resolve a block ID and then reuse the same object.

## Block queries

These are class methods, called directly on `ChainState`.

| Interface                                     | Parameters                  | Return value              |
| --------------------------------------------- | --------------------------- | ------------------------- |
| `get_latest_block(chain_id)`                  | Chain ID                    | Latest block dictionary   |
| `get_block_by_height(chain_id, block_height)` | Chain ID and integer height | Matching block dictionary |
| `get_block_by_id(chain_id, block_id)`         | Chain ID and block ID       | Matching block dictionary |
| `check_block_is_valid(chain_id, block_id)`    | Chain ID and block ID       | Block validity as `bool`  |

Block dictionaries include `id`, `height`, and `timestamp`. `timestamp` is Unix time in seconds. Additional fields may vary by chain.

## Account state

```python theme={null}
wallet = '0xd8da6bf26964af9d7eed9e03e53415d37aa96045'
balance_wei = chain.get_address_balance(wallet)
print(balance_wei)
```

| Interface                                      | Parameters                                | Return value                                                  |
| ---------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------- |
| `chain.get_address_balance(addr)`              | Address string                            | Python `int` in the native token's smallest unit; wei for ETH |
| `chain.get_address_code(addr)`                 | Contract address                          | Bytecode string starting with `0x`                            |
| `chain.get_storage_at(addr, slot)`             | Address and storage slot, such as `'0x0'` | Storage value string starting with `0x`                       |
| `ChainState.get_address_nonce(chain_id, addr)` | Chain ID and address                      | Latest nonce as Python `int`                                  |

`get_address_nonce()` uses the latest block, so it does not return a historical nonce from the `chain` object's context. The other three instance methods use that object's block context.

## Single contract call

### `chain.call(contract, method, payload, from_addr=None)`

| Parameter   | Description                                                                  |
| ----------- | ---------------------------------------------------------------------------- |
| `contract`  | Contract address                                                             |
| `method`    | Signature with input and output types, such as `balanceOf(address)(uint256)` |
| `payload`   | Positional argument list; use `[]` for no arguments                          |
| `from_addr` | Optional caller address for the simulated call context                       |

Returns decoded values. Multiple outputs can be unpacked; integers are Python `int` values.

```python theme={null}
pool = '0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc'
reserve_usdc, reserve_weth, timestamp = chain.call(
    pool, 'getReserves()(uint112,uint112,uint32)', []
)
```

This reads or simulates a contract call. It does not send a transaction to the chain.

## Batch contract calls

```python theme={null}
usdc = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
values = (
    chain.contract(usdc)
    .method('symbol()(string)', 'decimals()(uint8)')
    .payload([], [])
    .values()
)
print(values)
```

The output is `['USDC', 6]`.

| Builder step                    | Parameters and result                                                                           |
| ------------------------------- | ----------------------------------------------------------------------------------------------- |
| `contract(*contracts)`          | One or more contract addresses                                                                  |
| `method(*methods)`              | One or more method signatures; contracts and methods cannot both have multiple entries          |
| `payload(*payloads)`            | Positional argument lists for each call; empty lists may be omitted for calls with no arguments |
| `from_addr(addr)`               | Set the caller address                                                                          |
| `options(raise_on_error=False)` | Allow failed entries to return `None`; by default, call errors raise exceptions                 |
| `values()`                      | Return a list of results                                                                        |
| `zip(*keys)`                    | Return an iterator pairing keys with results                                                    |
| `dict(*keys)`                   | Return a dictionary using caller-supplied keys                                                  |

For example, replace `.values()` with `.dict('symbol', 'decimals')` to get `{'symbol': 'USDC', 'decimals': 6}`.

## State overrides

`set_block_overrides(value)` and `set_state_overrides(value)` set block and account-state overrides for simulated calls. The corresponding `get_*_overrides()` methods return current settings. Overrides affect simulated reads without changing on-chain state. See the [Leafage source](https://github.com/Chaintable/leafage-py) for field definitions and full examples.
