# Consultar o estado histórico da EVM dentro das janelas suportadas

> Source: https://docs.blockvectra.com/pt-br/guides/evm-historical-state/

Chamadas históricas de `eth_call` dependem da janela de estado da rede, e não do limite de intervalo de blocos de `eth_getLogs`. Verifique a janela de estado, o modo de autenticação do endpoint e o bloco de destino antes de ler o valor anterior de um contrato.

## Três limites históricos diferentes

| Campo em [GET /v1/chains](https://api.blockvectra.com/v1/chains) | O que controla                                                                                                                                 | O que verificar                                                                                                                                       |
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `state_window_blocks`                                            | Até que ponto no passado leituras de estado autenticadas como `eth_call`, `eth_getBalance`, `eth_getCode` e `eth_getStorageAt` podem consultar | Com o topo `H` e a janela declarada `W`, um bloco numerado anterior a `H − W` está fora da janela. Verifique também `methods.allow` e `methods.deny`. |
| `public.history_blocks`                                          | Referências a blocos históricos por meio da `public.url` sem chave                                                                             | Use apenas `public.methods`. Para leituras de estado, aplica-se o menor valor entre o histórico público e a janela de estado declarada.               |
| `max_logs_block_range`                                           | O número de blocos em uma única requisição autenticada de `eth_getLogs`                                                                        | Conte `toBlock − fromBlock + 1`. Um intervalo permitido não estabelece que o estado antigo do contrato ou os logs estejam disponíveis.                |

Esses limites são em blocos, não em dias. Uma janela de estado `null` ou não declarada não estabelece cobertura de arquivamento. A disponibilidade de métodos sem chave é separada da disponibilidade de métodos autenticados: um intervalo de logs por si só não habilita o `eth_getLogs` público.

## Comparar janelas de estado por rede

A tabela mostra as janelas de estado publicadas, o histórico sem chave, os intervalos de logs e os conjuntos de dados declarados da Data API a partir do snapshot público. Para uma requisição agora, consulte [GET /v1/chains](https://api.blockvectra.com/v1/chains) e [GET /v1/status](https://api.blockvectra.com/v1/status) novamente.

Desenvolvedores e agentes de IA devem verificar janelas de estado e intervalos de consulta de logs separadamente. Uma janela de estado nula não estabelece cobertura de arquivo. O histórico público aplica-se apenas aos métodos públicos declarados.

| Rede | Slug da rede | Janela de estado autenticada: state_window_blocks (blocos) | Histórico sem chave: public.history_blocks (blocos) | Intervalo de consulta de logs autenticado: max_logs_block_range (blocos) | Conjuntos de dados da Data API declarados |
| --- | --- | --- | --- | --- | --- |
| Arbitrum One | `arb_mainnet` | 6,000 | 1,000 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, freshness |
| Base | `base_mainnet` | 10,000 | 1,000 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, freshness |
| BNB Smart Chain | `bsc_mainnet` | 100 | 100 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, freshness |
| Ethereum | `eth_mainnet` | 250,000 | 1,000 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, freshness |
| Ethereum Sepolia | `eth_sepolia` | Não declarado | 1,000 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, freshness |
| HyperEVM | `hyperevm_mainnet` | Não declarado | 1,000 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, balances, holders, nfts, freshness |
| Polygon | `polygon_mainnet` | 126 | 126 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, freshness |
| Robinhood Chain | `robinhood_mainnet` | 900 | 900 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, balances, holders, nfts, dex_swaps, dex_prices, stocks, traces, freshness |
| Robinhood Chain Testnet | `robinhood_testnet` | 1,023 | 1,000 | 1,000 | Data API indisponível |

[GET /v1/chains](https://api.blockvectra.com/v1/chains) · Amostragem (UTC): 2026-10-09

[GET /v1/status](https://api.blockvectra.com/v1/status) · Amostragem (UTC): 2026-10-09

## Escolher uma tag de bloco

Use `latest` para o valor atual. Para uma comparação histórica, leia `eth_blockNumber` uma vez e converta o número de bloco escolhido em uma quantidade hexadecimal como `0x18efa2f`. Mantenha esse número fixo para todas as chamadas na comparação; chamadas repetidas com `latest` podem usar blocos diferentes.

Para leituras de estado, `earliest`, `safe` e `finalized` retornam `-32011` sob a política de janela de estado. Escolha um número de bloco explícito dentro da janela declarada. O formato de hash de bloco não é uma forma de obter histórico adicional: leituras de estado sem chave o rejeitam, e uma requisição autenticada ainda depende do estado disponível.

Um número de bloco pode se referir a um bloco diferente após uma reorganização. Registre o hash do bloco com `eth_getBlockByNumber` se você precisar identificar o bloco do resultado. Um número dentro da janela também precisa de uma rede sincronizada e de um contrato existente nessa altura.

## Leitura de contrato em bloco fixo

No Ethereum, o WETH em `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` expõe `decimals()` com o seletor `0x313ce567`. Uma chamada sem chave amostrada em 2026-10-08 (UTC) no bloco `0x18efa2f` retornou HTTP 200 com este resultado:

Requisição para a `public.url` da rede:

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "eth_call",
  "params": [
    { "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "data": "0x313ce567" },
    "0x18efa2f"
  ]
}
```

Resposta:

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": "0x0000000000000000000000000000000000000000000000000000000000000012"
}
```

O número inteiro codificado em ABI é 18. O resultado é um valor de decimais, não um saldo, e não estabelece disponibilidade em outras alturas. Esse bloco fixo sairá de uma janela limitada com o tempo; use um bloco recente ao executar o exemplo a seguir posteriormente.

Salve o exemplo como `historical-state.mjs` e execute `node historical-state.mjs` com Node.js 24 ou superior e sua variável de ambiente `BLOCKVECTRA_API_KEY` definida. Ele usa o endpoint autenticado, mantém o mesmo contrato e calldata e compara `latest`, um bloco recente fixo e um bloco fora da janela autenticada publicada. Cada saída inclui o status HTTP real e o corpo JSON-RPC; um HTTP 200 ainda pode conter um erro. Ele é interrompido diante de uma resposta inesperada em vez de tratá-la como uma leitura bem-sucedida.

```js
const key = process.env.BLOCKVECTRA_API_KEY;
if (!key) throw new Error('Set BLOCKVECTRA_API_KEY');
const chainsUrl = 'https://api.blockvectra.com/v1/chains';
const catalogResponse = await fetch(chainsUrl, { signal: AbortSignal.timeout(15_000) });
if (!catalogResponse.ok) throw new Error(`Chains HTTP ${catalogResponse.status}`);
const catalog = await catalogResponse.json();
const chain = catalog.chains.find(item => item.chain === 'eth_mainnet');
const matches = (method, pattern) => pattern.endsWith('*')
  ? method.startsWith(pattern.slice(0, -1)) : method === pattern;
if (!chain?.jsonrpc || !['eth_call', 'eth_blockNumber'].every(method =>
  chain.methods?.allow?.some(pattern => matches(method, pattern)) &&
  !chain.methods?.deny?.some(pattern => matches(method, pattern)))) {
  throw new Error('Required methods are unavailable');
}
const window = chain.state_window_blocks;
if (!Number.isSafeInteger(window) || window < 10) {
  throw new Error('This example needs a declared state window of at least 10 blocks');
}
const rpcUrl = new URL('./eth_mainnet', chainsUrl).href;
let id = 0;
async function rpc(method, params) {
  const response = await fetch(rpcUrl, {
    method: 'POST', redirect: 'error', signal: AbortSignal.timeout(15_000),
    headers: { 'Content-Type': 'application/json', 'x-api-key': key },
    body: JSON.stringify({ jsonrpc: '2.0', id: ++id, method, params }),
  });
  return { http: response.status, body: await response.json() };
}
const headResponse = await rpc('eth_blockNumber', []);
if (headResponse.http !== 200 || headResponse.body.error ||
    !/^0x[0-9a-f]+$/i.test(headResponse.body.result ?? '')) {
  throw new Error(`Cannot read head: ${JSON.stringify(headResponse)}`);
}
const head = BigInt(headResponse.body.result);
if (head <= BigInt(window)) throw new Error('Head is too low for an out-of-window block');
const hex = value => `0x${value.toString(16)}`;
const fixedBlock = hex(head - 10n);
const outsideBlock = hex(head - BigInt(window) - 1n);
const call = { to: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', data: '0x313ce567' };
for (const block of ['latest', fixedBlock, outsideBlock]) {
  const reply = await rpc('eth_call', [call, block]);
  console.log(JSON.stringify({ head: hex(head), block, ...reply }));
  if (block === outsideBlock) {
    if (reply.http !== 200 || reply.body.error?.code !== -32011 ||
        reply.body.error?.data?.reason !== 'state_window') {
      throw new Error('Expected state_window; inspect the actual response above');
    }
  } else if (reply.http !== 200 || reply.body.error ||
      reply.body.result !== '0x0000000000000000000000000000000000000000000000000000000000000012') {
    throw new Error('Expected the WETH decimals result; inspect the actual response above');
  }
}
```

A resposta registrada acima usa `public.url`; o script usa uma API key. Para fazer uma leitura sem chave, obtenha a URL diretamente de `public.url`, omita a chave e escolha um bloco dentro de `public.history_blocks` bem como da janela de estado. Alterar a autenticação pode alterar o histórico permitido, mesmo para o mesmo contrato e calldata.

## Diagnosticar um erro fora da janela

No mesmo endpoint sem chave, uma chamada amostrada em 2026-10-08 (UTC) alterando apenas o bloco de destino para `0x18ef650` (e o ID da requisição) retornou HTTP 200 com `error.code: -32011`, `error.data.reason: state_window` e `error.data.retryable: false`. Sua mensagem foi `block reference is outside the public history window`. Essa é uma falha de histórico público; o endpoint autenticado possui sua própria janela de estado.

Use estes campos da [entrada de erro state\_window](https://docs.blockvectra.com/en/errors/#state_window) para identificar a falha em vez de confiar em um número de janela específico na mensagem:

| Campo                  | Valor documentado ou significado                                                                                                                           |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Status HTTP            | `200`; inspecione o `error` JSON-RPC mesmo quando o HTTP for bem-sucedido                                                                                  |
| `error.code`           | `-32011`                                                                                                                                                   |
| `error.message`        | Erros de janela de estado autenticada descrevem a contagem de blocos suportados mais recente; erros de histórico público podem usar uma mensagem diferente |
| `error.data.reason`    | `state_window`                                                                                                                                             |
| `error.data.docs_url`  | Link para a explicação de `state_window` no catálogo de erros                                                                                              |
| `error.data.retryable` | `false`: enviar a mesma requisição mais tarde não restaura o estado mais antigo                                                                            |

Escolha um bloco numerado mais recente ou use `latest` se a tarefa precisar do valor atual. Reduzir um intervalo de `eth_getLogs` não recupera o estado histórico de `eth_call`. Outros motivos para `-32011` têm ações diferentes: [range\_not\_indexed](https://docs.blockvectra.com/en/errors/#range_not_indexed) exige um intervalo coberto; [history\_not\_ready](https://docs.blockvectra.com/en/errors/#history_not_ready) permite nova tentativa após a indexação alcançar a rede. Inspecione `error.data.reason`, e não apenas o código numérico.

O estado subjacente também pode estar indisponível com `-32000`, ou o histórico de blocos podado com `4444`; consulte o [catálogo de erros](https://docs.blockvectra.com/en/errors/). Não tente novamente um bloco antigo sem alteração nem presuma que uma janela declarada maior garanta todas as respostas.

## Escolher a próxima consulta

Para uma lista completa de verificação de carga de trabalho e autotestes, comece com [Como escolher um provedor RPC](https://docs.blockvectra.com/en/guides/choose-rpc-provider/).

Ao escolher um provedor para leituras repetidas de contratos, [compare orçamentos diários e de ciclo para leituras EVM](https://docs.blockvectra.com/en/guides/infura-alternative/). Verifique primeiro os blocos históricos necessários e, em seguida, planeje a distribuição diária e a taxa de transferência da tarefa; encaixar-se em um orçamento de créditos não estabelece cobertura de estado.

Ao comparar provedores para leituras históricas, primeiro confirme que ambos podem atender ao bloco de destino. A [comparação de excedente em requisições full](https://docs.blockvectra.com/en/guides/chainstack-alternative/) compara preços de RU adicionais com custos baseados em métodos, separa a cota incluída do uso excedente e explica as classes de cobrança full versus archive.

Para blocos indexados anteriores, transações, transferências ou outros conjuntos de dados, consulte os conjuntos de dados declarados da Data API na tabela e a [referência da Data API](https://docs.blockvectra.com/en/api/data/). Registros indexados não oferecem execução histórica arbitrária de contratos nem implicam que todas as redes tenham saldos históricos.

* [Referência do método eth\_call](https://docs.blockvectra.com/en/api/json-rpc/methods/eth_call/) para parâmetros de chamada e codificação de retorno.
* [Intervalo de blocos do eth\_getLogs e consultas em partes](https://docs.blockvectra.com/en/guides/getlogs-block-range/) para histórico de logs de eventos.
* [Configuração de RPC personalizado na carteira](https://docs.blockvectra.com/en/guides/wallet-custom-rpc/) para conexões de carteira e chaves dedicadas.
* [Redes compatíveis](https://docs.blockvectra.com/en/chains/) para disponibilidade de rede e [precificação de CU](https://docs.blockvectra.com/en/guides/reading-cu-pricing/) para custos de métodos.
