Skip to main content

Vue d’ensemble

La blockchain Solana stocke les données dans un registre séquentiel et à ajout unique. Cela est excellent pour l’intégrité des données et le débit des transactions, mais cela a un coût significatif : cela rend les requêtes de données historiques très inefficaces et prohibitives en termes de temps. Les opérations complexes impliquent souvent le filtrage, l’agrégation ou la jonction de données provenant de plusieurs sources. Dans ces cas, effectuer des requêtes directes à Solana est impraticable pour la plupart des applications du monde réel. Pour résoudre cela, la plupart des entreprises construisent des index privés des données historiques de Solana. Ce guide couvre le cycle de vie complet : compléter les données historiques avec getTransactionsForAddress et d’autres méthodes RPC archivales, choisir une base de données et maintenir l’index à jour avec le streaming en temps réel.

Quand utiliser ceci

Construire un index lorsque :
  • Votre produit a besoin de requêtes rapides et filtrées pour lesquelles les appels RPC directs sont trop lents (par exemple, les comptes de jetons et les soldes d’un portefeuille, ou l’historique complet d’une paire de trading)
  • Vous devez filtrer, agréger ou joindre des données on-chain, ou les combiner avec des données hors chaîne (prix CEX, KYC, étiquettes)
  • Vous calculez des éléments tels que le PnL, l’analyse des détenteurs, ou l’historique de vente des NFT qui nécessitent des données prétraitées et requêtables
  • Vous servez de nombreux utilisateurs et ne pouvez vous permettre une latence par requête contre la chaîne
Si vous avez seulement besoin des données standard de portefeuille ou d’actifs, une API gérée peut être plus simple que de gérer votre propre index. Voir Options complémentaires ci-dessous.

Que signifie indexer les données de Solana ?

L’indexation est le processus de requête des données de la blockchain Solana et leur stockage dans une base de données de backend (par exemple, PostgreSQL, ClickHouse) qui peut ensuite être utilisée pour servir rapidement les requêtes des clients sans avoir besoin de questionner directement la blockchain en utilisant les appels RPC Solana. Un indexeur effectue généralement quatre tâches :
  1. Compléter les données historiques : utiliser les méthodes RPC archivales pour interroger toutes les données historiques
  2. Streamer les nouvelles données : traiter les nouveaux blocs lorsqu’ils sont confirmés par le réseau
  3. Parser et transformer les données : extraire les données pertinentes des blocs confirmés (transactions, changements d’état, etc.)
  4. Organiser les données dans une base de données : mettre à jour l’index avec les nouvelles données

Pourquoi la plupart des entreprises construisent-elles des index Solana ?

Les entreprises créent des index Solana car leur activité dépend de l’accès rapide et en temps réel à des données spécifiques de la blockchain que les RPC natifs ne proposent pas (par exemple, l’historique des ventes de NFT). Les entreprises utilisent également des indices personnalisés pour combiner des données hors chaîne (par exemple, les prix des échanges centralisés, les informations KYC, etc.) avec leurs données on-chain.

Exemple de portefeuille

Par exemple, si un portefeuille Solana doit renvoyer rapidement les comptes de jetons et les soldes d’un utilisateur, interroger Solana directement avec getTokenAccountsByOwner et getTokenAccountBalance est trop lent et pourrait rendre leur produit inutilisable. Au lieu de cela, les portefeuilles maintiennent généralement leurs propres index des adresses, des jetons et des soldes des comptes clients.

Exemple de trading

De même, une entreprise de trading crypto peut vouloir consigner toutes les activités de trading qui se déroulent sur une paire de trading spécifique (par exemple, SOL-USDC) ou un marché spécifique pour tester leurs algorithmes de trading. Interroger directement la blockchain pour ces données serait bien trop lent pour toute analyse de trading pratique. Les traders quantitatifs peuvent choisir de créer des index pour le marché SOL-USDC et de le maintenir à jour avec les dernières transactions en utilisant des produits de streaming en temps réel comme LaserStream.

Exemple de filtrage

Imaginez qu’un utilisateur souhaite filtrer les transactions par des critères spécifiques dans son application frontend (par exemple, par type de jeton, montant du transfert, date ou adresse de portefeuille). Sans un indexeur, votre application devrait parcourir des millions de transactions à travers des centaines de milliers de blocs, vérifiant chacune par rapport aux critères de filtrage. Ce processus est trop lent pour les expériences utilisateur modernes.

