Docs
Cerca⌘ K
  • Home
  • Informazioni su The Graph
  • Supported Networks
  • Protocol Contracts
  • Subgraphs
    • Substreams
      • Token API
        • AI Suite
          • Indexing
            • Resources
              Subgraphs > Developing > Creating > API AssemblyScript

              20 minutes

              API AssemblyScript

              Note: If you created a Subgraph prior to graph-cli/graph-ts version 0.22.0, then you’re using an older version of AssemblyScript. It is recommended to review the Migration Guide.

              Learn what built-in APIs can be used when writing Subgraph mappings. There are two kinds of APIs available out of the box:

              • The Graph TypeScript library⁠ (graph-ts)
              • Code generated from Subgraph files by graph codegen

              You can also add other libraries as dependencies, as long as they are compatible with AssemblyScript⁠.

              Since language mappings are written in AssemblyScript, it is useful to review the language and standard library features from the AssemblyScript wiki⁠.

              Riferimento API

              La libreria @graphprotocol/graph-ts fornisce le seguenti API:

              • Un’API ethereum per lavorare con gli smart contract di Ethereum, gli eventi, i blocchi, le transazioni e i valori di Ethereum.
              • Un’API store per caricare e salvare entità da e verso il Graph Node store.
              • A log API to log messages to the Graph Node output and Graph Explorer.
              • Un’API ipfs per caricare i file da IPFS.
              • Un’API json per analizzare i dati JSON.
              • Un’API crypto per utilizzare le funzioni crittografiche.
              • Primitive di basso livello per tradurre tra diversi sistemi di tipi come Ethereum, JSON, GraphQL e AssemblyScript.

              Versioni

              The apiVersion in the Subgraph manifest specifies the mapping API version which is run by Graph Node for a given Subgraph.

              VersioneNote di rilascio
              0.0.9Adds new host functions eth_get_balance & hasCode
              0.0.8Adds validation for existence of fields in the schema when saving an entity.
              0.0.7Aggiunte le classi TransactionReceipt e Log ai tipi di Ethereum
              Aggiunto il campo receipt all’oggetto Ethereum Event
              0.0.6Aggiunto il campo nonce all’oggetto Ethereum Transaction
              Aggiunto baseFeePerGas all’oggetto Ethereum Block
              0.0.5AssemblyScript upgraded to version 0.19.10 (this includes breaking changes, please see the Migration Guide)
              ethereum.transaction.gasUsed renamed to ethereum.transaction.gasLimit
              0.0.4Aggiunto il campo functionSignature all’oggetto Ethereum SmartContractCall
              0.0.3Added from field to the Ethereum Call object
              ethereum.call.address renamed to ethereum.call.to
              0.0.2Aggiunto il campo input all’oggetto Ethereum Transaction

              Tipi integrati

              Documentation on the base types built into AssemblyScript can be found in the AssemblyScript wiki⁠.

              I seguenti tipi aggiuntivi sono forniti da @graphprotocol/graph-ts.

              ByteArray

              1importare { ByteArray } da '@graphprotocol/graph-ts'

              ByteArray rappresenta un array di u8.

              Construction

              • fromI32(x: i32): ByteArray - Decompone x in byte.
              • fromHexString(hex: string): ByteArray - La lunghezza dell’input deve essere pari. Il prefisso 0x è facoltativo.

              Type conversions

              • toHexString(): string - Converte in una stringa esadecimale con prefisso 0x.
              • toString(): string - Interpreta i byte come una string UTF-8.
              • toBase58(): string - Codifica i byte in una stringa base58.
              • toU32(): u32 - Interpreta i byte come un u32 little-endian. Viene lanciata in caso di overflow.
              • toI32(): i32 - Interpreta l’array di byte come un i32 little-endian. Viene lanciata in caso di overflow.

              Operators

              • equals(y: ByteArray): bool- può essere scritto comex == y`.
              • concat(other: ByteArray) : ByteArray - restituisce un nuovo ByteArray costituito da this direttamente seguito da other
              • concatI32(other: i32) : ByteArray - restituisce un nuovo ByteArray costituito da this direttamente seguito dalla rappresentazione in byte di other

              BigDecimal

              1import { BigDecimal } from '@graphprotocol/graph-ts'

              BigDecimal è usato per rappresentare decimali di precisione arbitraria.

              Note: Internally⁠ BigDecimal is stored in IEEE-754 decimal128 floating-point format⁠, which supports 34 decimal digits of significand. This makes BigDecimal unsuitable for representing fixed-point types that can span wider than 34 digits, such as a Solidity ufixed256x18⁠ or equivalent.

              Construction

              • constructor(bigInt: BigInt) - crea un BigDecimal da un BigInt.
              • static fromString(s: string): BigDecimal - analizza una stringa decimale.

              Type conversions

              • toString(): string - stampa una stringa decimale.

              Math

              • plus(y: BigDecimal): BigDecimal - può essere scritto come x + y.
              • minus(y: BigDecimal): BigDecimal - può essere scritto come x - y.
              • times(y: BigDecimal): BigDecimal - può essere scritto come x * y.
              • div(y: BigDecimal): BigDecimal - può essere scritto come x / y.
              • equals(y: BigDecimal): bool - può essere scritto come x == y.
              • notEqual(y: BigDecimal): bool - può essere scritto come x != y.
              • lt(y: BigDecimal): bool – può essere scritto come x < y.
              • le(y: BigDecimal): bool – può essere scritto come x <= y.
              • gt(y: BigDecimal): bool – può essere scritto come x > y.
              • ge(y: BigDecimal): bool – può essere scritto come x >= y.
              • neg(): BigDecimal - può essere scritto come -x.

              BigInt

              1import { BigInt } from '@graphprotocol/graph-ts'

              BigInt è usato per rappresentare i grandi numeri interi. Questo include i valori Ethereum di tipo da uint32 a uint256 e da int64 a int256. Tutto ciò che è inferiore a uint32, come int32, uint24 o int8 è rappresentato come i32.

              La classe BigInt ha la seguente API:

              Construction

              • BigInt.fromI32(x: i32): BigInt - crea un BigInt da un i32.

              • BigInt.fromString(s: string): BigInt- Analizza un BigInt da una stringa.

              • BigInt.fromUnsignedBytes(x: Bytes): BigInt - Interpreta bytes come un intero senza segno, little-endian. Se l’input è big-endian, chiamare prima .reverse().

              • BigInt.fromSignedBytes(x: Bytes): BigInt - Interpreta bytes come un intero firmato, little-endian. Se l’input è big-endian, chiamare prima .reverse().

                Type conversions

              • x.toHex(): string - trasforma BigInt in una stringa di caratteri esadecimali.

              • x.toString(): string - trasforma BigInt in una stringa di numeri decimali.

              • x.toI32(): i32 - restituisce il BigInt come i32; fallisce se il valore non entra in i32. È una buona idea controllare prima x.isI32().

              • x.toBigDecimal(): BigDecimal - converte in un decimale senza parti frazionarie.

              Math

              • x.plus(y: BigInt): BigInt - può essere scritto come x + y.
              • x.minus(y: BigInt): BigInt - può essere scritto come x - y.
              • x.times(y: BigInt): BigInt - può essere scritto come x * y.
              • x.div(y: BigInt): BigInt - può essere scritto come x / y.
              • x.mod(y: BigInt): BigInt - può essere scritto come x % y.
              • x.equals(y: BigInt): bool - può essere scritto come x == y.
              • x.notEqual(y: BigInt): bool - può essere scritto come x != y.
              • x.lt(y: BigInt): bool - può essere scritto come x < y.
              • x.le(y: BigInt): bool - può essere scritto come x <= y.
              • x.gt(y: BigInt): bool - può essere scritto come x > y.
              • x.ge(y: BigInt): bool - può essere scritto come x >= y.
              • x.neg(): BigInt - può essere scritto come -x.
              • x.divDecimal(y: BigDecimal): BigDecimal - divide per un decimale, dando un risultato decimale.
              • x.isZero(): bool - Conviene prima verificare se il numero è zero.
              • x.isI32(): bool - Controlla se il numero è compreso in un i32.
              • x.abs(): BigInt - Valore assoluto.
              • x.pow(exp: u8): BigInt - Esponenziale.
              • bitOr(x: BigInt, y: BigInt): BigInt - può essere scritto come x | y.
              • bitAnd(x: BigInt, y: BigInt): BigInt - può essere scritto come x & y.
              • leftShift(x: BigInt, bits: u8): BigInt - può essere scritto come x << y.
              • rightShift(x: BigInt, bits: u8): BigInt - può essere scritto come x >> y.

              TypedMap

              1import { TypedMap } from '@graphprotocol/graph-ts'

              TypedMap può essere usato per memorizzare coppie key-value. Vedere [questo esempio] (https://github.com/graphprotocol/aragon-subgraph/blob/29dd38680c5e5104d9fdc2f90e740298c67e4a31/individual-dao-subgraph/mappings/constants.ts#L51⁠).

              La classe TypedMap ha la seguente API:

              • new TypedMap<K, V>() - crea una mappa vuota con chiavi di tipo K e valori di tipo V
              • map.set(chiave: K, valore: V): void - imposta il valore di chiave su valore
              • map.getEntry(key: K): TypedMapEntry<K, V> | null - restituisce la coppia key-value per una key o null se la key non esiste nella mappa
              • map.get(chiave: K): V | null - restituisce il valore di una chiave o null se la chiave non esiste nella mappa
              • map.isSet(key: K): bool - restituisce true se la key esiste nella mappa e false se non esiste

              Bytes

              1import { Bytes } from '@graphprotocol/graph-ts'

              Bytes è usato per rappresentare array di byte di lunghezza arbitraria. Questo include i valori Ethereum di tipo bytes, bytes32, ecc.

              La classe Bytes estende Uint8Array⁠ di AssemblyScript e supporta tutte le funzionalità di Uint8Array, oltre ai seguenti nuovi metodi:

              Construction

              • fromHexString(hex: string) : Bytes - Converte la stringa hex, che deve essere composta da un numero pari di cifre esadecimali, in un ByteArray. La stringa hex può facoltativamente iniziare con 0x
              • fromI32(i: i32) : Bytes - Converte i in un array di byte

              Type conversions

              • b.toHex() - restituisce una stringa esadecimale che rappresenta i byte nell’array
              • b.toString() - converte i byte dell’array in una stringa di caratteri unicode
              • b.toBase58() - trasforma un valore Ethereum Bytes in una codifica base58 (usata per gli hash IPFS)

              Operators

              • b.concat(other: Bytes) : Bytes - - restituisce nuovi Bytes costituiti da this direttamente seguito da other
              • b.concatI32(other: i32) : ByteArray - restituisce nuovi Byte costituiti da this direttamente seguito dalla rappresentazione in byte di other

              Address

              1import { Address } from '@graphprotocol/graph-ts'

              Address estende Bytes per rappresentare i valori di address di Ethereum.

              Aggiunge il seguente metodo all’API Bytes:

              • Address.fromString(s: string): Address - crea un Address a partire da una stringa esadecimale
              • Address.fromBytes(b: Bytes): Address - crea un Address da b che deve essere lungo esattamente 20 byte. Se si passa un valore con un numero di byte inferiore o superiore, risulterà in un errore

              Store API

              1import { store } from '@graphprotocol/graph-ts'

              L’API store consente di caricare, salvare e rimuovere entità da e verso il Graph Node store.

              Entities written to the store map one-to-one to the @entity types defined in the Subgraph’s GraphQL schema. To make working with these entities convenient, the graph codegen command provided by the Graph CLI⁠ generates entity classes, which are subclasses of the built-in Entity type, with property getters and setters for the fields in the schema as well as methods to load and save these entities.

              Creazione di entità

              Quello che segue è un modello comune per la creazione di entità a partire da eventi Ethereum.

              1// Import the Transfer event class generated from the ERC20 ABI2import { Transfer as TransferEvent } from '../generated/ERC20/ERC20'34// Import the Transfer entity type generated from the GraphQL schema5import { Transfer } from '../generated/schema'67// Transfer event handler8export function handleTransfer(event: TransferEvent): void {9  // Create a Transfer entity, using the transaction hash as the entity ID10  let id = event.transaction.hash11  let transfer = new Transfer(id)1213  // Set properties on the entity, using the event parameters14  transfer.from = event.params.from15  transfer.to = event.params.to16  transfer.amount = event.params.amount1718  // Save the entity to the store19  transfer.save()20}

              Quando un evento Transfer viene incontrato durante l’elaborazione della chain, viene passato al gestore dell’evento handleTransfer usando il tipo Transfer generato (qui alias TransferEvent per evitare un conflitto di nomi con il tipo di entità). Questo tipo consente di accedere a dati quali la transazione genitore dell’evento e i suoi parametri.

              Each entity must have a unique ID to avoid collisions with other entities. It is fairly common for event parameters to include a unique identifier that can be used.

              Note: Using the transaction hash as the ID assumes that no other events in the same transaction create entities with this hash as the ID.

              Caricare le entità dallo store

              Se un’entità esiste già, può essere caricata dall’archivio con la seguente procedura:

              1let id = event.transaction.hash // or however the ID is constructed2let transfer = Transfer.load(id)3if (transfer == null) {4  transfer = new Transfer(id)5}67// Use the Transfer entity as before

              As the entity may not exist in the store yet, the load method returns a value of type Transfer | null. It may be necessary to check for the null case before using the value.

              Note: Loading entities is only necessary if the changes made in the mapping depend on the previous data of an entity. See the next section for the two ways of updating existing entities.

              Ricerca delle entità create all’interno di un blocco

              A partire da graph-node v0.31.0, @graphprotocol/graph-ts v0.30.0 e @graphprotocol/graph-cli v0.49.0 il metodo loadInBlock è disponibile per tutti i tipi di entità.

              The store API facilitates the retrieval of entities that were created or updated in the current block. A typical situation for this is that one handler creates a transaction from some onchain event, and a later handler wants to access this transaction if it exists.

              • In the case where the transaction does not exist, the Subgraph will have to go to the database simply to find out that the entity does not exist. If the Subgraph author already knows that the entity must have been created in the same block, using loadInBlock avoids this database roundtrip.
              • For some Subgraphs, these missed lookups can contribute significantly to the indexing time.
              1let id = event.transaction.hash // or however the ID is constructed2let transfer = Transfer.loadInBlock(id)3if (transfer == null) {4  transfer = new Transfer(id)5}67// Use the Transfer entity as before

              Nota: Se non esiste un’entità creata nel blocco dato, loadInBlock restituirà null anche se esiste un’entità con l’ID dato nel negozio.

              Ricerca di entità derivate

              A partire da graph-node v0.31.0, @graphprotocol/graph-ts v0.31.0 e @graphprotocol/graph-cli v0.51.0 è disponibile il metodo loadRelated.

              Ciò consente di caricare i campi entità derivati da un gestore di eventi. Per esempio, dato il seguente schema:

              1type Token @entity {2  id: ID!3  holder: Holder!4  color: String5}67type Holder @entity {8  id: ID!9  tokens: [Token!]! @derivedFrom(field: "holder")10}

              Il codice seguente carica l’entità Token da cui è derivata l’entità Holder:

              1let holder = Holder.load('test-id')2// Load the Token entities associated with a given holder3let tokens = holder.tokens.load()

              Aggiornamento di entità esistenti

              Esistono due modi per aggiornare un’entità esistente:

              1. Caricare l’entità con, ad esempio, Transfer.load(id), impostare le proprietà sull’entità, quindi .save() riportarla in archivio.
              2. È sufficiente creare l’entità con, ad esempio, new Transfer(id), impostare le proprietà sull’entità e quindi .save() nel negozio. Se l’entità esiste già, le modifiche vengono unite ad essa.

              La modifica delle proprietà è semplice nella maggior parte dei casi, grazie ai setter di proprietà generati:

              1let transfer = new Transfer(id)2transfer.from = ...3transfer.to = ...4transfer.amount = ...

              È anche possibile disattivare le proprietà con una delle due istruzioni seguenti:

              1transfer.from.unset()2transfer.from = null

              Questo funziona solo con le proprietà opzionali, cioè quelle dichiarate senza un ! in GraphQL. Due esempi potrebbero essere owner: Bytes o amount: BigInt.

              L’aggiornamento delle proprietà degli array è un po’ più complicato, poiché l’ottenimento di un array da un’entità crea una copia di tale array. Ciò significa che le proprietà dell’array devono essere impostate di nuovo in modo esplicito dopo aver modificato l’array. Quanto segue presuppone che l’entità abbia un campo numbers: [BigInt!]!.

              1// This won't work2entity.numbers.push(BigInt.fromI32(1))3entity.save()45// This will work6let numbers = entity.numbers7numbers.push(BigInt.fromI32(1))8entity.numbers = numbers9entity.save()

              Rimozione di entità dal negozio

              Attualmente non c’è modo di rimuovere un’entità tramite i tipi generati. Per rimuovere un’entità è necessario passare il nome del tipo di entità e l’ID dell’entità a store.remove:

              1import { store } from '@graphprotocol/graph-ts'2...3let id = event.transaction.hash4store.remove('Transfer', id)

              API Ethereum

              L’API di Ethereum fornisce l’accesso agli smart contract, alle variabili di stato pubbliche, alle funzioni dei contratti, agli eventi, alle transazioni, ai blocchi e alla codifica/decodifica dei dati di Ethereum.

              Supporto per i tipi di Ethereum

              As with entities, graph codegen generates classes for all smart contracts and events used in a Subgraph. For this, the contract ABIs need to be part of the data source in the Subgraph manifest. Typically, the ABI files are stored in an abis/ folder.

              With the generated classes, conversions between Ethereum types and the built-in types take place behind the scenes so that Subgraph authors do not have to worry about them.

              The following example illustrates this. Given a Subgraph schema like

              1type Transfer @entity {2  id: Bytes!3  from: Bytes!4  to: Bytes!5  amount: BigInt!6}

              e una firma di evento Transfer(address,address,uint256) su Ethereum, i valori from, to e amount di tipo address, address e uint256 sono convertiti in Address e BigInt, consentendo di passarli alle proprietà Bytes! e BigInt! dell’entità Transfer:

              1let id = event.transaction.hash2let transfer = new Transfer(id)3transfer.from = event.params.from4transfer.to = event.params.to5transfer.amount = event.params.amount6transfer.save()

              Eventi e dati di blocco/transazione

              Gli eventi di Ethereum passati ai gestori di eventi, come l’evento Transfer negli esempi precedenti, non solo forniscono accesso ai parametri dell’evento, ma anche alla transazione genitore e al blocco di cui fanno parte. I seguenti dati possono essere ottenuti dalle istanze di event (queste classi fanno parte del modulo ethereum di graph-ts):

              1class Event {2  address: Address3  logIndex: BigInt4  transactionLogIndex: BigInt5  logType: string | null6  block: Block7  transaction: Transaction8  parameters: Array<EventParam>9  receipt: TransactionReceipt | null10}1112class Block {13  hash: Bytes14  parentHash: Bytes15  unclesHash: Bytes16  author: Address17  stateRoot: Bytes18  transactionsRoot: Bytes19  receiptsRoot: Bytes20  number: BigInt21  gasUsed: BigInt22  gasLimit: BigInt23  timestamp: BigInt24  difficulty: BigInt25  totalDifficulty: BigInt26  size: BigInt | null27  baseFeePerGas: BigInt | null28}2930class Transaction {31  hash: Bytes32  index: BigInt33  from: Address34  to: Address | null35  value: BigInt36  gasLimit: BigInt37  gasPrice: BigInt38  input: Bytes39  nonce: BigInt40}4142class TransactionReceipt {43  transactionHash: Bytes44  transactionIndex: BigInt45  blockHash: Bytes46  blockNumber: BigInt47  cumulativeGasUsed: BigInt48  gasUsed: BigInt49  contractAddress: Address50  logs: Array<Log>51  status: BigInt52  root: Bytes53  logsBloom: Bytes54}5556class Log {57  address: Address58  topics: Array<Bytes>59  data: Bytes60  blockHash: Bytes61  blockNumber: Bytes62  transactionHash: Bytes63  transactionIndex: BigInt64  logIndex: BigInt65  transactionLogIndex: BigInt66  logType: string67  removed: bool | null68}

              Accesso allo stato dello smart contract

              The code generated by graph codegen also includes classes for the smart contracts used in the Subgraph. These can be used to access public state variables and call functions of the contract at the current block.

              Un modello comune è quello di accedere al contratto da cui proviene un evento. Questo si ottiene con il seguente codice:

              1// Import the generated contract class and generated Transfer event class2import { ERC20Contract, Transfer as TransferEvent } from '../generated/ERC20Contract/ERC20Contract'3// Import the generated entity class4import { Transfer } from '../generated/schema'56export function handleTransfer(event: TransferEvent) {7  // Bind the contract to the address that emitted the event8  let contract = ERC20Contract.bind(event.address)910  // Access state variables and functions by calling them11  let erc20Symbol = contract.symbol()12}

              Transfer è alias di TransferEvent qui per evitare un conflitto di nomi con il tipo di entità

              Finché il ERC20Contract su Ethereum ha una funzione pubblica di sola lettura chiamata symbol, questa può essere chiamata con .symbol(). Per le variabili di stato pubbliche viene creato automaticamente un metodo con lo stesso nome.

              Any other contract that is part of the Subgraph can be imported from the generated code and can be bound to a valid address.

              Gestione delle chiamate annullate

              If the read-only methods of your contract may revert, then you should handle that by calling the generated contract method prefixed with try_.

              • For example, the Gravity contract exposes the gravatarToOwner method. This code would be able to handle a revert in that method:
              1let gravity = Gravity.bind(event.address)2let callResult = gravity.try_gravatarToOwner(gravatar)3if (callResult.reverted) {4  log.info('getGravatar reverted', [])5} else {6  let owner = callResult.value7}

              Note: A Graph node connected to a Geth or Infura client may not detect all reverts. If you rely on this, we recommend using a Graph Node connected to a Parity client.

              Codifica/decodifica ABI

              I dati possono essere codificati e decodificati secondo il formato di codifica ABI di Ethereum utilizzando le funzioni encode e decode del modulo ethereum.

              1import { Address, BigInt, ethereum } from '@graphprotocol/graph-ts'23let tupleArray: Array<ethereum.Value> = [4  ethereum.Value.fromAddress(Address.fromString('0x0000000000000000000000000000000000000420')),5  ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(62)),6]78let tuple = tupleArray as ethereum.Tuple910let encoded = ethereum.encode(ethereum.Value.fromTuple(tuple))!1112let decoded = ethereum.decode('(address,uint256)', encoded)

              Per maggiori informazioni:

              • ABI Spec⁠
              • Codifica/decodifica libreria Rust/CLI⁠
              • More complex example⁠.

              Balance of an Address

              The native token balance of an address can be retrieved using the ethereum module. This feature is available from apiVersion: 0.0.9 which is defined subgraph.yaml. The getBalance() retrieves the balance of the specified address as of the end of the block in which the event is triggered.

              1import { ethereum } from '@graphprotocol/graph-ts'23let address = Address.fromString('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')4let balance = ethereum.getBalance(address) // returns balance in BigInt

              Check if an Address is a Contract or EOA

              To check whether an address is a smart contract address or an externally owned address (EOA), use the hasCode() function from the ethereum module which will return boolean. This feature is available from apiVersion: 0.0.9 which is defined subgraph.yaml.

              1import { ethereum } from '@graphprotocol/graph-ts'23let contractAddr = Address.fromString('0x2E645469f354BB4F5c8a05B3b30A929361cf77eC')4let isContract = ethereum.hasCode(contractAddr).inner // returns true56let eoa = Address.fromString('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')7let isContract = ethereum.hasCode(eoa).inner // returns false

              API di registrazione

              1import { log } from '@graphprotocol/graph-ts'

              The log API allows Subgraphs to log information to the Graph Node standard output as well as Graph Explorer. Messages can be logged using different log levels. A basic format string syntax is provided to compose log messages from argument.

              L’API log include le seguenti funzioni:

              • log.debug(fmt: string, args: Array<string>): void - registra un messaggio di debug.
              • log.info(fmt: string, args: Array<string>): void - registra un messaggio informativo.
              • log.warning(fmt: string, args: Array<string>): void - registra un avviso.
              • log.error(fmt: string, args: Array<string>): void - registra un messaggio di errore.
              • log.critical(fmt: string, args: Array<string>): void – logs a critical message and terminates the Subgraph.

              L’API log accetta una stringa di formato e un array di valori stringa. Quindi sostituisce i segnaposto con i valori stringa dell’array. Il primo segnaposto {} viene sostituito dal primo valore dell’array, il secondo segnaposto {} viene sostituito dal secondo valore e così via.

              1log.info('Message to be displayed: {}, {}, {}', [value.toString(), anotherValue.toString(), 'already a string'])

              Registrazione di uno o più valori

              Registrazione di un singolo valore

              Nell’esempio seguente, il valore stringa “A” viene passato in un array per diventare ['A'] prima di essere registrato:

              1let myValue = 'A'23export function handleSomeEvent(event: SomeEvent): void {4  // Displays : "My value is: A"5  log.info('My value is: {}', [myValue])6}
              Registrazione di una singola voce da un array esistente

              Nell’esempio seguente, viene registrato solo il primo valore dell’array di argomenti, nonostante l’array contenga tre valori.

              1let myArray = ['A', 'B', 'C']23export function handleSomeEvent(event: SomeEvent): void {4  // Displays : "My value is: A"  (Even though three values are passed to `log.info`)5  log.info('My value is: {}', myArray)6}

              Registrazione di più voci da una matrice esistente

              Ogni voce dell’array di argomenti richiede il proprio segnaposto {} nella stringa del messaggio di log. L’esempio seguente contiene tre segnaposto {} nel messaggio di log. Per questo motivo, tutti e tre i valori di myArray vengono registrati.

              1let myArray = ['A', 'B', 'C']23export function handleSomeEvent(event: SomeEvent): void {4  // Displays : "My first value is: A, second value is: B, third value is: C"5  log.info('My first value is: {}, second value is: {}, third value is: {}', myArray)6}
              Registrazione di una voce specifica da un array esistente

              Per visualizzare un valore specifico della matrice, è necessario fornire il valore indicizzato.

              1export function handleSomeEvent(event: SomeEvent): void {2  // Displays : "My third value is C"3  log.info('My third value is: {}', [myArray[2]])4}
              Registrazione delle informazioni sugli eventi

              L’esempio seguente registra il numero di blocco, l’hash del blocco e l’hash della transazione di un evento:

              1import { log } from '@graphprotocol/graph-ts'23export function handleSomeEvent(event: SomeEvent): void {4  log.debug('Block number: {}, block hash: {}, transaction hash: {}', [5    event.block.number.toString(), // "47596000"6    event.block.hash.toHexString(), // "0x..."7    event.transaction.hash.toHexString(), // "0x..."8  ])9}

              IPFS API

              1import { ipfs } from '@graphprotocol/graph-ts'

              Smart contracts occasionally anchor IPFS files onchain. This allows mappings to obtain the IPFS hashes from the contract and read the corresponding files from IPFS. The file data will be returned as Bytes, which usually requires further processing, e.g. with the json API documented later on this page.

              Dato un hash o un percorso IPFS, la lettura di un file da IPFS avviene come segue:

              1// Put this inside an event handler in the mapping2let hash = 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D'3let data = ipfs.cat(hash)45// Paths like `QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/Makefile`6// that include files in directories are also supported7let path = 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/Makefile'8let data = ipfs.cat(path)

              Nota: ipfs.cat non è deterministico al momento. Se il file non può essere recuperato attraverso la rete IPFS prima che la richiesta si esaurisca, restituirà null. Per questo motivo, vale sempre la pena di controllare che il risultato non sia null.

              È anche possibile elaborare file di dimensioni maggiori in modo streaming con ipfs.map. La funzione si aspetta l’hash o il percorso di un file IPFS, il nome di un callback e i flag per modificare il suo comportamento:

              1import { JSONValue, Value } from '@graphprotocol/graph-ts'23export function processItem(value: JSONValue, userData: Value): void {4  // See the JSONValue documentation for details on dealing5  // with JSON values6  let obj = value.toObject()7  let id = obj.get('id')8  let title = obj.get('title')910  if (!id || !title) {11    return12  }1314  // Callbacks can also created entities15  let newItem = new Item(id)16  newItem.title = title.toString()17  newitem.parent = userData.toString() // Set parent to "parentId"18  newitem.save()19}2021// Put this inside an event handler in the mapping22ipfs.map('Qm...', 'processItem', Value.fromString('parentId'), ['json'])2324// Alternatively, use `ipfs.mapJSON`25ipfs.mapJSON('Qm...', 'processItem', Value.fromString('parentId'))

              L’unico flag attualmente supportato è json, che deve essere passato a ipfs.map. Con il flag json, il file IPFS deve essere costituito da una serie di valori JSON, un valore per riga. La chiamata a ipfs.map leggerà ogni riga del file, la deserializzerà in un JSONValue e chiamerà il callback per ognuno di essi. Il callback può quindi utilizzare le operazioni sulle entità per memorizzare i dati dal JSONValue. Le modifiche alle entità vengono memorizzate solo quando il gestore che ha chiamato ipfs.map termina con successo; nel frattempo, vengono mantenute in memoria e la dimensione del file che ipfs.map può elaborare è quindi limitata.

              On success, ipfs.map returns void. If any invocation of the callback causes an error, the handler that invoked ipfs.map is aborted, and the Subgraph is marked as failed.

              Crypto API

              1import { crypto } from '@graphprotocol/graph-ts'

              L’API crypto rende disponibili funzioni crittografiche da usare nelle mappature. Al momento, ce n’è solo una:

              • crypto.keccak256(input: ByteArray): ByteArray

              JSON API

              1import { json, JSONValueKind } from '@graphprotocol/graph-ts'

              I dati JSON possono essere analizzati utilizzando l’API json:

              • json.fromBytes(data: Bytes): JSONValue - analizza i dati JSON da un array di Bytes interpretati come una sequenza UTF-8 valida
              • json.try_fromBytes(data: Bytes): Result<JSONValue, boolean> - versione sicura di json.fromBytes, restituisce una variante di errore se il parsing è fallito
              • json.fromString(data: string): JSONValue - analizza i dati JSON da una string UTF-8 valida
              • json.try_fromString(data: string): Result<JSONValue, boolean> - versione sicura di json.fromString, restituisce una variante di errore se il parsing è fallito

              La classe JSONValue fornisce un modo per estrarre valori da un documento JSON arbitrario. Poiché i valori JSON possono essere booleani, numeri, array e altro, JSONValue è dotato di una proprietà kind per verificare il tipo di valore:

              1let value = json.fromBytes(...)2if (value.kind == JSONValueKind.BOOL) {3  ...4}

              Inoltre, esiste un metodo per verificare se il valore è null:

              • value.isNull(): boolean

              Quando il tipo di un valore è certo, può essere convertito in un tipo incorporato usando uno dei seguenti metodi:

              • value.toBool(): boolean
              • value.toI64(): i64
              • value.toF64(): f64
              • value.toBigInt(): BigInt
              • value.toString(): string
              • value.toArray(): Array<JSONValue> - (e poi convertire JSONValue con uno dei 5 metodi precedenti)

              Riferimento alle conversioni di tipo

              Fonte(i)DestinazioneFunzione di conversione
              AddressBytesnone
              AddressStrings.toHexString()
              BigDecimalStrings.toString()
              BigIntBigDecimals.toBigDecimal()
              BigIntString (hexadecimal)s.toHexString() o s.toHex()
              BigIntString (unicode)s.toString()
              BigInti32s.toI32()
              BooleanBooleannone
              Bytes (signed)BigIntBigInt.fromSignedBytes(s)
              Bytes (unsigned)BigIntBigInt.fromUnsignedBytes(s)
              BytesString (hexadecimal)s.toHexString() o s.toHex()
              BytesString (unicode)s.toString()
              BytesString (base58)s.toBase58()
              Bytesi32s.toI32()
              Bytesu32s.toU32()
              BytesJSONjson.fromBytes(s)
              int8i32none
              int32i32none
              int32BigIntBigInt.fromI32(s)
              uint24i32none
              int64 - int256BigIntnone
              uint32 - uint256BigIntnone
              JSONbooleans.toBool()
              JSONi64s.toI64()
              JSONu64s.toU64()
              JSONf64s.toF64()
              JSONBigInts.toBigInt()
              JSONstrings.toString()
              JSONArrays.toArray()
              JSONObjects.toObject()
              StringAddressAddress.fromString(s)
              BytesAddressAddress.fromBytes(s)
              StringBigIntBigInt.fromString(s)
              StringBigDecimalBigDecimal.fromString(s)
              String (hexadecimal)BytesByteArray.fromHexString(s)
              String (UTF-8)BytesByteArray.fromUTF8(s)

              Metadati della Data Source

              È possibile ispezionare l’indirizzo del contratto, la rete e il contesto dell’origine dati che ha invocato il gestore attraverso lo spazio dei nomi dataSource:

              • dataSource.address(): Address
              • dataSource.network(): string
              • dataSource.context(): DataSourceContext

              Entità e DataSourceContext

              La classe base Entity e la classe figlia DataSourceContext hanno degli helper per impostare e ottenere dinamicamente i campi:

              • setString(key: string, value: string): void
              • setI32(key: string, value: i32): void
              • setBigInt(key: string, value: BigInt): void
              • setBytes(key: string, value: Bytes): void
              • setBoolean(key: string, value: bool): void
              • setBigDecimal(key, value: BigDecimal): void
              • getString(key: string): string
              • getI32(key: string): i32
              • getBigInt(key: string): BigInt
              • getBytes(key: string): Bytes
              • getBoolean(key: string): boolean
              • getBigDecimal(key: string): BigDecimal

              DataSourceContext nel manifesto

              The context section within dataSources allows you to define key-value pairs that are accessible within your Subgraph mappings. The available types are Bool, String, Int, Int8, BigDecimal, Bytes, List, and BigInt.

              Ecco un esempio YAML che illustra l’uso di vari tipi nella sezione context:

              1dataSources:2  - kind: ethereum/contract3    name: ContractName4    network: mainnet5    context:6      bool_example:7        type: Bool8        data: true9      string_example:10        type: String11        data: 'hello'12      int_example:13        type: Int14        data: 4215      int8_example:16        type: Int817        data: 12718      big_decimal_example:19        type: BigDecimal20        data: '10.99'21      bytes_example:22        type: Bytes23        data: '0x68656c6c6f'24      list_example:25        type: List26        data:27          - type: Int28            data: 129          - type: Int30            data: 231          - type: Int32            data: 333      big_int_example:34        type: BigInt35        data: '1000000000000000000000000'
              • Bool: Specifica un valore booleano (true o false).
              • String: Specifica un valore string.
              • Int: Specifica un numero intero a 32 bit.
              • Int8: Specifica un numero intero a 8 bit.
              • BigDecimal: Specifica un numero decimale. Deve essere quotato.
              • Bytes: Specifica una string esadecimale.
              • List: Specifica un elenco di elementi. Ogni elemento deve specificare il suo tipo e i suoi dati.
              • BigInt: Specifica un valore intero di grandi dimensioni. Deve essere quotato a causa delle sue grandi dimensioni.

              This context is then accessible in your Subgraph mapping files, enabling more dynamic and configurable Subgraphs.

              ⁠Edit on GitHub⁠

              IntroduzioneCommon Issues
              On this page
              • Riferimento API
              • Versioni
              • Tipi integrati
              • Store API
              • API Ethereum
              • API di registrazione
              • IPFS API
              • Crypto API
              • JSON API
              • Riferimento alle conversioni di tipo
              • Metadati della Data Source
              • Entità e DataSourceContext
              • DataSourceContext nel manifesto
              The GraphStatusTestnetBrand AssetsForumSecurityPrivacy PolicyTerms of Service