Docs
La Recherche⌘ K
  • Accueil
  • À propos de The Graph
  • Réseaux pris en charge
  • Contrats du Protocole
  • Subgraphs
    • Substreams
      • Token API
        • AI Suite
          • Indexing
            • Resources
              Resources > Migration Guides

              11 minutes

              Guide de migration de l'AssemblyScript

              Up until now, Subgraphs have been using one of the first versions of AssemblyScript⁠ (v0.6). Finally we’ve added support for the newest one available⁠ (v0.19.10)! 🎉

              That will enable Subgraph developers to use newer features of the AS language and standard library.

              Ce guide s’applique à tous ceux qui utilisent graph-cli/graph-ts en dessous de la version 0.22.0. Si vous êtes déjà à une version supérieure (ou égale) à celle-ci, vous avez déjà utilisé la version 0.19.10 d’AssemblyScript 🙂

              Note: As of 0.24.0, graph-node can support both versions, depending on the apiVersion specified in the Subgraph manifest.

              Fonctionnalités

              Nouvelle fonctionnalité

              • Les TypedArrays peuvent maintenant être construits à partir des ArrayBuffers en utilisant la nouvelle méthode statique wrap⁠ (v0.8.1⁠)
              • Nouvelles fonctions de la bibliothèque standard : String#toUpperCase, String#toLowerCase, String#localeCompare et TypedArray#set (v0.9.0⁠)
              • Ajout de la prise en charge de x instanceof GenericClass (v0.9.2⁠)
              • Ajout de StaticArray<T>, une variante de tableau plus efficace (v0.9.3⁠)
              • Ajout de Array<T>#flat (v0.10.0⁠)
              • Implémentation de l’argument radix sur Number#toString (v0.10.1⁠)
              • Ajout de la prise en charge des séparateurs dans les nombres à virgule flottante (v0.13.7⁠)
              • Prise en charge des fonctions de première classe (v0.14.0⁠)
              • Ajouter des éléments intégrés suivants: i32/i64/f32/f64.add/sub/mul (v0.14.13⁠)
              • Implémentation de Array/TypedArray/String#at (v0.18.2⁠)
              • Ajout de la prise en charge des modèles de chaînes de caractères (v0.18.17⁠)
              • Ajout de encodeURI(Component) et decodeURI(Component) (v0.18.27⁠)
              • Ajout de toString, toDateString et toTimeString à Date (v0.18.29⁠)
              • Ajout de toUTCString pour Date (v0.18.30⁠)
              • Ajout du type intégré nonnull/NonNullable (v0.19.2⁠)

              Optimizations

              • Les fonctions mathématiques telles que exp, exp2, log, log2 et pow ont été remplacées par des variantes plus rapides (v0.9.0⁠)
              • Optimisation légère de Math.mod (v0.17.1⁠)
              • Mise en cache de plus d’accès aux champs dans std Map et Set (v0.17.8⁠)
              • Optimisation pour les puissances de deux dans ipow32/64 (v0.18.2⁠)

              Autre

              • Le type d’un de tableau d’éléments peut maintenant être déduit de son contenu (v0.9.0⁠)
              • Mise à jour de la stdlib vers Unicode 13.0.0 (v0.10.0⁠)

              Comment mettre à niveau ?

              1. Change your mappings apiVersion in subgraph.yaml to 0.0.9:
              1...2dataSources:3  ...4    mapping:5      ...6      apiVersion: 0.0.97      ...
              1. Mettez à jour le graph-cli que vous utilisez avec la version la plus récente en exécutant :
              1# si vous l'avez installé globalement2npm install --global @graphprotocol/graph-cli@latest34# ou dans votre subgraph si vous l'avez comme dépendance de développement5npm install --save-dev @graphprotocol/graph-cli@latest
              1. Faites la même chose pour graph-ts, mais au lieu de l’installer globalement, sauvegardez-le dans vos dépendances principales :
              1npm install --save @graphprotocol/graph-ts@latest
              1. Suivez le reste du guide pour corriger les changements de langue.
              2. Exécutez codegen et deploy à nouveau.

              Modifications radicales

              Nullability

              Sur l’ancienne version d’AssemblyScript, vous pouviez créer du code comme celui-ci :

              1function load(): Value | null { ... }23let maybeValue = load();4maybeValue.aMethod();

              Cependant, sur la version la plus récente, comme la valeur est nullable, vous devez vérifier, comme ceci :

              1let maybeValue = load()23if (maybeValue) {4  maybeValue.aMethod() // `maybeValue` n'est plus nul5}

              Ou forcez-le comme ceci :

              1let maybeValue = load()! // breaks in runtime if value is null23maybeValue.aMethod()

              If you are unsure which to choose, we recommend always using the safe version. If the value doesn’t exist you might want to just do an early if statement with a return in you Subgraph handler.

              Ombrage variable

              Auparavant, vous pouviez faire un variable shadowing⁠ et un code comme celui-ci fonctionnait :

              1let a = 102let b = 203let a = a + b

              Cependant, cela n’est plus possible et le compilateur renvoie cette erreur :

              1ERROR TS2451: Cannot redeclare block-scoped variable 'a'23 let a = a + b;4 ~~~~~~~~~~~~~5in assembly/index.ts(4,3)

              Vous devrez renommer vos variables en double si vous conservez une observation de variables.

              Comparaisons nulles

              By doing the upgrade on your Subgraph, sometimes you might get errors like these:

              1ERROR TS2322: Type '~lib/@graphprotocol/graph-ts/common/numbers/BigInt | null' is not assignable to type '~lib/@graphprotocol/graph-ts/common/numbers/BigInt'.2     if (decimals == null) {3                     ~~~~4 in src/mappings/file.ts(41,21)

              Pour résoudre ce problème, il suffit de modifier l’instruction if en quelque chose comme ceci :

              1if (!decimals) {23  // ou45  if (decimals === null) {

              La même chose s’applique si vous faites != au lieu de ==.

              Casting

              Auparavant, la façon la plus courante d’effectuer une conversion de type était d’utiliser le mot-clé as, comme ceci :

              1let byteArray = new ByteArray(10)2let uint8Array = byteArray as Uint8Array // équivalent à : <Uint8Array>byteArray

              Cependant, cela ne fonctionne que dans deux scénarios :

              • Conversion des types primitifs (entre des types tels que u8, i32, bool ; ex : let b : isize = 10 ; b as usize) ;
              • Upcasting sur l’héritage de classe (sous-classe → superclasse)

              Les Exemples:

              1// primitive casting2let a: usize = 103let b: isize = 54let c: usize = a + (b as usize)
              1// conversion vers le type parent dans l'héritage des classes2class Bytes extends Uint8Array {}34let bytes = new Bytes(2)5// <Uint8Array>bytes // idem que: bytes as Uint8Array

              Il y a deux cas de figure où l’on peut vouloir faire une conversion de type, mais l’utilisation de as/<T>var n’est pas sûre :

              • Downcasting sur l’héritage de classe (superclasse → sous-classe)
              • Entre deux types qui partagent une superclasse
              1// conversion vers le type enfant dans l'héritage des classes2class Bytes extends Uint8Array {}34let uint8Array = new Uint8Array(2)5// <Bytes>uint8Array // crash l'exécution :(
              1// entre deux types qui partagent la même superclasse2class Bytes extends Uint8Array {}3class ByteArray extends Uint8Array {}45let bytes = new Bytes(2)6// <ByteArray>bytes // crash à l'exécution :(

              Dans ce cas, vous pouvez utiliser la fonction changetype<T> :

              1// conversion vers le type enfant dans l'héritage des classes2class Bytes extends Uint8Array {}34let uint8Array = new Uint8Array(2)5changetype<Bytes>(uint8Array) // fonctionne :)
              1// entre deux types qui partagent une même superclasse2class Bytes extends Uint8Array {}3class ByteArray extends Uint8Array {}45let bytes = new Bytes(2)6changetype<ByteArray>(bytes) // fonctionne :)

              Si vous voulez juste supprimer la nullité, vous pouvez continuer à utiliser l’opérateur as (ou <T>variable), mais assurez-vous que vous savez que la valeur ne peut pas être nulle, sinon cela causera un crash.

              1// supprimer la possibilité de valeur nulle (nullability)2let previousBalance = AccountBalance.load(balanceId) // AccountBalance | null34if (previousBalance != null) {5  return previousBalance as AccountBalance // suppression sûre de null6}78let newBalance = new AccountBalance(balanceId)

              Pour le cas de la nullité, nous recommandons de jeter un coup d’œil à la fonction de vérification de la nullité⁠, cela rendra votre code plus propre 🙂

              Nous avons également ajouté quelques méthodes statiques supplémentaires dans certains types pour faciliter la diffusion, à savoir :

              • Bytes.fromByteArray
              • Bytes.fromUint8Array
              • BigInt.fromByteArray
              • ByteArray.fromBigInt

              Vérification de nullité avec accès à la propriété

              Pour utiliser la fonction de vérification de la nullité⁠, vous pouvez utiliser les instructions if ou l’opérateur ternaire (? et :) comme suit :

              1let something: string | null = 'data'23let somethingOrElse = something ? something : 'else'45// ou67let somethingOrElse89if (something) {10  somethingOrElse = something11} else {12  somethingOrElse = 'else'13}

              Cependant, cela ne fonctionne que lorsque vous faites le if / ternaire sur une variable, et non sur l’accès à une propriété, comme ceci :

              1class Container {2  data: string | null3}45let container = new Container()6container.data = 'data'78let somethingOrElse: string = container.data ? container.data : 'else' // ne compile pas

              Ce qui génère cette erreur :

              1ERROR TS2322: Type '~lib/string/String | null' is not assignable to type '~lib/string/String'.23   let somethingOrElse: string = container.data ? container.data : "else";4                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

              Pour résoudre ce problème, vous pouvez créer une variable pour l’accès à cette propriété afin que le compilateur puisse effectuer la vérification magique de la nullité :

              1class Container {2  data: string | null3}45let container = new Container()6container.data = 'data'78let data = container.data910let somethingOrElse: string = data ? data : 'else' // compile sans problème :)

              Surcharge de l’opérateur avec accès à la propriété

              Si vous essayez de additionner (par exemple) un type nullable (à partir d’un accès à une propriété) avec un type non nullable, le compilateur AssemblyScript au lieu de donner une erreur de compilation avertissant que l’une des valeurs est nullable, il compile simplement silencieusement, donnant une chance pour que le code soit interrompu au moment de l’exécution.

              1class BigInt extends Uint8Array {2  @operator('+')3  plus(other: BigInt): BigInt {4    // ...5  }6}78class Wrapper {9  public constructor(public n: BigInt | null) {}10}1112let x = BigInt.fromI32(2)13let y: BigInt | null = null1415x + y // donne une erreur de compilation concernant la nullité16let wrapper = new Wrapper(y)1718wrapper.n = wrapper.n + x // ne donne pas d'erreurs de compilation comme il se doit

              We’ve opened a issue on the AssemblyScript compiler for this, but for now if you do these kind of operations in your Subgraph mappings, you should change them to do a null check before it.

              1let wrapper = new Wrapper(y)23if (!wrapper.n) {4  wrapper.n = BigInt.fromI32(0)5}67wrapper.n = wrapper.n + x // maintenant `n` est garanti comme étant un BigInt

              Initialisation de valeur

              Si vous avez un code comme celui-ci :

              1var value: Type // null2value.x = 103value.y = 'content'

              It will compile but break at runtime, that happens because the value hasn’t been initialized, so make sure your Subgraph has initialized their values, like this:

              1var value = new Type() // initialized2value.x = 103value.y = 'content'

              De plus, si vous avez des propriétés nullables dans une entité GraphQL, comme ceci :

              1type Total @entity {2  id: Bytes!3  amount: BigInt4}

              Et vous avez un code similaire à celui-ci :

              1let total = Total.load('latest')23if (total === null) {4  total = new Total('latest')5}67total.amount = total.amount + BigInt.fromI32(1)

              Vous devez vous assurer d’initialiser la valeur total.amount, car si vous essayez d’y accéder comme dans la dernière ligne pour la somme, cela va planter. Il faut donc d’abord l’initialiser :

              1let total = Total.load('latest')23if (total === null) {4  total = new Total('latest')5  total.amount = BigInt.fromI32(0)6}78total.tokens = total.tokens + BigInt.fromI32(1)

              Ou vous pouvez simplement changer votre schéma GraphQL pour ne pas utiliser un type nullable pour cette propriété, puis nous l’initialiserons à zéro à l’étape codegen 😉

              1type Total @entity {2  id: Bytes!3  amount: BigInt!4}
              1let total = Total.load('latest')23if (total === null) {4  total = new Total('latest') // initialise déjà les propriétés non-nullables5}67total.amount = total.amount + BigInt.fromI32(1)

              Initialisation de la propriété de classe

              Si vous exportez des classes avec des propriétés qui sont d’autres classes (déclarées par vous ou par la bibliothèque standard), comme ceci :

              1class Thing {}23export class Something {4  value: Thing5}

              Le compilateur génèrera une erreur car vous devez soit ajouter un initialisateur pour les propriétés qui sont des classes, soit ajouter l’opérateur ! :

              1export class Something {2  constructor(public value: Thing) {}3}45// ou67export class Something {8  value: Thing910  constructor(value: Thing) {11    this.value = value12  }13}1415// ou1617export class Something {18  value!: Thing19}

              Initialisation du tableau

              La classe Array accepte toujours un nombre pour initialiser la longueur de la liste, cependant vous devez faire attention car des opérations comme .push vont en fait augmenter la taille au lieu d’ajouter au début, par exemple :

              1let arr = new Array<string>(5) // ["", "", "", "", ""]23arr.push('something') // ["", "", "", "", "", "something"] // taille 6 :(

              En fonction des types que vous utilisez, par exemple les types nullables, et de la manière dont vous y accédez, vous pourriez rencontrer une erreur d’exécution comme celle-ci :

              1ERRO Handler skipped due to execution failure, error: Mapping aborted at ~lib/array.ts, line 110, column 40, with message: Element type must be nullable if array is holey  wasm backtrace:     0: 0x19c4 - <unknown>!~lib/@graphprotocol/graph-ts/index/format         1: 0x1e75 - <unknown>!~lib/@graphprotocol/graph-ts/common/collections/Entity#constructor        2: 0x30b9 - <unknown>!node_modules/@graphprotocol/graph-ts/global/global/id_of_type

              Pour pousser au début, vous devez soit initialiser le Tableau avec une taille de zéro, comme ceci :

              1let arr = new Array<string>(0) // []23arr.push('something') // ["quelque chose"]

              Ou vous devriez le muter via index :

              1let arr = new Array<string>(5) // ["", "", "", "", ""]23arr[0] = 'something' // ["quelque chose", "", "", "", ""]

              Schéma GraphQL

              Il ne s’agit pas d’un changement direct d’AssemblyScript, mais vous devrez peut-être mettre à jour votre fichier schema.graphql.

              Vous ne pouvez désormais plus définir de champs dans vos types qui sont des listes non nullables. Si vous avez un schéma comme celui-ci :

              1type Something @entity {2  id: Bytes!3}45type MyEntity @entity {6  id: Bytes!7  invalidField: [Something]! # n'est plus valide8}

              Vous devrez ajouter un ! au membre du type List, comme ceci :

              1type Something @entity {2  id: Bytes!3}45type MyEntity @entity {6  id: Bytes!7  invalidField: [Something!]! # valide8}

              Cela a changé à cause des différences de nullité entre les versions d’AssemblyScript, et c’est lié au fichier src/generated/schema.ts (chemin par défaut, vous pouvez l’avoir changé).

              Autre

              • Alignement de Map#set et Set#add avec la spécification, retournant this (v0.9.2⁠)
              • Les tableaux n’héritent plus de ArrayBufferView, mais sont désormais distincts (v0.10.0⁠)
              • Les classes initialisées à partir d’objets littéraux ne peuvent plus définir de constructeur (v0.10.0⁠)
              • Le résultat d’une opération binaire ** est maintenant l’entier de dénominateur commun si les deux opérandes sont des entiers. Auparavant, le résultat était un flottant comme si l’on appelait Math/f.pow (v0.11.0⁠)
              • Contraindre NaN à false lors d’une conversion de type vers bool (v0.14.9⁠)
              • Lors du déplacement d’une petite valeur entière de type i8/u8 ou i16/u16, seuls les 3 ou 4 bits les moins significatifs de la valeur RHS affectent le résultat, de manière analogue au résultat d’un i32.shl qui n’est affecté que par les 5 bits les moins significatifs de la valeur RHS. Exemple : someI8 << 8 produisait auparavant la valeur 0, mais produit maintenant someI8 à cause du masquage de la valeur RHS comme 8 & 7 = 0 (3 bits) (v0.17.0⁠)
              • Correction d’un bug dans les comparaisons de chaînes de caractères relationnelles lorsque les tailles sont différentes (v0.17.8⁠)
              ⁠Edit on GitHub⁠

              CurationGraphQL Validations Migration Guide
              On this page
              • Fonctionnalités
              • Nouvelle fonctionnalité
              • Optimizations
              • Autre
              • Comment mettre à niveau ?
              • Modifications radicales
              • Nullability
              • Ombrage variable
              • Comparaisons nulles
              • Casting
              • Vérification de nullité avec accès à la propriété
              • Surcharge de l’opérateur avec accès à la propriété
              • Initialisation de valeur
              • Initialisation de la propriété de classe
              • Initialisation du tableau
              • Schéma GraphQL
              • Autre
              The GraphStatusTestnetActifs de la MarqueForumSécuritéPolitique de confidentialitéConditions d'utilisation