Exemple de PnL

Pour calculer le profit et la perte (PnL) d’un trader, vous devriez :
  • Trouver chaque transaction associée à son portefeuille dans un délai donné
  • Filtrer les transactions de swap et les étiqueter comme achats ou ventes
  • Déterminer combien de frais l’utilisateur a payés lors de chaque swap
  • Obtenir les données de prix historiques pour chaque jeton au moment de chaque transaction
  • Ajouter le PnL de chaque transaction pour calculer le PnL total du trader
Calculer tout cela en temps réel est impraticable et nécessite une solution plus rapide et plus évolutive. Avec un index, toutes ces informations sont déjà traitées et stockées dans une base de données requêtable. Désormais, calculer le PnL d’un trader devient un simple appel API servi instantanément. Examinons trois approches pour compléter un index Solana et le maintenir à jour.

Étape 1 : Obtenez les données historiques

La première étape pour construire un index Solana consiste à obtenir toutes les données historiques qui vous intéressent. Il y a trois manières principales de le faire :
  1. getTransactionsForAddress (recommandé)
  2. getSignaturesForAddress et getTransaction
  3. getBlock

Méthode 1 : getTransactionsForAddress (recommandé)

La méthode RPC getTransactionsForAddress vous permet de récupérer les détails de transaction complets pour un segment arbitraire de données blockchain. Grâce à ses capacités de filtrage puissantes, vous ne perdrez pas de temps à récupérer des données qui ne sont pas nécessaires pour votre index, et grâce à sa fonctionnalité de recherche inversée, vous pouvez obtenir les transactions dans l’ordre chronologique.

Étapes pour utiliser cette méthode

  • Déterminez la période dont vous avez besoin et définissez le filtre en conséquence
  • Configurez transactionDetails à full pour obtenir tous les détails de transaction
  • Configurez le filtre tokenAccounts pour inclure les transactions de comptes de jetons associés si nécessaire
  • Paginer à travers les résultats en utilisant paginationToken
  • À chaque itération, extrayez les données dont vous avez besoin et stockez-les dans votre base de données

Avantages de l’utilisation de getTransactionsForAddress

Les principaux avantages de l’utilisation du point de terminaison gTFA sont la rapidité et la simplicité. Avec les filtres basés sur la slot et le temps, le support des comptes de jetons, la recherche inversée et la pagination, vous pouvez obtenir toutes les données que vous souhaitez, de n’importe quel moment de l’histoire de Solana, le tout avec un simple appel sans boucles complexes ni logique de répétition. Contrairement à getSignaturesForAddress, il peut également inclure des transactions impliquant des comptes de jetons associés détenus par l’adresse. Si votre index concerne spécifiquement le mouvement des jetons et du SOL natif (paiements, registres, rapprochement des soldes), getTransfersByAddress renvoie des lignes de transfert parsées, prêtes pour le rapprochement au lieu de transactions complètes, ce qui peut vous faire gagner une étape de parsing.

Méthode 2 : getSignaturesForAddress et getTransaction

Avant la sortie de gTFA, l’approche standard pour interroger les données historiques consistait à boucler de manière récursive sur les signatures en utilisant getSignaturesForAddress (du plus récent au plus ancien) et ensuite appeler getTransaction pour extraire les détails de transaction complets.

Étapes pour utiliser cette méthode

Voici les étapes de base pour utiliser cette méthode :
  • Appelez getSignaturesForAddress
  • Stockez la signature de la dernière transaction reçue de cet appel
  • Pour le prochain appel à getSignaturesForAddress, définissez le paramètre before sur cette signature
  • Répétez ceci en boucle aussi longtemps que nécessaire
  • Pour chaque signature de transaction récupérée de cette manière, appelez getTransaction pour obtenir ses détails de transaction complets
  • Insérez les données pertinentes dans votre base de données

Inconvénients de cette méthode

