Le gaz (gas en anglais) est indispensable sur le réseau Ethereum pour exécuter tout contrat. Même si au premier abord, devoir payer pour exécuter du code peut sembler bizarre, cela est indispensable pour deux raisons :
– une blockchain fonctionne comme un immense ordinateur dont chacun peut posséder une partie, et est rémunéré en contrepartie des calculs qu’il effectue (la validation des blocs, ce qu’on appelle le minage). Chaque transaction est validée par des milliers de nœuds du réseau, et c’est ce qui garantit la sécurité très importante du système.
– Pour pas qu’un utilisateur de » l’ordinateur géant « que constitue la blockchain Ethereum puisse s’accaparer toutes les ressources de celui-ci, que ce soit volontairement ou par une erreur de code avec par exemple une boucle infinie, exécuter des fonctions a un coût qui augmente avec la consommation de ressources utilisées.
Pour conclure, on voit donc que ce carburant du réseau garantit sa sécurité et sa fiabilité. Ce qui est intéressant ici, c’est que pour sécuriser des données il est plus efficace d’ajouter des ordinateurs au réseau que d’acheter des systèmes complexes ou cher comme avec des données centralisées.
Il est donc très important, à chaque développement d’un smart contract, d’anticiper le fait que la quantité de gas (ETH) qu’il utilisera sera proportionnelle aux nombres de fonctions qu’il exécute.Coder proprement ne devient donc plus juste une rigueur méthodologique, mais bien un pré requis pour garantir l’efficacité de son application.
Imaginez une application très utilisée, qui se vend bien, dont les utilisateurs sont contents, mais qui a été mal pensée et qui consomme beaucoup de ressources, elle serait assez rapidement sortie du marché par un concurrent qui a développé cette application avec un coût de fonctionnement beaucoup élevé.
Voyons maintenant deux types de données qui peuvent être optimisées, les struct et les uint
Au vu de ce qui est décrit ci dessus, il pourrait être tentant de bien spécifier pour chaque uint sa taille exacte en byte en utilisant uint8, uint16, … uint256 etc, mais c’est en fait parfaitement inutile car Solidity réserve dans tous les cas 256 bits de stockage pour un uint (au passage int et uint sont des alias de uint256). On ne gagnera donc pas de gas à utiliser un uint32 plutôt que uint8, sauf dans un cas très particulier qui est le type de donnée struct
Struct est dans Solidity un type de variable particulier qui peut contenir plusieurs autres types de variables, c’est un lointain cousin d’un objet dans un autre langage de programmation plus classique.
Imaginons que nous souhaitons stocker pour une personne son nom, son âge, et son adresse Ethereum, on peut alors créer une structure ainsi :
struct Personne{
string Nom;
uint Age;
address Adresse;
}
On pourra ensuite par exemple initialiser Michel qui a 34 ans et dont l’adresse ETH est « 0xca35… » ainsi :
Personne personne = Personne("Michel",34,"0xca35...");
Venons en à l’optimisation en gas, Solidity va automatiquement emboîter les uint à l’intérieur d’un struct, et il sera donc intéressant d’utiliser le plus petit sous type possible.
Reprenons l’exemple de notre struct Personne, nous allons ajouter aussi une variable pour le poids. On pourrait simplement ajouter uint Poids; dans la déclaration, ce qui donnerait :
struct Personne{
string Nom;
uint Age;
uint Poids;
address Adresse;
}
Cependant, pour optimiser la consommation il serait plus intelligent de faire ainsi :
struct Personne{
string Nom;
uint8 Age;
uint8 Poids;
address Adresse;
}
Cela évitera de bloquer 2×256 bits pour des variables qui n’utiliseront jamais cet espace. Cela peut paraître minime, mais à l’échelle de milliers de transactions, ce peut être fondamental.