Loading...

Solidity : Un guide complet pour la création de contrats intelligents

Solidity est le langage de programmation de premier choix pour le développement de contrats intelligents sur la plateforme Ethereum. Sa syntaxe, influencée par JavaScript, C++, Python et d'autres langages de haut niveau, offre une courbe d'apprentissage accessible, surtout pour ceux qui connaissent la programmation orientée objet. Solidity compile le code en bytecode, exécuté sur l'Ethereum Virtual Machine (EVM), suivant une logique typée statiquement avec un riche système de types incluant booléens, entiers, adresses, contrats et plus. La sécurité est un principe fondamental de Solidity, avec des améliorations continues et des fonctionnalités supplémentaires dans les versions récentes pour répondre aux besoins des développeurs et renforcer la sécurité.

Alternatives à Solidity

Bien que Solidity soit prédominant, d'autres langages comme Vyper et Move gagnent en popularité. Vyper se concentre sur la simplicité et la lisibilité pour prévenir les bugs, tandis que Move vise à résoudre les problèmes de sécurité des cryptomonnaies et des contrats intelligents, offrant une expressivité sélective pour la gestion granulaire des actifs. Le choix du langage dépend des besoins spécifiques du projet, de l'aisance des développeurs et de l'importance de la sécurité et de la lisibilité.

Optimisation des contrats intelligents pour la performance

Les contrats intelligents sont les piliers des applications décentralisées sur la blockchain, fonctionnant de manière autonome et automatisée. Cependant, leur efficacité peut être compromise s'ils ne sont pas optimisés pour la performance, entraînant des coûts de gaz prohibitifs et des temps d'exécution lents. La sécurité et l'efficacité sont donc indissociables de l'optimisation.

Développement d'une application décentralisée (dApp) avec Solidity

Cet article explore l'écriture d'une application entièrement décentralisée (dApp) avec Solidity, exploitant les capacités d'Ethereum. Une dApp est accessible via un site web, se connectant directement à la blockchain Ethereum au lieu d'un serveur centralisé. Le rôle de back-end est assuré par le portefeuille local, éliminant le besoin d'un serveur centralisé.

Mise en garde concernant la sécurité

Les contrats Ethereum peuvent contenir des failles de sécurité, car la technologie est jeune. Cela est risqué, car on manipule indirectement de l'Ether, échangeable contre des euros.

Lire aussi: Droit Contractuel et Force Majeure

Environnement de développement

Pour développer une dApp, l'environnement reste léger, sans nécessiter une artillerie lourde d'outils. Les contrats Ethereum sont stockés dans la blockchain sous forme de code binaire assemblé, mais Solidity permet l'écriture des contrats à un niveau plus élevé.

Exemple de contrat : Roulette simplifiée

Le contrat gère un jeu de roulette simplifié, où un nombre aléatoire est choisi entre 0 et 36 à intervalles réguliers. Les mises des joueurs et le paiement des gagnants se font directement avec de l'Ether inclus dans les transactions. Le contrat permet à quiconque de "tourner" la roulette et de déclencher les paiements, tant que l'intervalle entre les tours est écoulé.

Simulation du tirage aléatoire

Il n'est pas possible de tirer un nombre aléatoire dans un contrat Ethereum, car le résultat doit être le même quel que soit le nœud d'exécution. Pour simuler le tirage, on utilise le hash du dernier bloc reçu avant l'exécution.

Structure du contrat

Un contrat réside dans un bloc contract, généralement dans un fichier .sol. La syntaxe de déclaration d'une variable est <type> [modifier] <name>. Les variables de type uint (entier non signé) peuvent être publiques ou privées, tandis que les variables de type address contiennent l'adresse du créateur du contrat. Une énumération et une structure Bet sont utilisées pour gérer les paris des joueurs. Les événements permettent de notifier des actions spécifiques du contrat.

Constructeur

Le constructeur initialise le contrat, en particulier la variable _creator contenant l'adresse du créateur. Il accède à l'objet global msg contenant les informations de la transaction courante, notamment sa propriété sender.

Lire aussi: Enjeux des Smart Contracts

Fonction betSingle

