Cryptomonnaie

Comment ne pas manquer de gaz à Ethereum – Alberto Cuesta Cañada

Comment ne pas manquer de gaz à Ethereum - Alberto Cuesta Cañada


Ou encore, comment coder des contrats intelligents évolutifs.

1*FmM57rntjA9sQCNBo5XAPw - Comment ne pas manquer de gaz à Ethereum - Alberto Cuesta Cañada
© Gab Pili / Unsplash

Le respect des hommes pour les impondérables varie, mais il y a toujours une limite. - H. P. Lovecraft

Je conçois et je code des solutions Ethercha blockchain depuis un certain temps. Si vous avez suivi cet espace, vous remarquerez que nous faisons les choses différemment ici. Nous sommes obsédés par le code minimaliste, mis en place avec des limitations ridicules et agissons toujours comme si nos erreurs apparaissaient dans les journaux.

Dans cet article, je vais vous parler de l’une de ces limitations qui contraignent les développeurs Ethereum à respecter les principes fondamentaux: la taille du bloc. Avec l’immuabilité, c’est facilement la plus grande contrainte au développement de la blockchain.

Contrairement à un ordinateur normal, le réseau Ethereum doit être calculé en blocs, chaque bloc pouvant exécuter une quantité limitée de code. La limite exacte varie, mais il s’agit actuellement d’environ 10 millions de gaz. Chaque opération Ethereum EVM a un coût de gaz différent, mais à la fin, vous devez vous rappeler que la lecture d’un élément de données du stockage représente 200 gaz et l’écriture d’un élément de données dans le stockage représente 20000 gaz.

Si vous lancez le calcul, vous constaterez qu'un seul bloc peut contenir environ 50 000 opérations de lecture, 500 opérations d'écriture ou une combinaison des deux.

Quand les gens parlent de la blockchain comme solution pour automatiser les affaires, ils ne comprennent pas toujours bien le concept. La Blockchain automatise les réactions selon des ordres immuables.

Si je déploie un contrat sur le réseau Ethereum qui indique à quiconque m'envoie une crypto-cryptographie, je monnais et envoyais un crypto-log, cela se produira pour toujours. L'action est suivie d'une réaction déterministe.

Ce que la blockchain Ethereum ne fait pas, c’est exécuter un algorithme de contrat intelligent qui ne se termine pas.

Essayez de faire cela et vous recevrez le redouté panne d'essence Erreur. Pour chaque action, mon contrat smart peut générer une réaction ne coûtant pas plus de 10 millions d’essence. Cela signifie que nous devons utiliser nos ressources informatiques avec parcimonie ou diviser les tâches en étapes. Si je veux distribuer des dividendes aux actionnaires à l'aide d'un contrat intelligent, chacun d'entre eux devra venir demander le dividende.

Si je lance une boucle pour distribuer des dividendes, je vais manquer d’essence avant d’arriver au 500ème actionnaire.

J'aime bien que le codage des applications de tous les jours me mène aux mathématiques et aux structures de données de base. C’est comme retourner à l’université. Jours heureux.

Lorsque vous codez un contrat intelligent, vous devez faire très attention aux boucles. Une boucle est une invitation à un panne d'essence erreur de ruiner votre application.

Mais coder complètement sans boucles n'est pas amusant non plus.

La clé pour coder les contrats intelligents avec l’utilité maximale est d’être très prudent avec les structures de données que nous utilisons, de connaître les limites de calcul inhérentes aux limites de gaz en bloc et de scinder le travail en appels séparés lorsque tout le reste échoue.

Pour parler de limites de calcul, nous devrons utiliser un peu de notation O. Si vous avez besoin d’un rappel, rendez-vous sur wikipedia pour en savoir plus sur O (1), O (log N) et O (N). Nous n’avons besoin d’aucune autre pour l’instant. Je vais vous donner un indice: tous les contrats Ethereum intelligents doivent être exécutés dans le petit Excellent ruban ci-dessous:

BigOCheatSheet.

Si nous considérons les coûts de gaz de 200 pour une opération de lecture et de 20000 pour une opération d'écriture, ainsi que d'une limite de gaz en bloc de 10 millions de gaz, nous pouvons faire quelques affirmations sur les algorithmes que nous pouvons exécuter en bloc.

Les structures de données de base dépendent d'algorithmes qui ont tendance à être O (N). Par exemple, cela consisterait à conserver les données dans un tableau et à le parcourir en boucle pour faire des choses.