Malheureusement, pour utiliser cette méthode, vous devez :
  • Commencer à la transaction la plus récente et remonter
  • Effectuer un appel RPC supplémentaire pour chaque transaction
  • Construire une file d’attente thread-safe pour gérer le traitement simultané
  • Construire une logique pour les répétitions et les reculs pour éviter de manquer des données et être limité par le taux
  • Ne pas inclure les transactions impliquant des comptes de jetons associés détenus par l’adresse
Bien que cette méthode fonctionne, elle est plus compliquée, moins flexible et dépense beaucoup plus de crédits. Pour un historique complet de portefeuille incluant les comptes de jetons, utilisez getTransactionsForAddress à la place.

Méthode 3 : Utiliser getBlock

La méthode getBlock est la plus efficace lorsqu’un pourcentage élevé de transactions dans vos blocs cibles est pertinent pour votre analyse, comme l’indexation des transactions de programmes Solana fréquemment utilisés comme l’agrégateur de DFlow, le programme Pump.fun, ou le programme Token de Solana.

Étapes pour utiliser cette méthode

Le processus de base pour interroger les données historiques avec getBlock inclut :
  • Décidez d’une période à interroger
  • Convertissez cette période en numéros de slot
  • Récupérez les blocs correspondants de manière séquentielle (vers l’avant ou l’arrière)
  • Pour chaque bloc, filtrez les transactions qui sont pertinentes pour votre index
  • Stockez les informations pertinentes dans votre index
Pour la plupart des cas d’utilisation, cette méthode est intrinsèquement inefficace car vous récupérez toutes les transactions d’un bloc alors que typiquement seules une petite fraction seront pertinentes pour votre analyse. Utilisez cette méthode uniquement lorsque vous examinez les transactions de programmes fréquemment utilisés ou lorsque le filtrage basé sur l’adresse ne peut pas capturer vos données cibles.

Étape 2 : Synchronisez les données de Solana avec votre base de données

Après avoir récupéré les données historiques, vous devez les transformer et les stocker efficacement dans une base de données. Votre choix de stockage doit être adapté à votre cas d’utilisation spécifique — il n’existe pas de solution unique. La bonne base de données dépend de la taille de votre ensemble de données, des exigences de latence, des schémas de requête et de l’expertise de l’équipe.

Option 1 : Bases de données SQL

Stocker les données de Solana dans des bases de données relationnelles comme PostgreSQL est recommandé pour la plupart des cas d’utilisation. Le SQL est flexible, omniprésent et facile à apprendre. Les bases de données relationnelles modernes peuvent évoluer au-delà de 100M+ lignes, tout en vous offrant les avantages de la conformité ACID, des jointures complexes et des indices secondaires puissants. Utilisez SQLite pour le prototypage, le développement local ou lorsque vous souhaitez une configuration zéro avec une base de données à fichier unique. C’est idéal lorsque votre ensemble de données ne dépasse pas quelques gigaoctets. Utilisez PostgreSQL pour les applications de production qui ont besoin de réplication de données, d’accès simultané depuis plusieurs clients, ou de fonctionnalités avancées comme la recherche en texte intégral et les opérateurs JSON. Pour la plupart des indexeurs Solana de niveau production, PostgreSQL est notre choix recommandé.

Exemple de mise en œuvre :

À titre d’exemple, nous allons montrer comment stocker des transferts de jetons dans une base de données PostgreSQL. Tout d’abord, créez une table :
Ensuite, ajoutez des index sur les colonnes fréquemment interrogées :
Vous pouvez également créer des indices partiels si seul un sous-ensemble des données est fréquemment interrogé. Voici comment créer un index pour les transferts de grande valeur uniquement :
Lors du complément de données, assurez-vous d’utiliser des INSERTs en masse et des instructions préparées pour une vitesse d’écriture optimale.

Option 2 : Bases de données en colonnes

Les bases de données en colonnes sont optimisées pour les requêtes analytiques, les agrégations et les données chronologiques à haut volume. Si vous devez indexer plusieurs milliards de transactions, des bases de données en colonnes comme ClickHouse ou Cassandra sont votre meilleure option. Utilisez ClickHouse lorsque vous avez besoin de requêtes analytiques en temps réel sur de grands ensembles de données — il est optimisé pour les lectures rapides, les agrégations et l’analyse chronologique. Utilisez Cassandra lorsque vous avez besoin d’un débit d’écriture extrêmement élevé, d’une mise à l’échelle horizontale sans effort et d’une tolérance aux pannes élevée. Cela en fait un choix idéal pour l’ingestion continue de volumes massifs de données Solana.

