Consultar el estado histórico EVM dentro de las ventanas compatibles
Distinga las ventanas de estado autenticadas, el historial sin clave y la amplitud de logs. Elija un bloque fijo para eth_call y diagnostique errores state_window.
El eth_call histórico depende de la ventana de estado de la cadena, no de su límite de rango de bloques de eth_getLogs. Compruebe la ventana de estado, el modo de autenticación del endpoint y el bloque de destino antes de leer un valor de contrato anterior.
Tres límites históricos diferentes
| Campo de GET /v1/chains | Qué controla | Qué comprobar |
|---|---|---|
state_window_blocks | Hasta dónde pueden retroceder las lecturas de estado autenticadas como eth_call, eth_getBalance, eth_getCode y eth_getStorageAt | Con una cabecera H y una ventana declarada W, un bloque numerado anterior a H − W está fuera de la ventana. Compruebe también methods.allow y methods.deny. |
public.history_blocks | Referencias históricas de bloques mediante la public.url sin clave | Utilice solo public.methods. Para lecturas de estado, se aplica el menor entre el historial público y la ventana de estado declarada. |
max_logs_block_range | El número de bloques de una solicitud eth_getLogs autenticada | Cuente toBlock − fromBlock + 1. Una amplitud permitida no demuestra que estén disponibles el estado antiguo de contratos ni los logs antiguos. |
Estos límites se expresan en bloques, no en días. Una ventana de estado null o no declarada no demuestra cobertura de archivo. La disponibilidad de métodos sin clave es independiente de la disponibilidad de métodos autenticados: una amplitud de logs por sí sola no habilita eth_getLogs público.
Comparar ventanas de estado por cadena
La tabla muestra las ventanas de estado publicadas, el historial sin clave, las amplitudes de logs y los conjuntos de datos de Data API declarados en la instantánea pública. Para una solicitud actual, vuelva a leer GET /v1/chains y GET /v1/status.
Los desarrolladores y agentes de IA deben verificar las ventanas de estado y los rangos de consulta de logs por separado. Una ventana de estado nula no establece cobertura de archivo histórico. El historial público se aplica únicamente a los métodos públicos declarados.
| Cadena | Slug de la cadena | Ventana de estado autenticada: state_window_blocks (bloques) | Historial sin clave: public.history_blocks (bloques) | Rango de consulta de logs autenticado: max_logs_block_range (bloques) | Conjuntos de datos de 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 | No declarado | 1,000 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, freshness |
| HyperEVM | hyperevm_mainnet | No 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 no disponible |
GET /v1/chains · Muestreado (UTC):
GET /v1/status · Muestreado (UTC):
Elegir una etiqueta de bloque
Utilice latest para el valor actual. Para una comparación histórica, lea eth_blockNumber una vez y convierta un número de bloque elegido a una cantidad hexadecimal como 0x18efa2f. Mantenga ese número fijo en cada llamada de la comparación; las llamadas repetidas a latest pueden utilizar bloques diferentes.
Para lecturas de estado, earliest, safe y finalized devuelven -32011 según la política de ventana de estado. Elija en su lugar un número de bloque explícito dentro de la ventana declarada. La forma con hash de bloque no permite obtener historial adicional: las lecturas de estado sin clave la rechazan, y una solicitud autenticada sigue dependiendo del estado disponible.
Un número de bloque puede referirse a un bloque diferente tras una reorganización. Registre el hash del bloque con eth_getBlockByNumber si necesita identificar el bloque del resultado. Un número dentro de la ventana también requiere una cadena sincronizada y un contrato existente a esa altura.
Leer un contrato en un bloque fijo
En Ethereum, WETH en 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 ofrece decimals() con el selector 0x313ce567. Una llamada sin clave muestreada el 2026-10-08 (UTC) en el bloque 0x18efa2f devolvió HTTP 200 con este resultado:
Solicitud a la public.url de la cadena:
{
"jsonrpc": "2.0",
"id": 2,
"method": "eth_call",
"params": [
{ "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "data": "0x313ce567" },
"0x18efa2f"
]
}Respuesta:
{
"jsonrpc": "2.0",
"id": 2,
"result": "0x0000000000000000000000000000000000000000000000000000000000000012"
}El entero codificado mediante ABI es 18. El resultado es un valor de decimales, no un saldo, y no demuestra disponibilidad en otras alturas. Ese bloque fijo acabará quedando fuera de una ventana acotada; utilice un bloque reciente cuando ejecute más adelante el ejemplo siguiente.
Guarde el ejemplo como historical-state.mjs y ejecute node historical-state.mjs con Node.js 24 o posterior y su variable de entorno BLOCKVECTRA_API_KEY establecida. Utiliza el endpoint autenticado, mantiene el mismo contrato y calldata, y compara latest, un bloque fijo reciente y un bloque fuera de la ventana autenticada publicada. Cada salida incluye el estado HTTP real y el body JSON-RPC; un HTTP 200 aún puede contener un error. Se detiene ante una respuesta inesperada en lugar de tratarla como una lectura exitosa.
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');
}
}La respuesta registrada arriba utiliza public.url; el script utiliza una API key. Para una lectura sin clave, tome la URL directamente de public.url, omita la clave y elija un bloque dentro de public.history_blocks y de la ventana de estado. Cambiar la autenticación puede cambiar el historial permitido, incluso para el mismo contrato y calldata.
Diagnosticar un error fuera de la ventana
En el mismo endpoint sin clave, una llamada muestreada el 2026-10-08 (UTC) que cambió únicamente el bloque de destino a 0x18ef650 (y el ID de solicitud) devolvió HTTP 200 con error.code: -32011, error.data.reason: state_window y error.data.retryable: false. Su mensaje fue block reference is outside the public history window. Es un fallo de historial público; el endpoint autenticado tiene su propia ventana de estado.
Utilice estos campos de la entrada de error state_window para reconocer el fallo en lugar de depender de un número de ventana concreto del mensaje:
| Campo | Valor o significado documentado |
|---|---|
| Estado HTTP | 200; revise el error JSON-RPC incluso cuando HTTP sea exitoso |
error.code | -32011 |
error.message | Los errores de ventana de estado autenticada describen el número de bloques más recientes compatibles; los errores de historial público pueden utilizar otro mensaje |
error.data.reason | state_window |
error.data.docs_url | Enlace a la explicación de state_window en el catálogo de errores |
error.data.retryable | false: enviar la misma solicitud más adelante no restaura el estado antiguo |
Elija un bloque numerado más reciente o utilice latest si la tarea necesita el valor actual. Reducir la amplitud de eth_getLogs no recupera el estado histórico de eth_call. Otros motivos de -32011 requieren acciones diferentes: range_not_indexed requiere un rango cubierto; history_not_ready permite reintentar cuando la indexación se pone al día. Revise error.data.reason, no solo el código numérico.
El estado subyacente también puede no estar disponible con -32000, o el historial de bloques puede haberse podado con 4444; consulte el catálogo de errores. No reintente un bloque antiguo sin cambios ni suponga que una ventana declarada mayor garantiza todas las respuestas.
Elegir la siguiente consulta
Para obtener una lista completa de comprobaciones de carga de trabajo y pruebas propias, comience con Cómo elegir un proveedor RPC.
Al elegir un proveedor para lecturas repetidas de contratos, compare los presupuestos diarios y de ciclo para lecturas EVM. Compruebe primero los bloques históricos necesarios y después planifique la distribución diaria y la capacidad de procesamiento de la tarea; ajustarse a un presupuesto de créditos no demuestra cobertura de estado.
Al comparar proveedores para lecturas históricas, confirme primero que ambos puedan servir el bloque de destino. La comparación de uso adicional de solicitudes full compara los precios de RU adicionales con los costes por método, distingue la cuota incluida del uso adicional y explica las clases de facturación full y archive.
Para bloques, transacciones, transferencias u otros conjuntos de datos indexados anteriores, compruebe los conjuntos de datos de Data API declarados en la tabla y la referencia de Data API. Los registros indexados no proporcionan ejecución histórica arbitraria de contratos ni implican que todas las cadenas tengan saldos históricos.
- Referencia del método eth_call para los parámetros de llamada y la codificación de retorno.
- Rango de bloques de eth_getLogs y consultas por tramos para el historial de logs de eventos.
- Configuración de RPC personalizado de billeteras para conexiones de billeteras y claves dedicadas.
- Cadenas compatibles para la disponibilidad de redes y precios CU para los costes de métodos.
Última actualización:
Elegir un proveedor RPC
Evalúe costes de métodos RPC, rangos de logs, créditos gratuitos, límites de tasa, cobertura de cadenas, APIs de Push y datos, autenticación y acceso de agentes mediante pruebas de su carga de trabajo.
Rango de bloques de eth_getLogs
Gestione el límite de rango de bloques de eth_getLogs y el error logs_range_too_large: consulte el max_logs_block_range de cada cadena y divida consultas amplias en fragmentos.