Toute lecture d'algorithme O (N) sur une structure de données s'épuisera en gaz si la structure de données atteint environ N = 50000. Par souci de simplicité, vous pouvez supposer que cela inclut également une seule opération d'écriture. Nous pouvons parler de cela comme d’une opération de recherche et d’écriture.

Toute écriture d’algorithme O (N) sur tous les éléments d’une structure de données s’épuisera en gaz si la structure de données passe à environ N = 500. Je l’appellerai une opération d’écriture multiple.

Cela a plus de sens lorsque cela est expliqué dans un contexte réel. Si vous avez un jeton qui garde la trace de tous les détenteurs de jetons et que, pour une opération donnée, vous devez tous les vérifier avant de mettre à jour une variable de contrat, vous ne pouvez pas avoir plus de 50 000 détenteurs de jetons. Si votre jeton offre des récompenses aux détenteurs de jetons et que vous mettez à jour tous les soldes dans le même appel, votre nombre maximal de détenteurs de jetons est d'environ 500.

Il existe des structures de données plus complexes où les algorithmes manipulant des données sont O (log N). Cela signifie que pour trouver une valeur spécifique dans une structure de données contenant N éléments, il vous suffit de suivre log N étapes, ce qui est un nombre beaucoup plus petit.

Toute lecture d'algorithme O (log2 N) sur une structure de données s'épuisera en gaz si la structure de données croît à environ N = 2 ** 50000. Pour plus de simplicité, vous pouvez supposer que cela inclut également une seule opération d'écriture. Nous pouvons parler de cela comme d'une recherche. Cela signifie que si votre algorithme de recherche dans une structure de données est O (log2 N), votre contrat intelligent sera mis à l'échelle. Opération d'écriture. Le nombre maximal pouvant être représenté dans Solidity est 2 ** 256, ce qui correspond également au nombre maximal d'éléments que vous pouvez conserver dans une structure de données Solidity.

Cela signifie que si votre algorithme de recherche dans une structure de données est O (log2 N), votre contrat intelligent évoluera.

Tout algorithme O (log2N) écrivant sur une structure de données n’écrirait pas sur tous les N éléments de la structure de données, mais le ferait au maximum sur log2 N. Cela signifie qu'un algorithme O (log2 N) avec plusieurs écritures manquerait de gaz si la structure de données atteignait N = 2 ** 500, valeur qui est toujours supérieure au nombre maximal existant dans Solidity.

Cela signifie que si votre algorithme à écrire dans une structure de données est O (log2 N), votre contrat intelligent évoluera.

J'aime rendre les choses faciles pour moi et pour les autres. Maintenant que nous connaissons les limites générales et leurs raisons, nous pouvons retourner à l'université et définir tout ce que nous pouvons et ne pouvons pas faire:

BigOCheatSheet.

Il existe essentiellement quatre structures de données en informatique:

  1. Tableaux
  2. Listes liées.
  3. Tables de hachage.
  4. Des arbres.

Table de hachage

Les tables de hachage constituent une structure de données assez avancée dans la plupart des langages informatiques, à l'exception de Solidity. Tout dans Solidity est une table de hachage, que nous appelons cartographie. Même les tableaux sont implémentés sous forme de mappages sous le capot. Lorsque j'implémente des listes liées, j'utilise des mappages. Lorsque vous utilisez uniquement des mappages, vous utilisez uniquement des mappages.

La lecture d'un mappage est toujours O (1), l'écriture dans un mappage est toujours O (1). Il n’existe pas de fonction de recherche intégrée; pour cela, vous devez implémenter l’une des autres structures de données. Tout cela signifie que vous devez utiliser uniquement des mappages chaque fois que vous le pouvez et vous serez en sécurité. La taille limite pour un mappage dans Solidity est 2 ** 256.

Tableaux

Les tableaux sont un élément amusant de Solidity, mais ils constituent également la seule structure de données intégrée pouvant contenir plusieurs éléments et prenant en charge une fonction de recherche.

GeeksForGeeks

Les tableaux peuvent contenir 2 ** 256 éléments si vous n'avez pas besoin de passer par toutes les positions en un seul appel et si vous insérez ou supprimez uniquement des éléments à la fin. Si vous devez vérifier toutes les positions dans un tableau avant d'écrire dans le stockage, vous devrez limiter votre tableau à une longueur d'environ 50 000, voire moins. Les tableaux ne doivent pas être utilisés si vous devez insérer n'importe où sauf à la fin.

Listes liées