Exemple de mise en œuvre :

Nous allons montrer comment stocker les transferts de jetons dans une base de données ClickHouse. À cette fin, créez une table qui utilise le moteur de table MergeTree. Il est conçu pour des taux d’ingestion élevés, donc idéal pour l’indexation. Utilisez cette commande :
Dans cette configuration, (token_mint, date) est défini comme à la fois la clé primaire et la clé de tri. ClickHouse ordonnera les données sur le disque selon votre clé de tri. C’est optimal pour interroger un seul token mint, et réduire la réponse par plages de dates. Voici un exemple de requête :
Les signatures et adresses de transactions sont stockées en utilisant le format de données FixedString(N) qui stocke exactement N octets. ClickHouse compresse automatiquement les données, ce qui réduit les coûts de stockage de 10-20x et améliore les performances des requêtes. Pour optimiser les performances des requêtes, utilisez des vues matérialisées pour pré-calculer les agrégations courantes. Par exemple, vous pourriez pré-calculer le volume de transfert quotidien des jetons à utiliser par des graphiques liés au volume sur un tableau de bord.

Option 3 : Lacs de données

Les lacs de données sont idéaux pour stocker des quantités massives de données blockchain brutes et traitées pour l’archivage à long terme et les requêtes analytiques. Une implémentation simple utilise le format de données Parquet avec Amazon Athena. Parquet est un format de fichier de données orienté colonne conçu pour un stockage et une récupération efficaces des données. Amazon Athena est un service de requêtes interactif qui vous permet d’analyser des données stockées dans Amazon S3 en utilisant le SQL standard sans avoir besoin de configurer une infrastructure ou de charger des données dans une base de données séparée.
Les lacs de données ne sont recommandés que si vous avez besoin de requêter de grandes quantités de données non structurées. Pour la majorité des cas d’utilisation, nous recommandons l’utilisation d’une base de données SQL (Option 1).

Exemple de mise en œuvre :

Nous voulons créer une archive des transferts de jetons et les interroger. Tout d’abord, nous devons les stocker dans S3 : Créez un compartiment nommé solana_index et partitionnez vos données de transfert de jetons par temps en utilisant cette structure de clé :
Les transferts de chaque jour sont stockés dans un fichier Parquet séparé dans son dossier de date correspondant. Au fur et à mesure que vous traitez les transferts de Solana, transformez-les au format Parquet et inscrivez-les dans l’objet S3 respectif. Ensuite, vous créez une table dans Athena et la connectez au compartiment. Cela vous permet de lancer des requêtes comme celle-ci directement sur les données du compartiment :

Utiliser des frameworks d’indexation

Utilisez Carbon et des frameworks similaires pour éviter d’écrire du code redondant et configurer votre indexeur en quelques heures plutôt que des jours.

Principales caractéristiques :

  • Décodeurs pré-construits pour les programmes populaires (programme Token, protocoles DeFi, Metaplex)
  • Sources de données configurables (RPC, LaserStream, Enhanced WebSockets)
  • Prise en charge intégrée du complément et du streaming en temps réel
  • Sorties vers plusieurs supports de stockage (Postgres par défaut)
  • Entièrement personnalisable : vous pouvez configurer vos propres sources de données, décodeurs et puits de données

Étape 3 : Maintenez votre index à jour

Après avoir complété les données historiques, vous avez besoin d’une solution de streaming en temps réel pour maintenir votre index à jour avec la nouvelle activité de la blockchain. Sans cela, votre index devient obsolète.

Méthode 1 : LaserStream (recommandé)

Nous recommandons LaserStream gRPC comme choix par défaut pour tous les cas d’utilisation d’indexation en production. Il est spécialement conçu pour un streaming de données fiable, à ultra-faible latence et tolérant aux pannes. Quelques avantages de l’utilisation de LaserStream incluent :
  • Relecture historique de 24 heures : si votre indexeur se déconnecte, LaserStream rejoue automatiquement toutes les transactions manquées à partir de l’endroit où vous vous êtes arrêté
  • Reconnexion automatique : nos SDKs LaserStream (Rust, Go, JS/TS) gèrent de manière transparente les interruptions de réseau pour vous
  • Gestion des pannes de nœuds : votre connexion LaserStream agrège les données de plusieurs nœuds simultanément, garantissant un temps de disponibilité maximal
