Consultar o estado histórico da EVM dentro das janelas suportadas
Distinga janelas de estado autenticadas, histórico sem chave e intervalos de logs. Escolha um bloco fixo para eth_call e diagnostique erros de state_window.
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 | 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 e GET /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 · Amostragem (UTC):
GET /v1/status · Amostragem (UTC):
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:
{
"jsonrpc": "2.0",
"id": 2,
"method": "eth_call",
"params": [
{ "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "data": "0x313ce567" },
"0x18efa2f"
]
}Resposta:
{
"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.
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 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 exige um intervalo coberto; 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. 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.
Ao escolher um provedor para leituras repetidas de contratos, compare orçamentos diários e de ciclo para leituras EVM. 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 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. 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 para parâmetros de chamada e codificação de retorno.
- Intervalo de blocos do eth_getLogs e consultas em partes para histórico de logs de eventos.
- Configuração de RPC personalizado na carteira para conexões de carteira e chaves dedicadas.
- Redes compatíveis para disponibilidade de rede e precificação de CU para custos de métodos.
Última atualização:
Preços diários de DEX
Consulte preços diários de OHLC e VWAP de DEX na Data API, manipule frações racionais exatas em TypeScript e Python e faça o backfill de dados históricos com eficiência.
Plano gratuito
Entenda o que o plano gratuito cobre com base em pesos reais de métodos, com cálculos baseados em tarefas e caminhos de atualização.