# Historischen EVM-State innerhalb unterstützter Fenster abfragen

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

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](https://api.blockvectra.com/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](https://api.blockvectra.com/v1/chains) und [GET /v1/status](https://api.blockvectra.com/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](https://api.blockvectra.com/v1/chains) · Stichprobe (UTC): 2026-10-09

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

## 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:

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

Antwort:

```json
{
  "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.

```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');
  }
}
```

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](https://docs.blockvectra.com/de/errors/#state_window), 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](https://docs.blockvectra.com/de/errors/#range_not_indexed) erfordert einen abgedeckten Bereich; [history\_not\_ready](https://docs.blockvectra.com/de/errors/#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](https://docs.blockvectra.com/de/errors/). 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](https://docs.blockvectra.com/de/guides/choose-rpc-provider/).

Wenn Sie einen Provider für wiederholte Contract-Leseoperationen auswählen, [vergleichen Sie Tages- und Zyklusbudgets für EVM-Leseoperationen](https://docs.blockvectra.com/de/guides/infura-alternative/). 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](https://docs.blockvectra.com/de/guides/chainstack-alternative/) 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](https://docs.blockvectra.com/de/api/data/). 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](https://docs.blockvectra.com/de/api/json-rpc/methods/eth_call/) für Aufrufparameter und Rückgabe-Codierung.
* [eth\_getLogs-Blockbereich und segmentierte Abfragen](https://docs.blockvectra.com/de/guides/getlogs-block-range/) für den Event-Log-Verlauf.
* [Benutzerdefiniertes Wallet-RPC-Setup](https://docs.blockvectra.com/de/guides/wallet-custom-rpc/) für Wallet-Verbindungen und dedizierte Keys.
* [Unterstützte Chains](https://docs.blockvectra.com/de/chains/) für die Netzwerkverfügbarkeit und [CU-Preise](https://docs.blockvectra.com/de/guides/reading-cu-pricing/) für Methodenkosten.
