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

# Write EVM data functions

> Read a contract at an explicit block and produce an exact derived value.

Use a function to turn EVM state or event inputs into a derived record. This example queries a token balance and carries the read context in its output.

## Chain and block context

Provide a chain supported by your node backend, a concrete block identifier, a token contract, and a holder address. Use a block that the backend can serve. `EVM(chain_id, block_id)` binds the object's state reads and contract queries to that context.

## Prerequisites

* A BlockX execution environment with EVM node access.
* A contract that implements `balanceOf(address)(uint256)` at the selected block.
* Function dependencies matching the BlockX checkout's `python/pyproject.toml`.

## Write the function

```python theme={null}
def _(chain_id, block_id, token, holder):
    from leafage import EVM

    evm = EVM(chain_id, block_id)
    balance = evm.call(token, "balanceOf(address)(uint256)", [holder])
    return {
        "id": holder,
        "chain_id": chain_id,
        "block_id": block_id,
        "token": token,
        "balance": balance,
    }
```

Keep `balance` as an integer. To write the record to a table, prepare compatible target columns; table writers project returned records onto the target schema.

## Submit the arguments

For one-off computation, place `[chain_id, block_id, token, holder]` in one row of `InputsCallConfig.callList` and use `ReturnValueHandler`. See [Run once](/guides/run-once) for the submission pattern.

For trigger-table computation, build these arguments from the source schema. Pass the row's block context when processing history; selecting a bundle does not bind every row's dependency reads to one historical block.

## Confirm the result

Check task success and inspect `balance`, `block_id`, and `token` in the returned record. A returned value confirms the computation for those arguments; it does not write a table unless you select a table Writer Plugin.

## Handle failures

| Symptom | Check |
| - | - |
| Block unavailable | The backend serves the selected chain and historical block |
| Contract call reverts or decoding fails | Contract address, method signature, arguments, and block |
| Function rejected | Supported imports and audit findings |
| Unexpected historical value | The explicit block passed into the function |

## Continue reading

* [EVM computation model](/concepts/evm-computation)
* [Compute per block](/guides/block-computation)
* [Invoke and debug](/guides/synchronous-invocation)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.