Les listes chaînées constituent la structure de données de votre choix lorsque vous devez conserver l'ordre d'insertion et également lorsque vous souhaitez insérer des positions arbitraires. Vous pouvez les utiliser pour contenir 2 ** 256 éléments, tels que des tableaux pour l’accès et l’insertion arbitraire. De la même manière que les tableaux, si vous devez visiter toutes les positions en un seul appel, vous devez limiter leur longueur à 50 000 éléments.

GeeksForGeeks

Vous pouvez utiliser les listes liées pour conserver vos éléments de données dans un ordre spécifique en forçant les insertions à se produire à la position appropriée. Cet insert aura un coût de 0 (N) lectures et O (1) d’écriture, ainsi il limitera la longueur de votre liste à quelques dizaines de milliers sans raffinement supplémentaire.

Des arbres

Les arbres sont la structure de données que vous utilisez dans Solidity si vous avez besoin de rechercher efficacement dans un jeu de données ordonné. Ils sont complexes, mais il existe quelques implémentations (Arbre de statistiques de commande, Arbre noir rouge) que vous pouvez utiliser si vous vous sentez courageux. Toutes les opérations dans un arbre ont une complexité de O (log N), ce qui signifie que vous pouvez conserver un arbre de taille astronomique.

GeeksForGeeks

Si vous utilisez un arbre pour stocker des données, vous n'avez aucune limite pratique à la taille de la structure pour les opérations de recherche et d'écriture, et une limite de mille millions de millions d'éléments pour les opérations d'écriture multiple. Néanmoins, vous ne ferez jamais plus que quelques centaines d’écritures en un seul appel.

Cependant, l'utilisation des arbres a ses propres inconvénients. Ils sont complexes à écrire et à tester. Ils sont coûteux à déployer. À mon avis, l'utilisation d'une structure de données aussi complexe constitue un risque énorme pour votre projet.

Ne me faites pas confiance, testez par vous-même. Vous pouvez utiliser ce petit contrat pour tester le nombre d’opérations de lecture ou d’écriture contenues dans un bloc:

solidité du pragma ^ 0.5.10;contrat gaz {
événement GasEvent (données uint256);
mapping (uint256 => uint256) public mappingStorage; fonction writeData (uint256 _times)
Publique
{
pour (uint256 i = 0; i <_times; i ++) {
mappingStorage[i] = 1;
}
}

fonction readData (uint256 _times)
Publique
{
uint256 tmp;
pour (uint256 i = 0; i <_times; i ++) {
tmp = mappingStorage[i];
}
émettre GasEvent (_times);
}
}

Il y a des coûts supplémentaires liés au gaz pour gérer ces boucles et pour transformer l'opération de lecture en une transaction qui change d'état en émettant un événement, mais je m'attendrais à ce que ces fonctions tombent en panne après quelques centaines d'écritures ou des dizaines de milliers de lectures. Voici les résultats si je règle la taille de bloc à 10 millions:

Contrat: gaz
✓ writeData (100) (484ms)
✓ writeData (200) (888ms)
✓ writeData (300) (1067ms)
✓ writeData (400) (661ms)
x writeData (500) - Épuisé
✓ readData (10000) (3422ms)
✓ readData (20000) (3372ms)
x readData (30000) - Épuisé
x readData (40000) - Épuisé
x readData (50000) - Épuisé

Boom.

Il m'a fallu un certain temps pour enfin comprendre les limites informatiques des contrats intelligents. Dans cet article, j’ai donné un guide clair et concis de ce que vous pouvez et ne pouvez pas faire lorsqu’un appel à un contrat intelligent Ethereum.

  1. Tout est une cartographie, utilisez-les toujours si vous n’avez pas à parcourir le contenu.
  2. Utilisez un tableau si vous devez rechercher et pouvez accepter d'insérer et de supprimer uniquement à la fin de celui-ci.
  3. Utilisez des listes chaînées si vous devez effectuer une recherche et que vous devez également insérer des positions arbitraires.
  4. Utilisez un arbre si vous devez garder vos données ordonnées.

Pour toute autre chose, vous devrez diviser votre code en différents appels et créer une machine à états. Vous pourriez aussi bien vous demander si vous devriez coder ceci dans une blockchain.

Si vous devez visiter tous les éléments d'une structure de données, votre taille limite est de quelques dizaines de milliers. Si vous devez écrire pour chaque élément d'une structure de données, votre taille limite sera de quelques centaines.

Ne manquez pas d’essence!

Afficher plus

SupportIvy

SupportIvy.com : Un lieu pour partager le savoir et mieux comprendre le monde. Meilleure plate-forme de support gratuit pour vous, Documentation &Tutoriels par les experts.

Articles similaires

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Bouton retour en haut de la page
Fermer