Vai al contenuto principale

The Graph: Risolvere l'interrogazione dei dati nel Web3

Solidity
smart contract
interrogazione
the graph
React
Intermedio
Markus Waas
6 settembre 2020
8 minuti di lettura

Questa volta daremo un'occhiata più da vicino a The Graph, che nell'ultimo anno è diventato essenzialmente parte dello stack standard per lo sviluppo di applicazioni decentralizzate (dapp). Vediamo prima come faremmo le cose nel modo tradizionale...

Senza The Graph...

Quindi procediamo con un semplice esempio a scopo illustrativo. A tutti piacciono i giochi, quindi immagina un semplice gioco in cui gli utenti piazzano scommesse:

Ora supponiamo che nella nostra dapp vogliamo mostrare le scommesse totali, il totale delle partite perse/vinte e anche aggiornarlo ogni volta che qualcuno gioca di nuovo. L'approccio sarebbe:

  1. Recuperare totalGamesPlayerWon.
  2. Recuperare totalGamesPlayerLost.
  3. Iscriversi agli eventi BetPlaced.

Possiamo ascoltare l'evento nel Web3 (opens in a new tab) come mostrato a destra, ma richiede la gestione di un bel po' di casi.

Ora, questo va ancora abbastanza bene per il nostro semplice esempio. Ma supponiamo di voler mostrare ora gli importi delle scommesse perse/vinte solo per il giocatore attuale. Beh, siamo sfortunati, faresti meglio a distribuire un nuovo contratto che memorizzi quei valori e li recuperi. E ora immagina uno smart contract e una dapp molto più complicati, le cose possono sfuggire di mano rapidamente.

One Does Not Simply Query

Puoi vedere come questo non sia ottimale:

  • Non funziona per i contratti già distribuiti.
  • Costi extra in gas per memorizzare quei valori.
  • Richiede un'altra chiamata per recuperare i dati per un nodo Ethereum.

Thats not good enough

Ora diamo un'occhiata a una soluzione migliore.

Lascia che ti presenti GraphQL

Prima parliamo di GraphQL, originariamente progettato e implementato da Facebook. Potresti avere familiarità con il modello tradizionale delle API REST. Ora immagina invece di poter scrivere un'interrogazione esattamente per i dati che desideri:

GraphQL API vs. REST API

Animated demonstration of a GraphQL query in The Graph playground

Le due immagini catturano praticamente l'essenza di GraphQL. Con l'interrogazione a destra possiamo definire esattamente quali dati vogliamo, in modo da ottenere tutto in una singola richiesta e niente di più di ciò di cui abbiamo esattamente bisogno. Un server GraphQL gestisce il recupero di tutti i dati richiesti, quindi è incredibilmente facile da usare per il lato consumatore del frontend. Questa è una bella spiegazione (opens in a new tab) di come esattamente il server gestisce un'interrogazione, se sei interessato.

Ora, con questa conoscenza, tuffiamoci finalmente nello spazio della blockchain e in The Graph.

Cos'è The Graph?

Una blockchain è un database decentralizzato, ma contrariamente a quanto accade di solito, non abbiamo un linguaggio di interrogazione per questo database. Le soluzioni per recuperare i dati sono dolorose o del tutto impossibili. The Graph è un protocollo decentralizzato per indicizzare e interrogare i dati della blockchain. E come potresti aver intuito, usa GraphQL come linguaggio di interrogazione.

The Graph

Gli esempi sono sempre il modo migliore per capire qualcosa, quindi usiamo The Graph per il nostro esempio GameContract.

Come creare un sottografo

La definizione di come indicizzare i dati è chiamata sottografo. Richiede tre componenti:

  1. Manifest (subgraph.yaml)
  2. Schema (schema.graphql)
  3. Mappatura (mapping.ts)

Manifest (subgraph.yaml)

Il manifest è il nostro file di configurazione e definisce:

  • quali smart contract indicizzare (indirizzo, rete, ABI...)
  • quali eventi ascoltare
  • altre cose da ascoltare come chiamate di funzione o blocchi
  • le funzioni di mappatura che vengono chiamate (vedi mapping.ts di seguito)

Qui puoi definire più contratti e gestori. Una configurazione tipica avrebbe una cartella del sottografo all'interno del progetto Hardhat con il proprio repository. In questo modo puoi facilmente fare riferimento all'ABI.