Alliant vitesse et fiabilité, LaserStream est idéal pour les applications en temps réel comme les flux de transactions en direct, les tableaux de bord de trading et les mises à jour instantanées des soldes.

Comment utiliser LaserStream pour l’indexation

Utilisez la méthode subscribe pour vous abonner aux événements de la blockchain. Voici quelques bonnes pratiques :
  • Réduisez au maximum votre filtre : Abonnez-vous uniquement aux données que vous devez réellement indexer pour minimiser la consommation de bande passante et le traitement nécessaire.
  • Utilisez le niveau de garantie confirmed : Cela équilibre la latence et la finalité. Le niveau processed peut être trop peu fiable, tandis que finalized ajoute environ 13 secondes de latence
  • Définissez failed: false sauf si vous avez spécifiquement besoin de suivre les transactions échouées
  • Excluez les transactions de vote (vote: false) car elles ne sont pas pertinentes pour l’indexation
Examinons un exemple. Utilisez l’abonnement suivant pour indexer tous les nouveaux transferts de jetons :

Méthode 2 : Utiliser LaserStream WebSocket

LaserStream WebSocket — la variante WebSocket de LaserStream, y compris l’extension spécifique Helius transactionSubscribe — fonctionne sur le même backend que LaserStream gRPC et est une alternative de streaming en temps réel économique lorsque vous n’avez pas besoin de gRPC. Vous devriez utiliser LaserStream WebSocket lorsque :
  • Votre application peut tolérer des écarts de données occasionnels
  • Les mises à jour en temps réel sont importantes, mais pas critiques
  • Vous avez une infrastructure existante pour détecter et compléter les données manquantes
  • Les contraintes budgétaires sont significatives et vous devez minimiser les coûts de streaming
  • Vous êtes en phase de prototypage ou de test avant de vous engager sur LaserStream
Cependant, il y a quelques compromis à considérer lors du choix des WebSockets :
  • Vitesse : LaserStream WebSocket fonctionne sur le même backend que LaserStream gRPC, mais le protocole WebSocket ajoute un encadrement JSON et un surcoût par message — pour la latence la plus faible possible sur les mêmes données, utilisez LaserStream gRPC
  • Fiabilité : Pas de garantie de relecture historique. Si votre WebSocket se déconnecte, vous devrez détecter et compléter manuellement les écarts en utilisant les méthodes RPC
  • Complexité : Nécessite une infrastructure de surveillance supplémentaire pour garantir l’exhaustivité des données

Comment utiliser les WebSockets pour l’indexation

Pour mettre à jour un index qui stocke tous les transferts de jetons, vous vous abonneriez à transactionSubscribe ainsi :

Commencez

Construire un index Solana robuste et compléter les données nécessite de résoudre trois défis principaux :
  1. Récupérer efficacement les données historiques
  2. Transformer et stocker les données pour des récupérations rapides
  3. Maintenir les données indexées de Solana à jour en temps réel
Avec notre nouveau système d’archivage à la pointe de la technologie, les appels d’archivage comme getTransactionsForAddress, et les solutions de streaming de données de pointe comme LaserStream, construire un index Solana est plus facile et plus pratique que jamais.

Options complémentaires

Gérer votre propre index vous donne un contrôle total, mais ce n’est pas toujours nécessaire. Pour des besoins communs, une API Helius gérée peut remplacer ou compléter un index personnalisé :
  • DAS API — interrogez les NFT, les jetons fongibles, et les actifs compressés (métadonnées, propriété, soldes, par propriétaire/collection/créateur) sans indexer vous-même les données des actifs.
  • Wallet API — points d’accès REST de haut niveau pour les soldes de portefeuille, l’historique, les transferts et l’identité, avec des valeurs USD et une structure de réponse simplifiée.
De nombreuses équipes utilisent celles-ci pour les données de portefeuille, de jeton et de portefeuille, et réservent un index personnalisé pour les données spécifiques que les API gérées ne couvrent pas.

Prochaines étapes