---
title: "Dados de arquivamento do Solana: como consultar o histórico completo de blocos e transações"
description: "Dados de arquivamento do Solana explicados: por que os nós fazem prune do histórico, quais métodos RPC exigem acesso a dados de arquivamento e como consultar o histórico completo de blocos e transações em escala."
---

# Dados de arquivamento do Solana: como consultar o histórico completo de blocos e transações

<ImageBlock
  src="https://media.alchemy.com/blog/solana-archival-data-hero.png"
  alt="Dados de arquivo do Solana: consultando histórico completo de blocos e transações"
  width={1920}
  height={900}
  priority
/>

Mais cedo ou mais tarde, toda equipe que indexa Solana esbarra na mesma parede. Você pede a um node uma transação de alguns meses atrás e recebe um erro de "block cleaned up", porque o node apagou esse trecho do ledger semanas antes. Um node Solana RPC padrão mantém [aproximadamente os últimos dois dias da chain](https://docs.anza.xyz/implemented-proposals/rpc-transaction-history) e descarta tudo o que é mais antigo para caber no orçamento de disco. Considerando que a Solana produz [mais de quatro petabytes de dados por ano em picos de velocidade](https://www.alchemy.com/blog/zero-downtime-zero-gaps-solana-grpc-streaming), nenhuma máquina isolada seria capaz de guardar tudo isso.

Dados de arquivo (archival data) são como você acessa tudo o que o node descartou. Antes de mais nada, é preciso deixar uma definição clara. Dados de arquivo da Solana são blocos e transações antigos, não estado de conta passado. Se você vem da Ethereum, onde um archive node consegue informar o saldo de qualquer conta em qualquer bloco histórico, essa diferença importa na primeira vez que você desenha um pipeline em torno de um método que não existe aqui. O resto é prático: onde o histórico completo da Solana realmente reside, quais métodos RPC o alcançam, como consultá-los, e como fazer o backfill de um index desde o genesis sem deixar lacunas.

## Por que um node Solana padrão não consegue servir o histórico completo?

Um validator escreve o ledger em um banco de dados local, e os operadores o rodam com a [flag `--limit-ledger-size`](https://docs.anza.xyz/operations/guides/validator-start) para o disco não encher. Com a flag ativada, o node descarta primeiro os dados mais antigos. O valor padrão é 200 milhões de shreds, os pedaços em que a Solana divide os blocos para propagação na rede, o que mantém o ledger abaixo de aproximadamente 500 GB. Sem a flag, o node guarda tudo o que recebe até ficar sem disco, o que, na taxa de dados da Solana, não demora muito.

A Anza, equipe que mantém o [cliente validator Agave](https://docs.anza.xyz/implemented-proposals/rpc-transaction-history), é direta quanto ao motivo. Seis meses de dados de transação não podem, na prática, ser armazenados no ledger local de um validator, de modo que o histórico que um node carrega é "da ordem de dias". Tudo o que é mais antigo precisa viver em outro lugar.

Você pode encontrar o piso de qualquer node chamando [`minimumLedgerSlot`](https://www.alchemy.com/docs/reference/solana-api-quickstart), que retorna o slot mais antigo que ele ainda mantém. Observe por um tempo e o número só sobe, porque o pruning nunca para. Consulte abaixo desse piso e você recebe o erro "block cleaned up" em vez de dados. Um disco maior não muda nada disso. Servir a ponta da chain e servir histórico profundo são problemas de infraestrutura diferentes, e sistemas de arquivo existem porque o segundo problema ultrapassou o que um node consegue fazer.

## O que significa "archival" na Solana, e qual a diferença em relação à Ethereum?

Um [archive node da Ethereum](https://www.alchemy.com/overviews/archive-nodes) mantém cada versão histórica da state trie. Você pode perguntar como estava o storage de um contrato ou o saldo de uma wallet em qualquer bloco passado, e o node responde com dados que guardou exatamente para isso. Equipes que vêm da Ethereum tendem a assumir que a Solana tem um equivalente. Não tem, e essa única suposição arruína mais planos de dados históricos do que qualquer outra coisa.

A Solana sobrescreve o estado de conta no lugar. Quando uma conta muda, a nova versão substitui a antiga, e um [processo de limpeza em background no AccountsDB](https://www.anza.xyz/blog/a-deep-dive-into-solana-s-accountsdb) faz garbage collection das versões substituídas assim que um slot posterior é finalizado. Não sobra nenhum registro do que uma conta tinha três meses atrás. É por isso que a API RPC da Solana não tem um método de "saldo no slot N", e por isso [consultar o estado histórico de contas](https://github.com/solana-labs/solana/issues/18197) permanece aberto como feature request no repositório da Solana há anos.

O que a infraestrutura de arquivo preserva é o próprio ledger, ou seja, blocos e as transações dentro deles. Um archive pode entregar a você o bloco 150.000.000, ou cada transação que já tocou em um endereço. Ele não pode entregar o saldo de USDC de uma wallet em março passado. Essa pergunta ainda pode ser respondida, mas você responde reproduzindo o histórico de transações da wallet por meio de [um indexer](https://www.alchemy.com/overviews/blockchain-indexer), não pedindo a um node um estado que ele nunca guardou.

## Quais métodos RPC precisam de dados de arquivo?

Um método se torna uma leitura archival no momento em que o slot que ele mira cai abaixo do piso local do node. Estes são os que acessam o armazenamento de longo prazo.

<EmbeddedTable
  table={{
    columns: [
      { key: "1", width: 200, title: "Method", dataType: "object" },
      { key: "2", width: 260, title: "What it returns", dataType: "object" },
      { key: "3", width: 300, title: "Limit to know", dataType: "object" },
    ],
    data: [
      {
        "1": {
          title: "<p><strong>getBlock</strong></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title: "<p>Full block and its transactions at a slot</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title: "<p>Only maxSupportedTransactionVersion: 0 is accepted</p>",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        "1": {
          title: "<p><strong>getTransaction</strong></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title: "<p>A confirmed transaction by signature</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title:
            "<p>Rejects processed commitment; returns null if not found</p>",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        "1": {
          title: "<p><strong>getSignaturesForAddress</strong></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title: "<p>Signatures that reference an address, newest first</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title:
            "<p>Limit 1 to 1,000 per call; paginate with before and until</p>",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
      {
        "1": {
          title: "<p><strong>getBlocks</strong></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title: "<p>Confirmed slots in a range</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title: "<p>Range capped at 500,000 slots</p>",
          tooltip: "",
          icon: "",
        },
        id: 3,
      },
      {
        "1": {
          title: "<p><strong>getBlockTime</strong></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title: "<p>Estimated production time of a block</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title: "<p>Returns null if no timestamp was recorded</p>",
          tooltip: "",
          icon: "",
        },
        id: 4,
      },
      {
        "1": {
          title: "<p><strong>getFirstAvailableBlock</strong></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title: "<p>Lowest slot available from storage</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title: "<p>The archive's floor, not the node's</p>",
          tooltip: "",
          icon: "",
        },
        id: 5,
      },
    ],
  }}
/>

A maioria dos pipelines históricos é construída sobre dois desses métodos. Percorra para trás o histórico de um endereço com `getSignaturesForAddress`, depois busque o detalhe de cada transação com `getTransaction`. Como a chamada de assinaturas retorna no máximo [1.000 resultados por chamada](https://www.alchemy.com/docs/reference/solana-api-quickstart), percorrer um endereço movimentado até sua primeira transação significa uma longa cadeia de chamadas paginadas, e quase todas elas, além do slot mínimo do ledger do node, são servidas pelo archive.

É aqui também que um archive fraco fica exposto. Se o armazenamento de longo prazo do provedor tem buracos, alguma chamada bem no meio do seu backfill retorna um erro de "slot skipped" ou "missing in long-term storage", e a menos que você esteja verificando isso, seu index fica incompleto sem que ninguém perceba. Todo provedor expõe os mesmos nomes de método. O que varia é se o armazenamento por trás deles tem lacunas, e quão rápido ele responde quando você está paginando por milhares de chamadas de uma vez.

## Como consultar o histórico completo de blocos e transações?

As consultas em si são JSON-RPC comum. Não existe uma API archival separada nem um parâmetro especial que desbloqueia o histórico. Você chama os mesmos métodos que usaria na ponta da chain, e o archive do provedor responde sempre que o slot cai abaixo do piso local do node.

Buscar um bloco no fundo do histórico se parece com isto:

<CodeSnippet
  language="bash"
  theme="dark"
  code={`curl https://solana-mainnet.g.alchemy.com/v2/YOUR_API_KEY \\
  -X POST \\
  -H "Content-Type: application/json" \\
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getBlock",
    "params": [150000000, {
      "maxSupportedTransactionVersion": 0,
      "transactionDetails": "full",
      "rewards": false
    }]
  }'`}
/>

A resposta traz o bloco inteiro, cada transação nele, e o status e os metadados de cada transação. Mantenha `maxSupportedTransactionVersion: 0` nos parâmetros em toda chamada. Sem isso, a chamada retorna erro em qualquer bloco que contenha transações versionadas, o que na mainnet é a maioria delas.

Percorrer o histórico completo de um endereço é o padrão de dois métodos da tabela acima, executado em loop. Percorra para trás com `getSignaturesForAddress` até ele voltar vazio, depois busque o detalhe de cada transação:

<CodeSnippet
  language="typescript"
  theme="dark"
  code={`import { createSolanaRpc, address, type Signature } from "@solana/kit";
const rpc = createSolanaRpc(
  "https://solana-mainnet.g.alchemy.com/v2/YOUR_API_KEY"
);
const target = address("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4");
let before: Signature | undefined;
const signatures: Signature[] = [];
while (true) {
  const page = await rpc
    .getSignaturesForAddress(target, { before, limit: 1000 })
    .send();
  if (page.length === 0) break;
  signatures.push(...page.map((entry) => entry.signature));
  before = page[page.length - 1].signature;
}
// Resolve each signature to full transaction detail
const tx = await rpc
  .getTransaction(signatures[0], {
    maxSupportedTransactionVersion: 0,
    encoding: "jsonParsed",
  })
  .send();`}
/>

Para uma única wallet, esse loop é tudo o que você precisa, e roda tranquilamente em um laptop. Ele deixa de ser suficiente quando o endereço é um programa movimentado com milhões de assinaturas, ou quando você precisa do histórico de todo endereço na chain. Esse é o problema de backfill, e as seções abaixo cobrem de onde vêm os dados e como carregá-los sem lacunas.

## Como o histórico completo da Solana é armazenado na prática?

Nenhum validator mantém o ledger inteiro, então o histórico de longo prazo vive inteiramente fora do node. Dois sistemas cuidam disso na prática.

O mais antigo é o padrão de warehouse. Um node dedicado envia continuamente blocos finalizados para o [Google Bigtable](https://docs.anza.xyz/operations/setup-an-rpc-node), e quando um node RPC recebe uma consulta para um slot que já não mantém, ele recorre a esse repositório. Slots recentes vêm do banco de dados local do node e tudo o que é mais antigo vem do Bigtable. A maior parte do RPC Solana em produção serve histórico profundo dessa forma há anos. O custo é a concentração, já que todo o passado da chain acaba dentro de um banco de dados proprietário de nuvem.

O mais novo é o [Old Faithful](https://old-faithful.net/), o archive open-source liderado pela Triton e pelo projeto Yellowstone. Ele empacota cada bloco desde o genesis em arquivos CAR endereçados por conteúdo, distribui-os entre IPFS, Filecoin e armazenamento compatível com S3, e os serve via Solana JSON-RPC e gRPC padrão. O projeto existe para que o histórico completo da Solana não dependa do banco de dados de uma única empresa, e equipes que precisam de cobertura verificável desde o genesis o tratam como o archive de referência.

Seja qual for o backend por trás do seu provedor, o que vale internalizar é que o archive é um sistema separado do node. Profundidade e completude são propriedades desse sistema, e vale a pena perguntar sobre elas diretamente em vez de presumir.

## Como obter histórico de conta e de token em escala?

Equipes que querem "histórico da Solana em escala" raramente querem blocos brutos. Elas querem o saldo de uma wallet ao longo do tempo, cada transferência que um endereço já fez, ou o histórico completo de holders de um token, servido rápido o suficiente para alimentar um dashboard ou uma exportação fiscal. Nada disso existe no ledger em forma consultável. Precisa ser derivado.

A receita muda pouco entre projetos. Puxe o histórico completo de transações de um endereço via RPC archival, reproduza essas transações em ordem, e compute o estado que interessa ao longo do caminho: saldos após cada transação, mudanças de propriedade, fluxos de transferência. Grave os resultados no seu próprio banco de dados para que o replay caro aconteça uma vez, em vez de a cada requisição. Em qualquer chain, esse é o trabalho de um indexer de blockchain. Na Solana é a única forma de chegar a estado histórico, porque o node não guarda nenhum.

Para a versão mais afiada da pergunta, o que uma wallet tinha em um slot específico, agora entregamos uma resposta direta. O [`getTokenAccountsByOwnerAtSlot`](https://www.alchemy.com/docs/chains/solana/solana-api-endpoints/get-token-accounts-by-owner-at-slot) mantém a sintaxe do `getTokenAccountsByOwner` padrão e adiciona um parâmetro `slot`, retornando os saldos exatos de token da wallet naquele ponto do histórico em uma única chamada. Ele é sustentado por um index histórico mantido continuamente em vez de replay, então, para holdings em um ponto no tempo, todo o pipeline de reconstrução acima desaparece. O [post de lançamento dos saldos históricos de token da Solana](https://www.alchemy.com/blog/historical-solana-token-balances) explica a mecânica.

Para as outras formas derivadas comuns, saldos ao longo do tempo, transferências e metadados de token, as [Data APIs](https://www.alchemy.com/docs/data) as servem pré-computadas e você pode pular o projeto de indexação. Construa seu próprio indexer quando precisar de dados derivados personalizados ou controle total do pipeline. Use os métodos gerenciados quando as formas padrão atenderem. O que não funciona é pedir a um node comum o estado passado de uma conta, porque o node nunca o guardou. Toda resposta que funciona vem de um index construído sobre o histórico.

## Como fazer o backfill de um index desde o genesis sem travar?

A parte difícil de um pipeline histórico é o cold start. Seu index está vazio, centenas de milhões de slots precisam ser carregados, e a chain continua produzindo novos blocos o tempo todo em que você está carregando os antigos. Se o backfill e o feed ao vivo não se encontrarem de forma limpa, abre-se uma lacuna entre onde um terminou e o outro começou.

Muitas equipes começam fazendo polling do RPC archival para todo o backfill, e em escala de genesis isso dói: rate limits, custo por requisição em centenas de milhões de slots, e nenhuma forma limpa de provar que nada foi perdido. O padrão que sobrevive ao contato com produção usa uma fonte diferente para cada fase. O histórico em massa vem direto de um archive, e ferramentas como o [Jetstreamer](https://github.com/anza-xyz/jetstreamer) o transmitem diretamente do Old Faithful. A ponta da chain vem de um stream ao vivo em vez de mais polling.

Para a metade ao vivo, um [stream Solana gRPC](https://www.alchemy.com/solana-grpc) compatível com Yellowstone envia novas transações e atualizações de conta para o seu indexer conforme acontecem, filtradas por conta, programa ou assinatura. A costura entre o backfill e o stream é onde os pipelines costumam vazar, e o replay é o que a sela. [Nosso gRPC](https://www.alchemy.com/blog/introducing-alchemy-solana-grpc) permite que um cliente reconecte com um parâmetro `from_slot` e receba novamente os slots que perdeu enquanto estava fora, de modo que uma conexão caída não deixe um buraco nos seus dados. Também construímos a [camada de streaming para atravessar failovers](https://www.alchemy.com/blog/zero-downtime-zero-gaps-solana-grpc-streaming) sem perder mensagens, trabalho que de outra forma vira um serviço separado de detecção de lacunas rodando ao lado do seu indexer. Assim que o archive cobre o passado e o stream cobre a ponta, o replay mantém os dois costurados.

## O que procurar em um provedor archival da Solana?

Profundidade é a primeira coisa a definir com precisão, e vale perguntar a qualquer provedor exatamente nestes termos: vocês indexam desde o genesis, ou a partir de uma altura mais recente em diante? "Dados históricos completos" com um piso não declarado é comum, e você geralmente descobre esse piso quando seu backfill morre nele.

O resto do checklist decorre de como um backfill realmente roda. Completude importa porque uma única lacuna corrompe o index construído sobre ela. Velocidade importa porque percorrer o histórico completo de assinaturas são milhares de leituras sequenciais no archive, então a latência por chamada se multiplica em horas ou dias de tempo real. JSON-RPC padrão importa porque um endpoint histórico proprietário prende seu pipeline a um único fornecedor, enquanto RPC comum não exige nenhuma reescrita. E preço importa porque o histórico profundo é, por natureza, intensivo em leitura.

Construímos nosso acesso archival em cima desse checklist. Ele cobre [histórico completo de blocos e transações desde o genesis](https://www.alchemy.com/docs/reference/solana-api-quickstart) via JSON-RPC padrão, e [nossos benchmarks](https://www.alchemy.com/blog/solana-infrastructure) mediram o `getTransaction` histórico rodando até 20x mais rápido que outros provedores, junto com `getBlock` até 3x mais rápido e até 10x mais rápido em chamadas pesadas como `getProgramAccounts`, sem mudanças de código nem métodos proprietários envolvidos. O [relato de engenharia sobre como construímos os métodos archival mais rápidos da Solana](https://www.alchemy.com/blog/how-alchemy-built-the-fastest-archival-methods-on-solana) cobre a arquitetura por trás desses números. Para uma comparação completa lado a lado de profundidade, uptime, preço e ferramentas, o [guia de decisão dos nove melhores provedores de Solana RPC](https://www.alchemy.com/overviews/solana-rpc) cobre todo o campo. Seja qual for o escolhido, obtenha as respostas sobre profundidade desde o genesis e completude por escrito antes de começar o backfill.

## Construa seu pipeline histórico da Solana na Alchemy

Um pipeline histórico funcional precisa de duas coisas: um archive profundo o suficiente para fazer backfill desde o genesis e um stream rápido o suficiente para acompanhar a ponta. Nós rodamos os dois como parte da [plataforma Solana da Alchemy](https://www.alchemy.com/solana). As leituras archival cobrem histórico completo de blocos e transações via JSON-RPC padrão, então apontar seu cliente Solana existente para um endpoint da Alchemy é toda a migração. O [streaming Solana gRPC](https://www.alchemy.com/solana-grpc) é compatível com Yellowstone, com replay na reconexão, precificado pay-as-you-go a $75 por TB, sem mínimo mensal e sem pré-requisito de plano.

Comece no tier gratuito, sem contrato e sem call de vendas. Equipes construindo infraestrutura Solana também podem se candidatar a até $25.000 em créditos através do nosso [$20M Solana Fund](https://www.alchemy.com/solana-20m-fund). Assim que seu pipeline estiver no ar, o histórico que seu node descarta deixa de ser problema seu.