La fonction betSingle permet de miser sur un numéro, vérifiant sa validité avant d'ajouter le pari à la liste. L'appel à une fonction d'un contrat est une transaction, pouvant contenir une valeur en weis et/ou demander l'exécution d'une fonction sur un contrat.

Fonction getResult

La fonction getResult détermine le résultat de la roulette, vérifiant si l'opération est autorisée et tirant un nombre "aléatoire" basé sur le hash du dernier bloc. Elle parcourt ensuite chaque pari pour vérifier s'il est gagnant et émet une transaction pour le paiement.

Modifiers

Les modifiers, comme transactionMustContainEther et bankMustBeAbleToPayForBetType, ajoutent des vérifications avant l'exécution de la fonction. Ils permettent de calculer la somme maximale que la banque devra payer si tous les joueurs gagnent.

Tests du contrat

Le contrat peut être testé dans une blockchain locale de test, Test RPC, initialisée avec plusieurs comptes crédités d'une quantité d'Ether. La méthode la plus simple est d'utiliser l'API JavaScript d'Ethereum, web3.

Compilation et déploiement

La compilation du contrat se fait avec l'outil Truffle, qui crée un projet avec plusieurs répertoires et fichiers. Le déploiement se fait avec la commande truffle deploy.

Lire aussi: NFL : L'influence durable de Mike Alstott

Tests avec Node.js et Truffle

Pour tester le contrat, on peut lancer une console Node.js initialisée avec les contrats du projet. Truffle génère un fichier (Roulette.sol.js) contenant une classe Roulette dont les méthodes sont les méthodes publiques du contrat. La méthode new de l'objet Roulette appelle le constructeur du contrat.

Conclusion des tests

Les tests permettent de vérifier le bon fonctionnement du contrat, en consultant les soldes du contrat et du joueur pour vérifier les gains.

Ethereum Virtual Machine (EVM)

L'Ethereum Virtual Machine (EVM) gère les transactions dans la blockchain Ethereum via des contrats intelligents. Elle exécute des instructions (opcodes) générées par la compilation d'un langage de haut niveau comme Solidity. Chaque instruction a un prix en gas, que l'utilisateur doit payer lors de l'appel à une fonction.

Instructions et gas

L'instruction revert permet d'effectuer une exception qui met fin à l'appel en cours. La notion de gas évite l'utilisation inutile de ressources et les attaques.

Variables globales

Les variables globales incluent :

  • block : informations sur le bloc validant la transaction.
  • tx : informations sur la transaction en cours.
  • msg : informations sur le message envoyé, comme l'émetteur, la quantité d'Ether fournie et les données jointes.

Stockage des données

Le code et les variables du contrat sont stockés dans des zones de stockage permanentes et temporaires.

Stockage permanent

Le code du contrat est stocké de manière permanente mais ne peut pas être modifié. L'account storage est une base de données clé/valeur, où la clé et la valeur sont de 256 bits. Les variables plus petites sont optimisées par le compilateur de Solidity pour être stockées dans le même slot.

Mémoire volatile

La mémoire volatile est effacée après l'exécution du contrat. Elle inclut la stack, utilisée pour stocker des informations temporaires, et la memory, une grande zone mémoire accessible en lecture et écriture.

Calldata

La calldata est une zone mémoire en lecture seule utilisée lors de l'appel d'une fonction par un client Ethereum. Les 4 premiers octets sont réservés au sélecteur de la fonction.

Program Counter (PC)

Le Program Counter (PC) contient l'adresse de la prochaine instruction à exécuter.

Types d'appels

Différents types d'appels permettent de demander à un contrat intelligent d'exécuter du code.

Appels internes

Les appels internes se produisent lorsqu'un contrat appelle une de ses propres fonctions ou une fonction d'un contrat dont il hérite.

Appels externes

Les appels externes permettent d'appeler les fonctions d'autres contrats. Le call est l'appel de base, exécutant la fonction dans une nouvelle instance d'EVM. Le staticcall est similaire, mais ne peut pas effectuer de modifications sur la blockchain. Le delegateCall utilise le code d'un autre contrat sur l'état du contrat appelant, conservant la valeur du msg.sender.

