8 minutes
Construction de subgraphs pour Arweave
La prise en charge d’Arweave dans Graph Node et dans Subgraph Studio est en beta : n’hésitez pas à nous contacter sur Discord pour toute question concernant la construction de subgraphs Arweave !
Dans ce guide, vous apprendrez comment créer et déployer des subgraphs pour indexer la blockchain Arweave.
Qu’est-ce qu’Arweave ?
Arweave est un protocole qui permet aux développeurs de stocker des données de façon permanente. C’est cette caractéristique qui constitue la principale différence entre Arweave et IPFS. En effet, IPFS n’a pas la caractéristique de permanence, et les fichiers stockés sur Arweave ne peuvent pas être modifiés ou supprimés.
Arweave a déjà construit de nombreuses bibliothèques pour intégrer le protocole dans plusieurs langages de programmation différents. Pour plus d’informations, vous pouvez consulter :
À quoi servent les subgraphs d’Arweave ?
The Graph vous permet de créer des API ouvertes personnalisées appelées “Subgraphs”. Les subgraphs sont utilisés pour indiquer aux Indexeurs (opérateurs de serveur) quelles données indexer sur une blockchain et enregistrer sur leurs serveurs afin que vous puissiez les interroger à tout moment à l’aide de GraphQL.
Graph Node est désormais capable d’indexer les données sur le protocole Arweave. L’intégration actuelle indexe uniquement Arweave en tant que blockchain (blocs et transactions), elle n’indexe pas encore les fichiers stockés.
Construire un subgraph Arweave
Pour pouvoir créer et déployer des Arweave Subgraphs, vous avez besoin de deux packages :
@graphprotocol/graph-cli
au-dessus de la version 0.30.2 - C’est un outil en ligne de commande pour construire et déployer des subgraphs. Cliquez ici pour le télécharger en utilisantnpm
.@graphprotocol/graph-ts
au-dessus de la version 0.27.0 - Il s’agit d’une bibliothèque de types spécifiques aux subgraphs. Cliquez ici pour télécharger en utilisantnpm
.
Caractéristique des subgraphs
Un subgraph se compose de trois éléments :
1. Le Manifest - subgraph.yaml
Définit les sources de données intéressantes et la manière dont elles doivent être traitées. Arweave est un nouveau type de source de données.
2. Schéma - schema.graphql
Vous définissez ici les données que vous souhaitez pouvoir interroger après avoir indexé votre subgraph à l’aide de GraphQL. Ceci est en fait similaire à un modèle pour une API, où le modèle définit la structure d’un corps de requête.
Les exigences relatives aux subgraphs Arweave sont couvertes par la documentation existante.
3. Mappages en AssemblyScript - mapping.ts
Il s’agit de la logique qui détermine comment les données doivent être récupérées et stockées lorsqu’une personne interagit avec les sources de données que vous interrogez. Les données sont traduites et stockées sur la base du schema que vous avez répertorié.
During Subgraph development there are two key commands:
1$ graph codegen # generates types from the schema file identified in the manifest2$ graph build # generates Web Assembly from the AssemblyScript files, and prepares all the Subgraph files in a /build folder
Définition du manifeste du subgraph
Le manifeste du subgraph subgraph.yaml
identifie les sources de données pour le subgraph, les déclencheurs intéressants et les fonctions qui doivent être exécutées en réponse à ces déclencheurs. Voir ci-dessous un exemple de manifeste de subgraph pour un subgraph Arweave :
1specVersion: 1.3.02description: Arweave Blocks Indexing3schema:4 file: ./schema.graphql # link to the schema file5dataSources:6 - kind: arweave7 name: arweave-blocks8 network: arweave-mainnet # The Graph only supports Arweave Mainnet9 source:10 owner: 'ID-OF-AN-OWNER' # The public key of an Arweave wallet11 startBlock: 0 # set this to 0 to start indexing from chain genesis12 mapping:13 apiVersion: 0.0.914 language: wasm/assemblyscript15 file: ./src/blocks.ts # link to the file with the Assemblyscript mappings16 entities:17 - Block18 - Transaction19 blockHandlers:20 - handler: handleBlock # the function name in the mapping file21 transactionHandlers:22 - handler: handleTx # the function name in the mapping file
- Les subgraphs Arweave introduisent un nouveau type de source de données (
arweave
) - Le réseau doit correspondre à un réseau sur le Graph Node hôte. Dans Subgraph Studio, le réseau principal d’Arweave est
arweave-mainnet
- Les sources de données Arweave introduisent un champ source.owner facultatif, qui est la clé publique d’un portefeuille Arweave
Les sources de données Arweave prennent en charge deux types de gestionnaires :
blockHandlers
- Exécuté sur chaque nouveau bloc Arweave. Aucun source.owner n’est requis.transactionHandlers
- Exécute chaque transaction dont le propriétaire estsource.owner
de la source de données. Actuellement, un propriétaire est requis pourtransactionHandlers
, si les utilisateurs veulent traiter toutes les transactions, ils doivent fournir "" commesource.owner
Source.owner peut être l’adresse du propriétaire ou sa clé publique.
Les transactions sont les éléments constitutifs du permaweb Arweave et ce sont des objets créés par les utilisateurs finaux.
Note : Les transactions Irys (anciennement Bundlr) ne sont pas encore prises en charge.
Définition de schéma
La définition du schéma décrit la structure de la base de données Subgraph résultante et les relations entre les entités. Elle est indépendante de la source de données d’origine. Vous trouverez plus de détails sur la définition du schéma du subgraph ici.
Cartographies AssemblyScript
Les gestionnaires d’événements sont écrits en AssemblyScript.
L’indexation Arweave introduit des types de données spécifiques à Arweave dans l’API AssemblyScript.
1class Block {2 timestamp: u643 lastRetarget: u644 height: u645 indepHash: Bytes6 nonce: Bytes7 previousBlock: Bytes8 diff: Bytes9 hash: Bytes10 txRoot: Bytes11 txs: Bytes[]12 walletList: Bytes13 rewardAddr: Bytes14 tags: Tag[]15 rewardPool: Bytes16 weaveSize: Bytes17 blockSize: Bytes18 cumulativeDiff: Bytes19 hashListMerkle: Bytes20 poa: ProofOfAccess21}2223class Transaction {24 format: u3225 id: Bytes26 lastTx: Bytes27 owner: Bytes28 tags: Tag[]29 target: Bytes30 quantity: Bytes31 data: Bytes32 dataSize: Bytes33 dataRoot: Bytes34 signature: Bytes35 reward: Bytes36}
Les gestionnaires de blocs reçoivent un Block
, tandis que les transactions reçoivent un Transaction
.
L’écriture des mappages d’un subgraph Arweave est très similaire à l’écriture des mappages d’un subgraph Ethereum. Pour plus d’informations, cliquez ici.
Déploiement d’un subgraph Arweave dans Subgraph Studio
Une fois que votre subgraph a été créé sur le tableau de bord de Subgraph Studio, vous pouvez le déployer en utilisant la commande CLI graph deploy
.
1graph deploy --access-token <votre-token-d-acces>
Interroger un subgraph d’Arweave
L’Endpoint GraphQL pour les subgraphs Arweave est déterminé par la définition du schéma, avec l’interface API existante. Veuillez consulter la documentation API GraphQL pour plus d’informations.
Exemples de subgraphs
Voici un exemple de subgraph à titre de référence :
FAQ
Un subgraph peut-il indexer Arweave et d’autres blockchains ?
No, a Subgraph can only support data sources from one chain/network.
Puis-je indexer les fichiers enregistrés sur Arweave ?
Actuellement, The Graph n’indexe Arweave qu’en tant que blockchain (ses blocs et ses transactions).
Puis-je identifier les packages de Bundlr dans mon subgraph ?
Cette fonction n’est pas prise en charge actuellement.
Comment puis-je filtrer les transactions sur un compte spécifique ?
La source.owner peut être la clé publique de l’utilisateur ou l’adresse de son compte.
Quel est le format de chiffrement actuel ?
Les données sont généralement passées dans les mappages sous forme de Bytes, qui, s’ils sont stockés directement, sont renvoyés dans le subgraph dans un format hex
(par exemple, les hash de blocs et de transactions). Vous pouvez vouloir convertir en un format base64
ou base64 URL
dans vos mappages, afin de correspondre à ce qui est affiché dans les explorateurs de blocs comme Arweave Explorer.
La fonction d’assistant bytesToBase64(bytes : Uint8Array, urlSafe : boolean) : string
suivante peut être utilisée, et sera ajoutée à graph-ts
:
1const base64Alphabet = [2 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",3 "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",4 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",5 "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",6 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"7];89const base64UrlAlphabet = [10 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",11 "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",12 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",13 "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",14 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "_"15];1617function bytesToBase64(bytes: Uint8Array, urlSafe: boolean): string {18 let alphabet = urlSafe? base64UrlAlphabet : base64Alphabet;1920 let result = '', i: i32, l = bytes.length;21 for (i = 2; i < l; i += 3) {22 result += alphabet[bytes[i - 2] >> 2];23 result += alphabet[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];24 result += alphabet[((bytes[i - 1] & 0x0F) << 2) | (bytes[i] >> 6)];25 result += alphabet[bytes[i] & 0x3F];26 }27 if (i === l + 1) { // 1 octet à écrire28 result += alphabet[bytes[i - 2] >> 2];29 result += alphabet[(bytes[i - 2] & 0x03) << 4];30 if (!urlSafe) {31 result += "==";32 }33 }34 if (!urlSafe && i === l) { // 2 octets à écrire35 result += alphabet[bytes[i - 2] >> 2];36 result += alphabet[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];37 result += alphabet[(bytes[i - 1] & 0x0F) << 2];38 if (!urlSafe) {39 result += "=";40 }41 }42 return result;43}