Per motivi di comodità potresti anche voler usare uno strumento di template come mustache. Quindi crei un subgraph.template.yaml e inserisci gli indirizzi in base alle ultime distribuzioni. Per un esempio di configurazione più avanzato, vedi ad esempio il repository del sottografo di Aave (opens in a new tab).

E la documentazione completa può essere consultata qui (opens in a new tab).

Schema (schema.graphql)

Lo schema è la definizione dei dati di GraphQL. Ti permetterà di definire quali entità esistono e i loro tipi. I tipi supportati da The Graph sono

  • Bytes
  • ID
  • String
  • Boolean
  • Int
  • BigInt
  • BigDecimal

Puoi anche usare le entità come tipo per definire le relazioni. Nel nostro esempio definiamo una relazione 1-a-molti dal giocatore alle scommesse. Il ! significa che il valore non può essere vuoto. La documentazione completa può essere consultata qui (opens in a new tab).

Mappatura (mapping.ts)

Il file di mappatura in The Graph definisce le nostre funzioni che trasformano gli eventi in entrata in entità. È scritto in AssemblyScript, un sottoinsieme di TypeScript. Questo significa che può essere compilato in WASM (WebAssembly) per un'esecuzione più efficiente e portabile della mappatura.

Dovrai definire ogni funzione nominata nel file subgraph.yaml, quindi nel nostro caso ne serve solo una: handleNewBet. Per prima cosa proviamo a caricare l'entità Player dall'indirizzo del mittente come id. Se non esiste, creiamo una nuova entità e la riempiamo con i valori iniziali.

Quindi creiamo una nuova entità Bet. L'id per questa sarà event.transaction.hash.toHex() + "-" + event.logIndex.toString() garantendo sempre un valore univoco. Usare solo l'hash non è sufficiente poiché qualcuno potrebbe chiamare la funzione placeBet più volte in una singola transazione tramite uno smart contract.

Infine possiamo aggiornare l'entità Player con tutti i dati. Gli array non possono essere inseriti direttamente, ma devono essere aggiornati come mostrato qui. Usiamo l'id per fare riferimento alla scommessa. E .save() è richiesto alla fine per memorizzare un'entità.

La documentazione completa può essere consultata qui: https://thegraph.com/docs/en/developing/creating-a-subgraph/#writing-mappings (opens in a new tab). Puoi anche aggiungere l'output di registrazione al file di mappatura, vedi qui (opens in a new tab).

Usarlo nel Frontend

Usando qualcosa come Apollo Boost, puoi facilmente integrare The Graph nella tua dapp React (o Apollo-Vue). Specialmente quando si usano gli hook di React e Apollo, recuperare i dati è semplice come scrivere una singola interrogazione GraphQL nel tuo componente. Una configurazione tipica potrebbe apparire così:

E ora possiamo scrivere ad esempio un'interrogazione come questa. Questa ci recupererà

  • quante volte l'utente attuale ha vinto
  • quante volte l'utente attuale ha perso
  • un elenco di timestamp con tutte le sue scommesse precedenti

Tutto in una singola richiesta al server GraphQL.

Magic

Ma ci manca un ultimo pezzo del puzzle e questo è il server. Puoi eseguirlo tu stesso o usare il servizio in hosting.

Il server di The Graph

Graph Explorer: Il servizio in hosting

Il modo più semplice è usare il servizio in hosting. Segui le istruzioni qui (opens in a new tab) per distribuire un sottografo. Per molti progetti puoi effettivamente trovare sottografi esistenti nell'explorer (opens in a new tab).

The Graph-Explorer

Eseguire il proprio nodo

In alternativa puoi eseguire il tuo nodo. La documentazione è qui (opens in a new tab). Un motivo per farlo potrebbe essere l'uso di una rete che non è supportata dal servizio in hosting. Le reti attualmente supportate possono essere trovate qui (opens in a new tab).

Il futuro decentralizzato

GraphQL supporta anche gli stream per i nuovi eventi in arrivo. Questi sono supportati su The Graph tramite i Substreams (opens in a new tab) che sono attualmente in open beta.

Nel 2021 (opens in a new tab) The Graph ha iniziato la sua transizione verso una rete di indicizzazione decentralizzata. Puoi leggere di più sull'architettura di questa rete di indicizzazione decentralizzata qui (opens in a new tab).

Due aspetti chiave sono:

  1. Gli utenti pagano gli indicizzatori per le interrogazioni.
  2. Gli indicizzatori mettono in staking i Graph Token (GRT).