Historischen EVM-State innerhalb unterstützter Fenster abfragen
Unterscheiden Sie authentifizierte State-Fenster, schlüssellosen Verlauf und Log-Spannen. Wählen Sie einen festen Block für eth_call und diagnostizieren Sie state_window-Fehler.
Historische eth_call-Aufrufe hängen vom State-Fenster der Chain ab, nicht von ihrem eth_getLogs-Blockbereichslimit. Prüfen Sie das State-Fenster, den Authentifizierungsmodus des Endpunkts und den Zielblock, bevor Sie einen früheren Contract-Wert auslesen.
Drei verschiedene historische Limits
| Feld in GET /v1/chains | Was es steuert | Was zu prüfen ist |
|---|---|---|
state_window_blocks | Wie weit authentifizierte State-Leseoperationen wie eth_call, eth_getBalance, eth_getCode und eth_getStorageAt zurückreichen können | Bei Chain-Head H und deklariertem Fenster W liegt ein nummerierter Block, der älter als H − W ist, außerhalb des Fensters. Prüfen Sie auch methods.allow und methods.deny. |
public.history_blocks | Historische Blockreferenzen über die schlüssellose public.url | Nutzen Sie nur public.methods. Bei State-Leseoperationen gilt das kleinere aus öffentlichem Verlauf und deklariertem State-Fenster. |
max_logs_block_range | Die Anzahl der Blöcke in einer authentifizierten eth_getLogs-Anfrage | Zählen Sie toBlock − fromBlock + 1. Eine zulässige Spanne belegt nicht, dass alter Contract-State oder alte Logs verfügbar sind. |
Diese Limits werden in Blöcken angegeben, nicht in Tagen. Ein null oder nicht deklariertes State-Fenster belegt keine Archiv-Abdeckung. Die schlüssellose Methodenverfügbarkeit ist von der authentifizierten Methodenverfügbarkeit getrennt: Eine Log-Spanne allein aktiviert kein öffentliches eth_getLogs.
State-Fenster pro Chain vergleichen
Die Tabelle zeigt veröffentlichte State-Fenster, den schlüssellosen Verlauf, Log-Spannen und deklarierte Data-API-Datensätze aus dem öffentlichen Snapshot. Für eine aktuelle Anfrage lesen Sie GET /v1/chains und GET /v1/status erneut aus.
Entwickler und KI-Agenten sollten Zustandsfenster und Log-Abfragespannen separat prüfen. Ein Null-Zustandsfenster garantiert keine Archiv-Abdeckung. Der öffentliche Verlauf gilt nur für die deklarierten öffentlichen Methoden.
| Chain | Chain-Slug | Authentifiziertes Zustandsfenster: state_window_blocks (Blöcke) | Schlüsselloser Verlauf: public.history_blocks (Blöcke) | Authentifizierte Log-Abfragespanne: max_logs_block_range (Blöcke) | Deklarierte Data-API-Datensätze |
|---|---|---|---|---|---|
| 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 | Nicht deklariert | 1,000 | 1,000 | blocks, transactions, address_transactions, transfers, token_metadata, freshness |
| HyperEVM | hyperevm_mainnet | Nicht deklariert | 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 nicht verfügbar |
GET /v1/chains · Stichprobe (UTC):
GET /v1/status · Stichprobe (UTC):
Block-Tag auswählen
Verwenden Sie latest für den aktuellen Wert. Für einen historischen Vergleich lesen Sie eth_blockNumber einmal aus und wandeln Sie eine gewählte Blocknummer in eine hexadezimale Größe wie 0x18efa2f um. Halten Sie diese Nummer für jeden Aufruf im Vergleich fest; wiederholte latest-Aufrufe können unterschiedliche Blöcke verwenden.
Bei State-Leseoperationen geben earliest, safe und finalized unter der State-Window-Richtlinie -32011 zurück. Wählen Sie stattdessen eine explizite Blocknummer innerhalb des deklarierten Fensters. Ein Block-Hash-Format ist kein Weg, um zusätzlichen Verlauf zu erhalten: Schlüssellose State-Leseoperationen weisen ihn ab, und eine authentifizierte Anfrage hängt weiterhin vom verfügbaren State ab.
Eine Blocknummer kann sich nach einer Reorganisation auf einen anderen Block beziehen. Erfassen Sie den Block-Hash mit eth_getBlockByNumber, wenn Sie den Block des Ergebnisses eindeutig identifizieren müssen. Eine Nummer innerhalb des Fensters setzt zudem eine synchronisierte Chain und einen existierenden Contract auf dieser Höhe voraus.
Contract-Leseoperation bei festem Block
Auf Ethereum stellt WETH unter 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 die Methode decimals() mit dem Selektor 0x313ce567 bereit. Ein schlüsselloser Aufruf, der am 2026-10-08 (UTC) bei Block 0x18efa2f als Stichprobe ausgeführt wurde, gab HTTP 200 mit diesem Ergebnis zurück:
Anfrage an die public.url der Chain:
{
"jsonrpc": "2.0",
"id": 2,
"method": "eth_call",
"params": [
{ "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "data": "0x313ce567" },
"0x18efa2f"
]
}Antwort:
{
"jsonrpc": "2.0",
"id": 2,
"result": "0x0000000000000000000000000000000000000000000000000000000000000012"
}Die ABI-codierte Ganzzahl ist 18. Das Ergebnis ist ein decimals-Wert, kein Kontostand, und belegt keine Verfügbarkeit auf anderen Höhen. Dieser feste Block fällt mit der Zeit aus einem begrenzten Fenster heraus; verwenden Sie einen aktuellen Block, wenn Sie das folgende Beispiel später ausführen.
Speichern Sie das Beispiel als historical-state.mjs und führen Sie node historical-state.mjs mit Node.js 24 oder höher und gesetzter Umgebungsvariable BLOCKVECTRA_API_KEY aus. Es nutzt den authentifizierten Endpunkt, behält denselben Contract und dieselben Calldata bei und vergleicht latest, einen festen aktuellen Block und einen Block außerhalb des veröffentlichten authentifizierten Fensters. Jede Ausgabe enthält den tatsächlichen HTTP-Status und den JSON-RPC-Body; ein HTTP 200 kann dennoch einen Fehler enthalten. Bei einer unerwarteten Antwort bricht es ab, anstatt diese als erfolgreiche Leseoperation zu behandeln.
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');
}
}Die oben aufgezeichnete Antwort verwendet public.url; das Skript verwendet einen API key. Um eine schlüssellose Leseoperation durchzuführen, übernehmen Sie die URL direkt aus public.url, lassen Sie den Key weg und wählen Sie einen Block sowohl innerhalb von public.history_blocks als auch innerhalb des State-Fensters. Eine Änderung der Authentifizierung kann den zulässigen Verlauf verändern, selbst für denselben Contract und dieselben Calldata.
Fehler außerhalb des Fensters diagnostizieren
Auf demselben schlüssellosen Endpunkt ergab ein am 2026-10-08 (UTC) als Stichprobe ausgeführter Aufruf, bei dem lediglich der Zielblock auf 0x18ef650 (und die Anfrage-ID) geändert wurde, HTTP 200 mit error.code: -32011, error.data.reason: state_window und error.data.retryable: false. Die Nachricht lautete block reference is outside the public history window. Dies ist ein Fehler des öffentlichen Verlaufs; der authentifizierte Endpunkt hat sein eigenes State-Fenster.
Verwenden Sie diese Felder aus dem state_window-Fehlereintrag, um den Fehler zu erkennen, anstatt sich auf eine bestimmte Fensternummer in der Nachricht zu verlassen:
| Feld | Dokumentierter Wert oder Bedeutung |
|---|---|
| HTTP-Status | 200; prüfen Sie den JSON-RPC-error auch bei erfolgreichem HTTP-Status |
error.code | -32011 |
error.message | Authentifizierte State-Window-Fehler beschreiben die Anzahl der zuletzt unterstützten Blöcke; Fehler des öffentlichen Verlaufs können eine andere Nachricht verwenden |
error.data.reason | state_window |
error.data.docs_url | Link zur state_window-Erklärung im Fehlerkatalog |
error.data.retryable | false: Ein erneutes Senden derselben Anfrage zu einem späteren Zeitpunkt stellt keinen älteren State wieder her |
Wählen Sie einen neueren nummerierten Block oder nutzen Sie latest, wenn die Aufgabe den aktuellen Wert benötigt. Das Verringern einer eth_getLogs-Spanne stellt keinen historischen eth_call-State wieder her. Andere Gründe für -32011 erfordern unterschiedliche Maßnahmen: range_not_indexed erfordert einen abgedeckten Bereich; history_not_ready erlaubt Wiederholungsversuche, nachdem die Indexierung aufholt. Prüfen Sie error.data.reason, nicht nur den numerischen Code.
Zugrunde liegender State kann auch mit -32000 nicht verfügbar sein oder bereinigter (pruned) Blockverlauf mit 4444; siehe den Fehlerkatalog. Wiederholen Sie eine Anfrage für einen alten Block nicht unverändert und gehen Sie nicht davon aus, dass ein größeres deklariertes Fenster jede Antwort garantiert.
Nächste Abfrage auswählen
Eine vollständige Workload-Checkliste und Selbsttests finden Sie unter Auswahl eines RPC-Providers.
Wenn Sie einen Provider für wiederholte Contract-Leseoperationen auswählen, vergleichen Sie Tages- und Zyklusbudgets für EVM-Leseoperationen. Prüfen Sie zuerst die erforderlichen historischen Blöcke und planen Sie anschließend die tägliche Verteilung und den Durchsatz der Aufgabe; das Einpassen in ein Guthabenbudget garantiert keine State-Abdeckung.
Bestätigen Sie beim Vergleich von Providern für historische Leseoperationen zunächst, dass beide den Zielblock bedienen können. Der Vergleich von Mehraufwand für vollständige Anfragen vergleicht zusätzliche RU-Preise mit methodenbasierten Kosten, trennt enthaltene Kontingente von zusätzlicher Nutzung und erläutert Full- versus Archive-Abrechnungsklassen.
Für frühere indexierte Blöcke, Transaktionen, Transfers oder andere Datensätze prüfen Sie die in der Tabelle deklarierten Data-API-Datensätze und die Data-API-Referenz. Indexierte Datensätze bieten keine beliebige historische Contract-Ausführung und bedeuten nicht, dass jede Chain über historische Kontostände verfügt.
- eth_call-Methodenreferenz für Aufrufparameter und Rückgabe-Codierung.
- eth_getLogs-Blockbereich und segmentierte Abfragen für den Event-Log-Verlauf.
- Benutzerdefiniertes Wallet-RPC-Setup für Wallet-Verbindungen und dedizierte Keys.
- Unterstützte Chains für die Netzwerkverfügbarkeit und CU-Preise für Methodenkosten.
Zuletzt aktualisiert:
DEX-Tagespreise
Tägliche DEX-OHLC-Preise und VWAP über die Data-API abfragen, exakte rationale Brüche in TypeScript und Python verarbeiten und historische Daten effizient nacherfassen.
Kostenloser Tarif
Verstehen Sie anhand realer Methodengewichte, was der kostenlose Tarif abdeckt, mit aufgabenbezogenen Berechnungen und Upgrade-Pfaden.