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

# Block data for EVM

> Block data interfaces for EVM — the batch handler context and the Block item iterables.

In EVM Squid SDK, the data is processed by repeatedly calling the user-defined [batch handler](../batch-processor#handler-context) function on batches of on-chain data. The sole argument of the batch handler is its context `ctx` with the structure `{store, blocks, isHead}`:

* `ctx.store` is the [store](../data-stores/store-interface) exposed by the database passed to [`run()` or `Processor`](../batch-processor#run-and-processor);
* `ctx.blocks` is an array of `Block` objects containing the data to be processed, aligned at the block level;
* `ctx.isHead` is `true` when the batch ends at the current chain head.

Portal-native handlers do not receive `ctx.log` — create a [logger](../logger) explicitly with `createLogger()` from `@subsquid/logger` if the handler needs one.

The `Block` interface is defined as follows:

```ts theme={"system"}
export interface Block<F extends FieldSelection = {}> {
  header: BlockHeader<F>
  transactions: Transaction<F>[]
  logs: Log<F>[]
  traces: Trace<F>[]
  stateDiffs: StateDiff<F>[]
}
```

`F` here is the type of the argument of the [`setFields()`](./field-selection) method of `DataSourceBuilder`.

`Block.header` contains the block header data; use `header.number` for the block height (`header.height` remains available only as a deprecated alias). The rest of the fields are flat iterables containing the four kinds of blockchain data. The items are not nested under their transactions — related items land in their own iterables (see [Augmented blocks](#augmented-blocks) for convenient navigation between them). The canonical ordering within each iterable depends on the data kind:

* `transactions` and `logs` are ordered in the same way as they are within blocks;
* [`stateDiffs`](./state-diffs) follow the order of transactions that gave rise to them;
* `traces` are ordered by `transactionIndex` and then lexicographically by `traceAddress`.

## Field guarantees

Each data item is guaranteed to have a small set of always-present fields (e.g. `logIndex` and `transactionIndex` for logs) plus exactly the fields requested with [`setFields()`](./field-selection) — there are no default optional fields. The exact fields available in each data item type are inferred from the `setFields()` call argument and documented on the [field selection](./field-selection) page:

* [transactions section](./field-selection#transactions);
* [logs section](./field-selection#logs);
* [traces section](./field-selection#traces);
* [state diffs section](./field-selection#state-diffs);
* [block headers section](./field-selection#block-headers).

Use `GetDataSourceBlock` to derive the exact block type from a configured data source:

```ts theme={"system"}
import {GetDataSourceBlock} from '@subsquid/evm-stream'

type RawBlock = GetDataSourceBlock<typeof dataSource>
```

<h2 id="augmented-blocks">
  Augmented blocks
</h2>

The raw items of `ctx.blocks` are plain data objects without item IDs or references between related items. `augmentBlock()` from `@subsquid/evm-objects` adds them:

```ts theme={"system"}
import {augmentBlock} from '@subsquid/evm-objects'

run(dataSource, database, async ctx => {
  let blocks = ctx.blocks.map(augmentBlock)
  // ...
})
```

Augmented items gain:

* `id`: a unique string identifier, handy as an entity primary key (also available on `header`);
* `block`: a reference to the block header of the item's block;
* `log.transaction` / `log.getTransaction()`: the parent transaction of a log;
* `trace.transaction` / `trace.getTransaction()`, `trace.parent` / `trace.getParent()`, `trace.children`: navigation across the trace tree and to the parent transaction;
* `stateDiff.transaction` / `stateDiff.getTransaction()`: the parent transaction of a state diff;
* `transaction.logs`, `transaction.traces`, `transaction.stateDiffs`: the related items of a transaction.

The optional properties (e.g. `log.transaction`) are populated only when the related items are present in the block data — request them with the `include` flags of the [data requests](../evm-stream). The `get*()` variants return the same values but throw instead of returning `undefined` when the related item is missing.

The package also exports the `formatId()` and `shortHash()` utilities used to build the IDs, and the `AugmentedBlock<B>` type that maps a raw block type to its augmented counterpart:

```ts theme={"system"}
import {AugmentedBlock} from '@subsquid/evm-objects'

type Block = AugmentedBlock<RawBlock>
```

## Example

The handler below simply outputs all the log items emitted by the contract `0x2E645469f354BB4F5c8a05B3b30A929361cf77eC` in [real time](../../guides/advanced/unfinalized-blocks):

```ts theme={"system"}
import {run} from '@subsquid/batch-processor'
import {DataSourceBuilder} from '@subsquid/evm-stream'
import {createLogger} from '@subsquid/logger'
import {TypeormDatabase} from '@subsquid/typeorm-store'

const CONTRACT_ADDRESS = '0x2E645469f354BB4F5c8a05B3b30A929361cf77eC'.toLowerCase()

const dataSource = new DataSourceBuilder()
  .setPortal('https://portal.sqd.dev/datasets/ethereum-mainnet')
  .setBlockRange({from: 17_000_000})
  .addLog({
    where: {address: [CONTRACT_ADDRESS]}
  })
  .setFields({
    log: {
      address: true,
      topics: true,
      data: true
    }
  })
  .build()

const log = createLogger('sqd:processor:gravatar')

run(dataSource, new TypeormDatabase({supportHotBlocks: true}), async (ctx) => {
  for (let block of ctx.blocks) {
    for (let item of block.logs) {
      if (item.address === CONTRACT_ADDRESS) {
        log.info(item, 'Log:')
      }
    }
  }
})
```

Note that the `address` field must be requested with `setFields()` to be read in the handler — there are no default fields.

For more elaborate examples, check [EVM Examples](../../examples-tutorials/examples-widget).
