> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.ampdb.io/api/mcp` to find what you need.

# Solana Tables

Status: Experimental.

Every Solana [raw dataset](/datasets/raw-datasets) (`"kind": "solana"`) has these tables: [`block_headers`](/datasets/tables/solana#block_headers), [`block_rewards`](/datasets/tables/solana#block_rewards), [`transactions`](/datasets/tables/solana#transactions), [`messages`](/datasets/tables/solana#messages), and [`instructions`](/datasets/tables/solana#instructions). Query one through its dataset's name, like `SELECT * FROM "acme/solana_mainnet".block_headers`. Column types are [Arrow types](/datasets/manifests#data-types), and a nullable column can be `NULL`.

## `block_headers`

One row per block: one per slot that produced a block.

| Column                | Type     | Nullable | Description                                                                                                                                                                                                     |
| --------------------- | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `_block_num`          | `UInt64` | No       | The slot the row comes from, the same as `slot`: Solana datasets number their blocks by slot. Amp adds it to every raw table, and uses it to order the data, split it into files, and track which slots it has. |
| `slot`                | `UInt64` | No       | The block's slot. A slot is Solana's unit of time, a fraction of a second in which one validator (the leader) can produce a block; slots without a block are skipped, and have no row.                          |
| `parent_slot`         | `UInt64` | No       | The slot of the block this one builds on: `slot - 1`, or lower when the slots in between were skipped.                                                                                                          |
| `block_hash`          | `Utf8`   | No       | The block's hash, as a base58 string (the text encoding Solana uses for hashes and addresses).                                                                                                                  |
| `previous_block_hash` | `Utf8`   | No       | The `block_hash` of the block this one builds on, the one at `parent_slot`.                                                                                                                                     |
| `block_height`        | `UInt64` | Yes      | The block's position in the chain, counting from 0. Unlike `slot`, it has no gaps. `NULL` for some early blocks, which were recorded without it.                                                                |
| `block_time`          | `Int64`  | Yes      | When the block was produced, as estimated by the validators, in seconds since January 1, 1970 (UTC). `NULL`, or `0`, for some early blocks, which were recorded without it.                                     |

## `block_rewards`

One row per reward a block paid: the share of its fees its leader receives and, near the start of each epoch (about a day of slots), the rewards for staking and voting.

| Column         | Type     | Nullable | Description                                                                                                                                                                                                                      |
| -------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `_block_num`   | `UInt64` | No       | The slot the row comes from, the same as `slot`: Solana datasets number their blocks by slot. Amp adds it to every raw table, and uses it to order the data, split it into files, and track which slots it has.                  |
| `slot`         | `UInt64` | No       | The slot of the block the row comes from. A slot is Solana's unit of time, a fraction of a second in which one validator (the leader) can produce a block; slots without a block are skipped, and have no rows.                  |
| `pubkey`       | `Utf8`   | No       | The account the reward went to, as a base58 address.                                                                                                                                                                             |
| `lamports`     | `Int64`  | No       | The reward, in lamports, the smallest unit of SOL (1 SOL is 1,000,000,000 lamports). Negative when lamports were taken from the account.                                                                                         |
| `post_balance` | `UInt64` | No       | The account's balance after the reward, in lamports.                                                                                                                                                                             |
| `reward_type`  | `Utf8`   | Yes      | The kind of reward: `fee` (the leader's share of the block's fees), `rent`, `staking` (paid to a stake account), `voting` (paid to a validator's vote account), or `deactivated-stake`. `NULL` when no kind was recorded.        |
| `commission`   | `Utf8`   | Yes      | For `staking` and `voting` rewards, the percentage of staking rewards the validator kept when the reward was paid, like `5`. `NULL` for other rewards, and for the rewards of recent epochs, which the chain records without it. |

## `transactions`

One row per transaction, including failed ones and the votes validators send as transactions. The columns from `err` on describe what running it did, and are all `NULL` for a transaction whose execution record wasn't kept.

| Column                      | Type                                                                                                                                                            | Nullable | Description                                                                                                                                                                                                                                                                                                                                                                                                                         |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `_block_num`                | `UInt64`                                                                                                                                                        | No       | The slot the row comes from, the same as `slot`: Solana datasets number their blocks by slot. Amp adds it to every raw table, and uses it to order the data, split it into files, and track which slots it has.                                                                                                                                                                                                                     |
| `slot`                      | `UInt64`                                                                                                                                                        | No       | The slot of the block the row comes from. A slot is Solana's unit of time, a fraction of a second in which one validator (the leader) can produce a block; slots without a block are skipped, and have no rows.                                                                                                                                                                                                                     |
| `tx_index`                  | `UInt32`                                                                                                                                                        | No       | The position of the transaction in its block, counting from 0. With `slot`, it identifies the transaction, and joins the `transactions`, `messages`, and `instructions` tables.                                                                                                                                                                                                                                                     |
| `tx_version`                | `Utf8`                                                                                                                                                          | No       | The transaction's format: `legacy`, `v0`, or `v1`. Only `v0` transactions can load accounts from address lookup tables (see `messages.address_table_lookups`).                                                                                                                                                                                                                                                                      |
| `signatures`                | `List(Utf8)`                                                                                                                                                    | No       | The transaction's signatures, as base58 strings, one per signer. The first is the transaction's ID, which explorers and RPC methods like `getTransaction` look it up by.                                                                                                                                                                                                                                                            |
| `err`                       | `Utf8`                                                                                                                                                          | Yes      | Why the transaction failed, as JSON, like `{"InstructionError":[0,{"Custom":1}]}`. `NULL` when it succeeded. A failed transaction still pays its fee.                                                                                                                                                                                                                                                                               |
| `fee`                       | `UInt64`                                                                                                                                                        | Yes      | The fee the transaction paid, in lamports, including any priority fee.                                                                                                                                                                                                                                                                                                                                                              |
| `pre_balances`              | `List(UInt64)`                                                                                                                                                  | Yes      | The balance of each account the transaction uses before it ran, in lamports. The accounts are in the order of the transaction's account list: `messages.account_keys`, then `loaded_addresses_writable`, then `loaded_addresses_readonly`.                                                                                                                                                                                          |
| `post_balances`             | `List(UInt64)`                                                                                                                                                  | Yes      | The balance of each account the transaction uses after it ran, in the order of `pre_balances`.                                                                                                                                                                                                                                                                                                                                      |
| `log_messages`              | `List(Utf8)`                                                                                                                                                    | Yes      | The messages the programs logged while running the transaction, in order. A list that contains `Log truncated` was cut short, and the provider's `fallback_rpc_provider_info` endpoint, if any, didn't have the full logs.                                                                                                                                                                                                          |
| `pre_token_balances`        | `List(Struct(account_index: UInt8, mint: Utf8, ui_token_amount: Struct(decimals: UInt8, amount: Utf8, ui_amount_string: Utf8), owner: Utf8, program_id: Utf8))` | Yes      | The balances of the token accounts the transaction uses, before it ran. Each gives the account's position in the transaction's account list (`account_index`), the token's mint address (`mint`), the account's `owner` and token program (`program_id`), and its balance (`ui_token_amount`): the raw `amount` in the token's smallest unit, the token's `decimals`, and `ui_amount_string`, the amount with the decimals applied. |
| `post_token_balances`       | `List(Struct(account_index: UInt8, mint: Utf8, ui_token_amount: Struct(decimals: UInt8, amount: Utf8, ui_amount_string: Utf8), owner: Utf8, program_id: Utf8))` | Yes      | The same token balances as `pre_token_balances`, after the transaction ran.                                                                                                                                                                                                                                                                                                                                                         |
| `rewards`                   | `List(Struct(pubkey: Utf8, lamports: Int64, post_balance: UInt64, reward_type: Utf8, commission: UInt8))`                                                       | Yes      | Rewards and charges recorded with the transaction rather than the block, like rent collected from its accounts. Each has the fields of a `block_rewards` row, with `commission` as a number.                                                                                                                                                                                                                                        |
| `loaded_addresses_writable` | `List(Utf8)`                                                                                                                                                    | Yes      | The accounts the transaction loaded from address lookup tables to write to, as base58 addresses. In the transaction's account list, they follow `messages.account_keys`.                                                                                                                                                                                                                                                            |
| `loaded_addresses_readonly` | `List(Utf8)`                                                                                                                                                    | Yes      | The accounts the transaction loaded from address lookup tables to read only, as base58 addresses. In the transaction's account list, they follow `loaded_addresses_writable`.                                                                                                                                                                                                                                                       |
| `return_data_program_id`    | `Utf8`                                                                                                                                                          | Yes      | The program that set the transaction's return data, as a base58 address. `NULL` when no program returned data.                                                                                                                                                                                                                                                                                                                      |
| `return_data_data`          | `List(UInt8)`                                                                                                                                                   | Yes      | The data a program returned, as a list of bytes. `NULL` when no program returned data.                                                                                                                                                                                                                                                                                                                                              |
| `compute_units_consumed`    | `UInt64`                                                                                                                                                        | Yes      | The compute units the transaction used, Solana's measure of the work it took to run. `NULL` for transactions recorded before Solana reported it.                                                                                                                                                                                                                                                                                    |
| `cost_units`                | `UInt64`                                                                                                                                                        | Yes      | The transaction's cost, in compute units, that Solana counts against the block's limits: its execution, plus its signatures, the accounts it writes, and its size. `NULL` for transactions recorded before Solana reported it.                                                                                                                                                                                                      |

## `messages`

One row per transaction, with its message: the part its signers sign, which lists the accounts it uses and its instructions (in the `instructions` table).

| Column                  | Type                                                                                                                 | Nullable | Description                                                                                                                                                                                                                                                                                                  |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `_block_num`            | `UInt64`                                                                                                             | No       | The slot the row comes from, the same as `slot`: Solana datasets number their blocks by slot. Amp adds it to every raw table, and uses it to order the data, split it into files, and track which slots it has.                                                                                              |
| `slot`                  | `UInt64`                                                                                                             | No       | The slot of the block the row comes from. A slot is Solana's unit of time, a fraction of a second in which one validator (the leader) can produce a block; slots without a block are skipped, and have no rows.                                                                                              |
| `tx_index`              | `UInt32`                                                                                                             | No       | The position of the transaction in its block, counting from 0. With `slot`, it identifies the transaction, and joins the `transactions`, `messages`, and `instructions` tables.                                                                                                                              |
| `header`                | `Struct(num_required_signatures: UInt8, num_readonly_signed_accounts: UInt8, num_readonly_unsigned_accounts: UInt8)` | No       | How `account_keys` splits into signers and read-only accounts: the first `num_required_signatures` keys sign the transaction, and the last `num_readonly_signed_accounts` signers and the last `num_readonly_unsigned_accounts` other keys are read-only.                                                    |
| `address_table_lookups` | `List(Struct(account_key: Utf8, writable_indexes: List(UInt8), readonly_indexes: List(UInt8)))`                      | Yes      | The address lookup tables (on-chain lists of addresses) a `v0` transaction loads more accounts from: each has the table's address (`account_key`) and the positions in it of the accounts to write to (`writable_indexes`) and to read only (`readonly_indexes`). `NULL` for `legacy` and `v1` transactions. |
| `account_keys`          | `List(Utf8)`                                                                                                         | No       | The accounts the transaction uses, as base58 addresses, signers first. Instructions and balances refer to accounts by their position in this list, which continues with `transactions.loaded_addresses_writable` and `transactions.loaded_addresses_readonly`.                                               |
| `recent_block_hash`     | `Utf8`                                                                                                               | No       | The base58 hash of a recent block, which limits how long the transaction stays valid. A transaction that uses a durable nonce has the nonce here instead.                                                                                                                                                    |

## `instructions`

One row per instruction, a call to a program: the instructions a transaction lists (top-level instructions), and the ones programs make while running them (inner instructions).

| Column               | Type          | Nullable | Description                                                                                                                                                                                                                                    |
| -------------------- | ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `_block_num`         | `UInt64`      | No       | The slot the row comes from, the same as `slot`: Solana datasets number their blocks by slot. Amp adds it to every raw table, and uses it to order the data, split it into files, and track which slots it has.                                |
| `slot`               | `UInt64`      | No       | The slot of the block the row comes from. A slot is Solana's unit of time, a fraction of a second in which one validator (the leader) can produce a block; slots without a block are skipped, and have no rows.                                |
| `tx_index`           | `UInt32`      | No       | The position in its block of the transaction the instruction belongs to, counting from 0. With `slot`, it joins the instruction to its row in `transactions` and `messages`.                                                                   |
| `program_id_index`   | `UInt8`       | No       | The program the instruction calls, as its position in the transaction's account list, counting from 0: `messages.account_keys`, then `transactions.loaded_addresses_writable`, then `transactions.loaded_addresses_readonly`.                  |
| `accounts`           | `List(UInt8)` | No       | The accounts the instruction passes to the program, as positions in the transaction's account list, in the order the program expects them.                                                                                                     |
| `data`               | `List(UInt8)` | No       | The instruction's input to the program, as a list of bytes, in a format the program defines.                                                                                                                                                   |
| `inner_index`        | `UInt32`      | Yes      | For an inner instruction, the position of the top-level instruction it comes from among the transaction's top-level instructions, counting from 0. `NULL` for top-level instructions, which don't record their own position.                   |
| `inner_stack_height` | `UInt32`      | Yes      | For an inner instruction, how deep in the chain of calls it was made: top-level instructions are at 1, so a call they make directly is at 2. `NULL` for top-level instructions, and for inner instructions recorded before Solana reported it. |