Spécificités de l'EVM et de Solidity

L'EVM propose des calculs sur des données de 256 bits à l'aide d'une pile d'exécution et de zones mémoires spéciales. Solidity compile le code en instructions pour la machine virtuelle, mais les concepts de haut niveau comme l'héritage et le polymorphisme ne sont pas directement connus par l'EVM.

Optimisations de Solidity

Solidity effectue des opérations de masque binaire pour manipuler quelques bytes à la fois sur chaque zone mémoire de 32 bytes. Les quatre premiers octets des paramètres de la transaction sont utilisés pour identifier la méthode à invoquer.

Constructeur et erreurs

Solidity génère automatiquement le code du constructeur pour fournir le code du contrat à générer sous forme de data. L'instruction throw signale une erreur en invoquant un saut vers une adresse mémoire invalide.

Events

La notion d'event correspond aux logs de la machine virtuelle, informant un code à l'écoute de la chaîne lorsqu'une méthode d'un contrat est invoquée.

Création d'un smart contract pour les pronostics

Cet exemple montre la création d'un smart contract pour sauvegarder les pronostics posés par les utilisateurs sur les différents matchs.

Structure du contrat

Le contrat permet de sauvegarder les pronostics sous forme d'une table de hashage, où la clé est l'adresse de l'utilisateur et la valeur est un objet de type Bet. La structure Bet contient les scores pronostiqués, le gagnant pronostiqué en cas de match nul, et des attributs de gestion des pronostics.

Flux de jeu

Un match est d'abord créé en amont puis lancé (au coup d'envoi). Les méthodes permettant de passer d'une étape à la suivante sont exposées publiquement, mais ne produisent l'effet attendu que si le statut courant du match est cohérent. La méthode require de Solidity teste la valeur du GameStatus.

Développement avec Solidity : un exemple de NFT

Cet article décrit le développement d'un smart contract ERC721 pour la création de NFT, en utilisant Remix pour simplifier le développement.

Environnement de développement

L'environnement de développement comprend :

  • Ganache : pour simuler un nœud Ethereum en local.
  • VSCode / Remix : pour l'IDE.
  • Truffle : pour le framework de développement.
  • Jest / Chai : pour les tests.
  • Metamask : pour le wallet de crypto monnaie.

Création du contrat NFT

Le contrat NFT utilise le principe de Price Feed de Chainlink pour convertir les dollars en crypto au moment du mint. Un contrat minter est utilisé pour contrôler la fonction mint du contrat NFT.

Structure des paramètres d'entrée

La structure des paramètres d'entrée du contrat comprend :

  • chainCurrencyDecimals : le nombre de décimales de la crypto monnaie.
  • presalePriceUSD : le prix de vente initial en USD.
  • publicsalePriceUSD : le prix de vente public en USD.
  • maxSupply : le nombre maximal de tokens mintables.
  • maxMint : le nombre maximal de mints par utilisateur.
  • token : les informations sur le token (nom, symbole, IPFS URI).
  • priceFeed : l'adresse du contrat Price Feed.
  • periods : les périodes de vente (privée et publique).
  • teamAddress : l'adresse du wallet de l'équipe.

Contrat YounupNFTMinter

Le contrat YounupNFTMinter gère le mint des NFT, en vérifiant l'état du contrat, le prix, les limites et les fonds disponibles. Il utilise un Price Feed pour obtenir le prix actuel de la crypto monnaie.

Contrat YounupNFT

Le contrat YounupNFT est le contrat ERC721 qui gère les NFT. Seul le contrat minter peut minter des tokens.

Déploiement et tests

Le contrat est déployé et testé en utilisant Remix et Metamask. Les NFT mintés peuvent être vérifiés sur OpenSea Testnet.

Gestion des ressources avec IPFS

IPFS (InterPlanetary File System) est un protocole P2P Web 3.0 pour le stockage de fichiers décentralisé. Il permet de stocker les ressources des NFT de manière décentralisée, au lieu d'utiliser des serveurs centralisés.

tags: #constructeur #contrat #solidity #exemple

Articles populaires:

Share: