# eth_getLogs vs Token Transfers API : historique des transferts ERC-20

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

Pour l'historique d'un portefeuille ou la réconciliation des transferts ERC-20, commencez par la [Token Transfers API](https://blockvectra.com/fr/data/transfers/). Utilisez `eth_getLogs` lorsque vous avez besoin des logs d'événements de contrat. Les développeurs et les agents IA peuvent interroger les transferts d'adresses indexés via la même API de données blockchain. Le [guide des actifs de portefeuille](https://docs.blockvectra.com/fr/guides/wallet-assets/) combine les soldes de jetons, l'historique des transferts et les métadonnées ; la [référence de la Data API](https://docs.blockvectra.com/fr/api/data/) définit les paramètres de requête et les schémas de réponse.

## Tâches que ce guide vous aide à accomplir

* [Interroger les logs d'événements de contrat](#querying-logs-with-eth_getlogs) via le RPC authentifié dans des plages de blocs bornées pour la surveillance ou le rétro-remplissage de logs.
* [Interroger l'historique indexé des transferts ERC-20](#querying-transfers-with-the-data-api) via l'API de données blockchain par adresse ou par contrat de jeton, avec pagination par curseur et vérifications de couverture.

## Deux façons de lire les logs et les transferts

`eth_getLogs` est une méthode JSON-RPC : elle renvoie les logs de blocs via l'endpoint JSON-RPC. La Data API expose l'historique des transferts de jetons via deux endpoints délimités par chaîne :

* `GET /{chain}/addresses/{address}/transfers` — transferts impliquant une adresse.
* `GET /{chain}/tokens/{token}/transfers` — transferts pour un contrat de jeton unique.

Les deux utilisent la même API key et sont mesurés en CU selon le poids de la méthode (voir les poids ci-dessous). Le choix de l'une ou l'autre dépend de l'ancienneté des données, du besoin d'une fenêtre de blocs et du mode de pagination.

## Limites qui s'appliquent à eth\_getLogs

`eth_getLogs` est encadré par des limites par chaîne publiées par la réponse publique de `GET /v1/chains` :

* **Étendue de blocs** : `max_logs_block_range` est le nombre maximal de blocs qu'une seule requête `eth_getLogs` peut couvrir. Il varie selon la chaîne — lisez-le depuis `GET /v1/chains` (les chaînes sont répertoriées sur la page [Chaînes prises en charge](https://docs.blockvectra.com/fr/chains/)) plutôt que de le coder en dur. Une plage plus large est rejetée avec l'erreur JSON-RPC `-32602 eth_getLogs block range too large` (non facturé).
* **Synchronisation du nœud** : tant que le nœud d'une chaîne n'est pas synchronisé, `eth_getLogs` renvoie `-32010` (non facturé).
* **Fenêtre d'état** : la fenêtre d'état que `GET /v1/chains` indique sous le nom `state_window_blocks` s'applique aux méthodes de lecture d'état telles que `eth_call` et `eth_getBalance`, et non à `eth_getLogs`.
* **Élagage du nœud** : les lectures de blocs et de logs ne sont pas limitées par la fenêtre d'état, mais elles sont limitées par l'historique conservé par le nœud. Les données élaguées renvoient `4444 pruned history unavailable` (non facturé).

Lorsque les champs de filtre `fromBlock` et `toBlock` sont omis ou définis sur `null`, ils prennent la valeur par défaut `latest`.

Appeler `eth_subscribe` sur HTTP renvoie `-32601 method not available`. Sur les chaînes où `ws` vaut `true` dans `/v1/chains`, `eth_subscribe` est disponible via WebSocket (voir [Chaînes prises en charge](https://docs.blockvectra.com/fr/chains/)) ; sinon, scrutez `eth_getLogs` sur les blocs les plus récents.

## Ce que fournissent les endpoints de transferts de la Data API

Les deux endpoints nécessitent des paramètres différents :

| Endpoint                                     | `standard`                                                        | Fenêtre de blocs                                                                                                                                                                                                                                                                    |
| -------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /{chain}/addresses/{address}/transfers` | Requis : `erc20` ou `erc721`. `erc1155` renvoie `422 no_coverage` | `from_block` et `to_block` sont tous deux requis. Les résultats sont triés par `(block_number, log_index)` par ordre décroissant. `direction` (`in`, `out` ou `any` ; par défaut `any`) filtre par direction, et `token` restreint facultativement les résultats à un seul contrat. |
| `GET /{chain}/tokens/{token}/transfers`      | Requis : `erc20`, `erc721` ou `erc1155`                           | `from_block` et `to_block` sont facultatifs. L'absence de `to_block` prend la valeur par défaut `as_of_block` ; un `to_block` ou `from_block` explicite supérieur à celui-ci déclenche une erreur stricte `409 not_indexed_yet`, sans possibilité d'échappement par `clamp`.        |

### Pagination

Les deux endpoints utilisent une pagination par jeu de clés (keyset) :

* `limit` a pour valeur par défaut 50 ; les valeurs supérieures à 500 sont ramenées à 500, et `0` ou une valeur non entière renvoie `400 bad_request`.
* `next_cursor` n'apparaît que lorsqu'il existe une page suivante. Sur la dernière page, la clé est totalement absente, jamais `null`.
* Transmettez la valeur renvoyée dans le paramètre `cursor`, sans modification, pour récupérer la page suivante. Un curseur n'est valide que pour la chaîne, l'endpoint et les paramètres de requête qui l'ont émis.

### Couverture et finalité

Les transferts de la Data API indexent l'historique des transferts de jetons depuis le `coverage.from_block` de chaque chaîne jusqu'à `meta.as_of_block`. Consultez la page [Chaînes prises en charge](https://docs.blockvectra.com/fr/chains/) pour savoir quelles chaînes le proposent.

Chaque élément de transfert contient `token`, `standard`, `from`, `to`, `block_number`, `block_timestamp`, `tx_hash`, `tx_index` et `log_index`. Les éléments ERC-20 ajoutent `amount` ; les éléments ERC-721 ajoutent `token_id` ; les éléments ERC-1155 ajoutent `operator`, `token_id`, `value` et `batch_index`.

## Lequel utiliser

| Tâche type                                                       | Meilleur choix                                                   | Pourquoi                                                                                                                                                                                  |
| ---------------------------------------------------------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Événements dans les quelques centaines de blocs les plus récents | `eth_getLogs`                                                    | Une seule requête peut couvrir une plage récente tant qu'elle ne dépasse pas le `max_logs_block_range` de cette chaîne.                                                                   |
| Transferts historiques d'une adresse                             | `GET /{chain}/addresses/{address}/transfers`                     | Requête ciblée par adresse avec une fenêtre `from_block`/`to_block`, des filtres `direction` et `token`, et une pagination par curseur ; les résultats sont servis jusqu'à `as_of_block`. |
| Tous les transferts d'un jeton                                   | `GET /{chain}/tokens/{token}/transfers`                          | Requête ciblée par contrat de jeton couvrant `erc20`, `erc721` et `erc1155`, avec une fenêtre facultative et une pagination par curseur pour le jeu complet de résultats.                 |
| Surveillance en direct des nouveaux événements                   | `eth_subscribe` (chaînes WebSocket) / `eth_getLogs` (scrutation) | Abonnez-vous aux nouvelles têtes ou aux logs via WebSocket lorsque c'est pris en charge, ou scrutez des plages de blocs récentes.                                                         |

## Interroger les logs avec eth\_getLogs

**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())
```


## Interroger les transferts avec la Data API

**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
```


Pour interroger par adresse à la place, `from_block` et `to_block` sont requis :

```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 par appel

Chaque méthode est facturée selon son poids en CU. Les poids ci-dessous sont lus depuis l'API des forfaits de la plateforme :

**Poids en CU par appel**

| Méthode | CU par appel |
| --- | --- |
| `eth_getLogs` | 30 |
| `data.address_transfers` | 25 |
| `data.token_transfers` | 25 |

Pour les prix actuels et les options de recharge, consultez la [page Tarifs](https://blockvectra.com/fr/pricing/).

## Prochaines étapes

* [Parcourir le catalogue des jeux de données](https://blockvectra.com/fr/data/) pour découvrir chaque jeu de données indexé par BlockVectra.
* [Consulter le forfait gratuit et les tarifs](https://blockvectra.com/fr/pricing/#free) pour vérifier ce que comprend votre compte.
* [Se connecter à la console](https://console.blockvectra.com/login/?next=%2Fkeys%2F) pour créer une API key.
