# eth_getLogs vs. Token Transfers API: ERC-20-Transferverlauf

> Source: https://docs.blockvectra.com/de/guides/logs-vs-transfers/

Für den Wallet-Verlauf oder den Abgleich von ERC-20-Transfers beginnen Sie mit der [Token Transfers API](https://blockvectra.com/de/data/transfers/). Verwenden Sie `eth_getLogs`, wenn Sie Contract-Event-Logs benötigen. Entwickler und KI-Agenten können indexierte Adresstransfers über dieselbe Blockchain-Data-API abfragen. Der [Leitfaden zu Wallet-Assets](https://docs.blockvectra.com/de/guides/wallet-assets/) kombiniert Token-Guthaben, Transferverlauf und Metadaten; die [Data-API-Referenz](https://docs.blockvectra.com/de/api/data/) definiert Anfrageparameter und Antwortschemas.

## Aufgaben, die dieser Leitfaden abdeckt

* [Contract-Event-Logs abfragen](#querying-logs-with-eth_getlogs) über authentifizierten RPC in begrenzten Blockbereichen für Monitoring oder Log-Backfill.
* [Indexierten ERC-20-Transferverlauf abfragen](#querying-transfers-with-the-data-api) über die Blockchain-Data-API nach Adresse oder Token-Contract, mit Cursor-Paginierung und Abdeckungsprüfungen.

## Zwei Wege zum Auslesen von Logs und Transfers

`eth_getLogs` ist eine JSON-RPC-Methode: Sie gibt Block-Logs über den JSON-RPC-Endpunkt zurück. Die Data API stellt den Token-Transferverlauf über zwei chainbezogene Endpunkte bereit:

* `GET /{chain}/addresses/{address}/transfers` — Transfers, die eine Adresse betreffen.
* `GET /{chain}/tokens/{token}/transfers` — Transfers für einen einzelnen Token-Contract.

Beide verwenden denselben API key und werden in CU nach Methodengewicht abgerechnet (siehe Gewichte unten). Welche Methode am besten passt, hängt davon ab, wie aktuell die Daten sind, ob Sie ein Blockfenster benötigen und wie Sie paginieren.

## Limits, die für eth\_getLogs gelten

`eth_getLogs` wird durch Limits pro Chain begrenzt, die in der öffentlichen Antwort von `GET /v1/chains` veröffentlicht werden:

* **Blockspanne**: `max_logs_block_range` ist die maximale Anzahl von Blöcken, die eine einzelne `eth_getLogs`-Anfrage umfassen darf. Sie unterscheidet sich je nach Chain — lesen Sie sie aus `GET /v1/chains` aus (Chains sind unter [Unterstützte Chains](https://docs.blockvectra.com/de/chains/) aufgeführt), anstatt sie fest zu codieren. Ein breiterer Bereich wird mit dem JSON-RPC-Fehler `-32602 eth_getLogs block range too large` abgelehnt (nicht abgerechnet).
* **Node-Synchronisation**: Solange der Node einer Chain nicht synchronisiert ist, gibt `eth_getLogs` `-32010` zurück (nicht abgerechnet).
* **State-Fenster**: Das State-Fenster, das `GET /v1/chains` als `state_window_blocks` ausweist, gilt für State-Leseoperationen wie `eth_call` und `eth_getBalance`, nicht für `eth_getLogs`.
* **Node-Pruning**: Block- und Log-Leseoperationen werden nicht durch das State-Fenster beschränkt, wohl aber durch den vom Node vorgehaltenen Verlauf. Bereinigte Daten (pruned) geben `4444 pruned history unavailable` zurück (nicht abgerechnet).

Wenn die Filterfelder `fromBlock` und `toBlock` weggelassen werden oder `null` sind, fallen sie standardmäßig auf `latest` zurück.

Der Aufruf von `eth_subscribe` über HTTP gibt `-32601 method not available` zurück. Auf Chains, bei denen `ws` in `/v1/chains` `true` ist, steht `eth_subscribe` über WebSocket zur Verfügung (siehe [Unterstützte Chains](https://docs.blockvectra.com/de/chains/)); andernfalls pollen Sie `eth_getLogs` über die neuesten Blöcke.

## Was die Transfers-Endpunkte der Data API bieten

Die beiden Endpunkte erfordern unterschiedliche Parameter:

| Endpunkt                                     | `standard`                                                                   | Blockfenster                                                                                                                                                                                                                                                              |
| -------------------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /{chain}/addresses/{address}/transfers` | Erforderlich: `erc20` oder `erc721`. `erc1155` gibt `422 no_coverage` zurück | `from_block` und `to_block` sind beide erforderlich. Ergebnisse sind absteigend nach `(block_number, log_index)` sortiert. `direction` (`in`, `out` oder `any`; Standard `any`) filtert nach Richtung, und `token` beschränkt die Ergebnisse optional auf einen Contract. |
| `GET /{chain}/tokens/{token}/transfers`      | Erforderlich: `erc20`, `erc721` oder `erc1155`                               | `from_block` und `to_block` sind optional. Ein fehlendes `to_block` fällt standardmäßig auf `as_of_block` zurück; ein explizites `to_block` oder `from_block` darüber führt zu einem harten `409 not_indexed_yet` ohne `clamp`-Ausweichmöglichkeit.                       |

### Paginierung

Beide Endpunkte sind keyset-paginiert:

* `limit` beträgt standardmäßig 50; Werte über 500 werden auf 500 begrenzt, und `0` oder ein Nicht-Ganzzahl-Wert gibt `400 bad_request` zurück.
* `next_cursor` erscheint nur, wenn eine weitere Seite vorhanden ist. Auf der letzten Seite fehlt der Schlüssel vollständig, niemals `null`.
* Übergeben Sie den zurückgegebenen Wert unverändert als `cursor`, um die nächste Seite abzurufen. Ein Cursor ist nur für die Chain, den Endpunkt und die Abfrageparameter gültig, die ihn ausgegeben haben.

### Abdeckung und Finalität

Data-API-Transfers indexieren historische Token-Transfers von `coverage.from_block` der jeweiligen Chain bis hin zu `meta.as_of_block`. Unter [Unterstützte Chains](https://docs.blockvectra.com/de/chains/) sehen Sie, welche Chains dies bereitstellen.

Jeder Transfer-Eintrag enthält `token`, `standard`, `from`, `to`, `block_number`, `block_timestamp`, `tx_hash`, `tx_index` und `log_index`. ERC-20-Einträge enthalten zusätzlich `amount`; ERC-721-Einträge `token_id`; ERC-1155-Einträge `operator`, `token_id`, `value` und `batch_index`.

## Wann welche Option zu nutzen ist

| Typische Aufgabe                           | Bessere Wahl                                                 | Warum                                                                                                                                                              |
| ------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Events in den letzten paar hundert Blöcken | `eth_getLogs`                                                | Eine Anfrage kann einen aktuellen Bereich abdecken, solange sie `max_logs_block_range` dieser Chain nicht überschreitet.                                           |
| Historische Transfers einer Adresse        | `GET /{chain}/addresses/{address}/transfers`                 | Adressbezogene Abfrage mit einem `from_block`/`to_block`-Fenster, `direction`- und `token`-Filtern sowie Cursor-Paginierung; liefert Ergebnisse bis `as_of_block`. |
| Alle Transfers eines Tokens                | `GET /{chain}/tokens/{token}/transfers`                      | Token-Contract-bezogene Abfrage für `erc20`, `erc721` und `erc1155` mit optionalem Fenster und Cursor-Paginierung für die gesamte Ergebnismenge.                   |
| Live-Monitoring neuer Events               | `eth_subscribe` (WebSocket-Chains) / `eth_getLogs` (Polling) | Neue Heads oder Logs über WebSocket abonnieren, wo unterstützt, oder aktuelle Blockbereiche pollen.                                                                |

## Logs mit eth\_getLogs abfragen

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

# fromBlock / toBlock default to latest. Set an explicit recent range to follow
# new events, and keep its span within the chain's max_logs_block_range.
curl -s "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "eth_getLogs",
    "params": [{
      "address": "0x1111111111111111111111111111111111111111",
      "fromBlock": "latest",
      "toBlock": "latest"
    }]
  }'
```


  **TypeScript**

```ts
const res = await fetch("https://api.blockvectra.com/v1/robinhood_mainnet", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": process.env.BLOCKVECTRA_API_KEY!,
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "eth_getLogs",
    params: [{
      address: "0x1111111111111111111111111111111111111111",
      fromBlock: "latest",
      toBlock: "latest",
    }],
  }),
});

const { result } = await res.json();
console.log(result);

// npx tsx example.mts
```


  **Python**

```python
import os
import requests

res = requests.post(
    "https://api.blockvectra.com/v1/robinhood_mainnet",
    headers={
        "Content-Type": "application/json",
        "x-api-key": os.environ["BLOCKVECTRA_API_KEY"],
    },
    json={
        "jsonrpc": "2.0",
        "id": 1,
        "method": "eth_getLogs",
        "params": [{
            "address": "0x1111111111111111111111111111111111111111",
            "fromBlock": "latest",
            "toBlock": "latest",
        }],
    },
)
res.raise_for_status()
print(res.json())
```


## Transfers mit der Data API abfragen

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

# from_block / to_block are optional here; omitting to_block defaults to as_of_block.
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens/0x1111111111111111111111111111111111111111/transfers?standard=erc20" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
let cursor: string | undefined;

do {
  const url = new URL(
    "https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens/0x1111111111111111111111111111111111111111/transfers",
  );
  url.searchParams.set("standard", "erc20");
  if (cursor) url.searchParams.set("cursor", cursor);

  const res = await fetch(url, {
    headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! },
  });
  const body = await res.json();
  console.log(body.data);
  cursor = body.next_cursor; // absent on the last page
} while (cursor);

// npx tsx example.mts
```


  **Python**

```python
import os
import requests

url = "https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens/0x1111111111111111111111111111111111111111/transfers"
cursor = None

while True:
    params = {"standard": "erc20"}
    if cursor:
        params["cursor"] = cursor
    res = requests.get(
        url,
        params=params,
        headers={"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]},
    )
    res.raise_for_status()
    body = res.json()
    print(body["data"])
    cursor = body.get("next_cursor")  # absent on the last page
    if not cursor:
        break
```


Um stattdessen nach Adresse abzufragen, sind `from_block` und `to_block` erforderlich:

```bash
# clamp=true truncates a too-wide window, or a to_block above as_of_block,
# instead of returning 409.
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/transfers?standard=erc20&from_block=0&to_block=73000000&direction=any&clamp=true" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```

## CU pro Aufruf

Jede Methode wird nach ihrem CU-Gewicht abgerechnet. Die folgenden Gewichte werden aus der Plans-API der Plattform ausgelesen:

**CU-Gewichtung pro Aufruf**

| Methode | CU pro Aufruf |
| --- | --- |
| `eth_getLogs` | 30 |
| `data.address_transfers` | 25 |
| `data.token_transfers` | 25 |

Aktuelle Preise und Aufladeoptionen finden Sie auf der [Preisseite](https://blockvectra.com/de/pricing/).

## Nächste Schritte

* [Datensatzverzeichnis durchsuchen](https://blockvectra.com/de/data/), um alle von BlockVectra indexierten Datensätze zu sehen.
* [Kostenlosen Tarif und Preise ansehen](https://blockvectra.com/de/pricing/#free), um zu prüfen, was Ihr Konto beinhaltet.
* [In der Konsole anmelden](https://console.blockvectra.com/login/?next=%2Fkeys%2F), um einen API key zu erstellen.
