Développement et Déploiement de Votre Premier Smart Contract
Bienvenue dans cette leçon fondamentale de votre parcours Web3 ! Après avoir posé les bases de la blockchain et de ses concepts, nous allons plonger au cœur de la programmation décentralisée en apprenant à développer et déployer notre tout premier Smart Contract. Les Smart Contracts sont les briques essentielles des DApps (Applications Décentralisées), agissant comme des accords numériques auto-exécutables stockés sur une blockchain.
Dans cette leçon, nous allons :
- Comprendre ce qu'est un Smart Contract et son importance.
- Mettre en place un environnement de développement local.
- Écrire un Smart Contract simple en Solidity.
- Compiler, tester et déployer ce contrat sur un réseau blockchain de test.
1. Comprendre les Smart Contracts
1.1 Qu'est-ce qu'un Smart Contract ?
Un Smart Contract est un programme informatique auto-exécutable et immuable stocké sur une blockchain. Imaginez-le comme un contrat traditionnel, mais dont les termes et conditions sont inscrits dans du code. Une fois déployé, il ne peut être modifié et son exécution est automatiquement déclenchée lorsque les conditions prédéfinies sont remplies.
Les caractéristiques clés sont :
- Immuabilité : Une fois déployé, le code du contrat ne peut pas être modifié. Cela garantit la confiance et la prévisibilité.
- Transparence : Le code est public et vérifiable par quiconque sur la blockchain.
- Décentralisation : Il n'y a pas d'autorité centrale contrôlant le contrat. Il s'exécute sur tous les nœuds du réseau.
- Auto-exécution : Une fois les conditions remplies, le contrat s'exécute automatiquement sans intervention humaine.
1.2 À quoi servent les Smart Contracts ?
Les Smart Contracts sont le fondement de la plupart des applications Web3 et des innovations de la blockchain, y compris :
- Cryptomonnaies et jetons (Tokens) : Création et gestion de jetons (ERC-20, ERC-721/NFTs).
- Finance Décentralisée (DeFi) : Prêts, emprunts, échanges automatisés, pools de liquidité.
- Organisation Autonome Décentralisée (DAO) : Gestion de la gouvernance et du vote.
- Jeux (GameFi) : Propriété d'actifs en jeu, logiques de jeu.
- Logistique et Supply Chain : Traçabilité automatisée.
2. L'Écosystème de Développement
Pour développer des Smart Contracts, nous avons besoin d'un ensemble d'outils. Nous nous concentrerons sur l'écosystème Hardhat, qui est un environnement de développement puissant et flexible pour Ethereum.
2.1 Prérequis Techniques
Avant de commencer, assurez-vous d'avoir installé :
- Node.js et npm (ou Yarn) : Ces outils sont essentiels pour gérer les dépendances de notre projet. Vous pouvez les télécharger depuis nodejs.org.
- Un éditeur de code : Visual Studio Code est fortement recommandé pour son support étendu de Solidity (via des extensions comme
Solidityde Juan Blanco).
2.2 Hardhat : Votre Boîte à Outils
Hardhat est un environnement de développement pour la compilation, le déploiement, le test et le débogage de votre logiciel Ethereum. Il fournit une infrastructure complète pour les Smart Contracts en Solidity.
Ses avantages incluent :
- Réseau Hardhat local : Un réseau Ethereum local intégré pour des tests rapides.
- Plugins : Un système de plugins riche pour étendre les fonctionnalités.
- Débogage facile : Support pour les messages d'erreur détaillés et les traces de pile.
3. Initialisation du Projet avec Hardhat
Créons notre premier projet Hardhat.
3.1 Création du Dossier Projet
Ouvrez votre terminal et suivez ces étapes :
# Créez un nouveau dossier pour votre projet
mkdir mon-premier-contrat-web3
cd mon-premier-contrat-web3
# Initialisez un projet Node.js
npm init -y
# Installez Hardhat
npm install --save-dev hardhat
3.2 Initialisation de Hardhat dans le Projet
Une fois Hardhat installé, vous pouvez l'initialiser :
npx hardhat
Vous serez invité à choisir une option. Sélectionnez Create a JavaScript project.
√ What do you want to do? · Create a JavaScript project
√ Hardhat project root: · /chemin/vers/mon-premier-contrat-web3
√ Do you want to add a .gitignore? (Y/n) · Y
√ Do you want to install this project's dependencies with npm? (Y/n) · Y
Hardhat va créer une structure de projet de base avec les dossiers suivants :
contracts/: Où vos fichiers Solidity (.sol) seront stockés.scripts/: Pour vos scripts de déploiement et d'interaction.test/: Pour vos fichiers de test JavaScript.hardhat.config.js: Le fichier de configuration de Hardhat.
4. Écriture de Votre Premier Smart Contract (Solidity)
Nous allons créer un Smart Contract simple appelé SimpleStorage. Ce contrat permettra de stocker un nombre et de le récupérer.
4.1 Introduction à Solidity
Solidity est un langage de programmation orienté objet, de haut niveau, utilisé pour implémenter des Smart Contracts sur diverses blockchains compatibles avec la Machine Virtuelle Ethereum (EVM).
Un contrat Solidity typique contient :
pragma solidity: Indique la version du compilateur Solidity.contract NomDuContrat { ... }: La définition du contrat.variables d'état: Des variables stockées en permanence sur la blockchain.fonctions: Des blocs de code qui peuvent interagir avec les variables d'état ou effectuer d'autres logiques.
4.2 Le Contrat SimpleStorage.sol
Créez un nouveau fichier SimpleStorage.sol dans le dossier contracts/ et ajoutez-y le code suivant :
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24; // Indique la version du compilateur Solidity
contract SimpleStorage {
// Ceci est une variable d'état. Sa valeur est stockée en permanence sur la blockchain.
uint256 public myNumber; // 'public' génère automatiquement une fonction getter pour cette variable.
// Cette fonction permet de définir la valeur de 'myNumber'.
// 'setNumber' est un nom descriptif pour notre fonction.
// 'newNumber' est l'argument que la fonction prend.
// 'public' signifie que n'importe qui peut appeler cette fonction.
function setNumber(uint256 newNumber) public {
myNumber = newNumber; // Met à jour la variable d'état 'myNumber'.
}
// Cette fonction permet de récupérer la valeur de 'myNumber'.
// 'view' signifie que la fonction ne modifie pas l'état de la blockchain.
// 'returns (uint256)' indique que la fonction retourne un entier non signé de 256 bits.
function getNumber() public view returns (uint256) {
return myNumber; // Retourne la valeur actuelle de 'myNumber'.
}
}
Explication du Code :
SPDX-License-Identifier: MIT: Obligatoire depuis Solidity 0.6.8, indique la licence du code.pragma solidity ^0.8.24;: Spécifie que ce contrat doit être compilé avec une version de Solidity supérieure ou égale à 0.8.24, et inférieure à 0.9.0.contract SimpleStorage { ... }: Définit notre Smart Contract nomméSimpleStorage.uint256 public myNumber;: Déclare une variable d'état nomméemyNumberde typeuint256(entier non signé de 256 bits, le type le plus courant pour les nombres en Solidity). Le mot-clépubliccrée automatiquement une fonction getter pourmyNumber, nous permettant de lire sa valeur depuis l'extérieur du contrat.function setNumber(uint256 newNumber) public { ... }: Définit une fonctionsetNumberqui prend un argumentnewNumberet met à jour la variablemyNumberavec cette nouvelle valeur. Puisqu'elle modifie l'état de la blockchain, appeler cette fonction coûtera des frais de gaz.function getNumber() public view returns (uint256) { ... }: Définit une fonctiongetNumberqui renvoie la valeur actuelle demyNumber. Le mot-cléviewindique que cette fonction ne modifie pas l'état de la blockchain. Par conséquent, appeler une fonctionviewne coûte pas de gaz.
5. Compilation du Smart Contract
Avant de pouvoir déployer notre contrat, il doit être compilé en bytecode, que la Machine Virtuelle Ethereum (EVM) peut comprendre. Hardhat s'occupe de cela pour nous.
5.1 Commande de Compilation
Dans votre terminal, exécutez la commande suivante :
npx hardhat compile
Hardhat va parcourir votre dossier contracts/, compiler tous les fichiers Solidity et générer les artefacts (bytecode, ABI) dans le dossier artifacts/.
Qu'est-ce que l'ABI ?
L'ABI (Application Binary Interface) est une interface qui définit comment interagir avec le Smart Contract. Elle spécifie les fonctions du contrat et leurs paramètres, permettant aux applications externes (comme votre DApp React) de communiquer avec lui.
6. Test du Smart Contract
Il est crucial de tester vos Smart Contracts avant de les déployer sur un réseau réel. Les bugs dans les contrats peuvent avoir des conséquences irréversibles (perte de fonds, vulnérabilités).
Hardhat intègre un environnement de test puissant basé sur Mocha et Chai.
6.1 Écriture d'un Test Simple
Ouvrez le fichier test/Lock.js (si Hardhat l'a créé) ou créez un nouveau fichier test/simple-storage.js. Supprimez le contenu existant et ajoutez ceci :
const { expect } = require("chai"); // Importe la bibliothèque d'assertions Chai
const { ethers } = require("hardhat"); // Importe la bibliothèque ethers.js de Hardhat
describe("SimpleStorage", function () {
let SimpleStorage; // Variable pour stocker la fabrique du contrat
let simpleStorage; // Variable pour stocker l'instance du contrat déployé
// Avant chaque test, nous déployons une nouvelle instance du contrat
beforeEach(async function () {
// Obtenir la fabrique du contrat "SimpleStorage"
SimpleStorage = await ethers.getContractFactory("SimpleStorage");
// Déployer une nouvelle instance du contrat
simpleStorage = await SimpleStorage.deploy();
// Attendre que le déploiement soit terminé
await simpleStorage.waitForDeployment();
});
it("Devrait stocker la nouvelle valeur et la récupérer", async function () {
const initialValue = await simpleStorage.getNumber();
expect(initialValue).to.equal(0); // Par défaut, uint256 est initialisé à 0
const newValue = 42;
// Appeler la fonction setNumber pour changer la valeur
const tx = await simpleStorage.setNumber(newValue);
await tx.wait(); // Attendre que la transaction soit minée
// Récupérer la nouvelle valeur et vérifier qu'elle est correcte
const storedValue = await simpleStorage.getNumber();
expect(storedValue).to.equal(newValue);
});
it("Devrait permettre la modification répétée de la valeur", async function () {
await simpleStorage.setNumber(10);
expect(await simpleStorage.getNumber()).to.equal(10);
await simpleStorage.setNumber(20);
expect(await simpleStorage.getNumber()).to.equal(20);
});
});
Explication du Code de Test :
describe("SimpleStorage", function() { ... }): Définit une suite de tests pour notre contratSimpleStorage.beforeEach(async function() { ... }): Un hook Mocha qui est exécuté avant chaque test. C'est ici que nous déployons une nouvelle instance du contrat pour assurer que chaque test commence avec un état propre.ethers.getContractFactory("SimpleStorage"): Récupère l'abstraction du contratSimpleStorage, qui est comme une "usine" pour créer des instances de ce contrat.SimpleStorage.deploy(): Déploie une nouvelle instance du contrat sur le réseau Hardhat local (simulé).await simpleStorage.waitForDeployment(): Attend que le contrat soit effectivement déployé.
it("Devrait stocker la nouvelle valeur et la récupérer", async function() { ... }): Définit un cas de test individuel.await simpleStorage.getNumber(): Appelle la fonctiongetNumberdu contrat déployé.expect(...).to.equal(...): Utilise Chai pour faire des assertions sur les résultats.await simpleStorage.setNumber(newValue): Appelle la fonctionsetNumberdu contrat.await tx.wait(): Attendre la confirmation de la transaction sur la blockchain (importante pour les fonctions qui modifient l'état).
6.2 Exécution des Tests
Dans votre terminal, exécutez la commande :
npx hardhat test
Hardhat lancera un réseau Ethereum local temporaire, déploiera votre contrat, exécutera les tests, puis arrêtera le réseau. Vous devriez voir un résultat indiquant que les tests ont réussi.
7. Déploiement du Smart Contract
Maintenant que notre contrat est écrit et testé, nous pouvons le déployer sur un réseau blockchain. Nous allons commencer par le déployer sur un réseau de test public, comme Sepolia ou Goerli, qui simule le Mainnet Ethereum.
7.1 Préparation au Déploiement
Pour déployer sur un réseau de test, vous avez besoin de :
- Fonds sur le réseau de test (Ether de test) : Vous pouvez en obtenir gratuitement via des "faucets" (robinets) en ligne, par exemple
faucet.sepolia.devpour Sepolia. - Un compte Ethereum (clé privée) : L'adresse Ethereum associée à cette clé privée sera l'expéditeur de la transaction de déploiement et paiera les frais de gaz.
- Un nœud Ethereum (ou un service RPC) : Pour interagir avec le réseau, nous utiliserons un fournisseur de services comme Infura ou Alchemy. Ils vous donnent une URL RPC pour se connecter à leur nœud.
Obtenir une clé privée :
- Si vous utilisez MetaMask, vous pouvez exporter la clé privée d'un compte (attention : ne partagez jamais votre clé privée en production !).
- Pour les projets de développement, il est courant d'utiliser une variable d'environnement pour stocker la clé privée de manière sécurisée.
Obtenir une URL RPC :
- Rendez-vous sur Infura ou Alchemy.
- Créez un compte gratuit.
- Créez un nouveau projet et sélectionnez le réseau Sepolia (ou Goerli).
- Copiez l'URL HTTPS du point de terminaison RPC.
7.2 Configuration de Hardhat pour le Déploiement
Nous devons mettre à jour le fichier hardhat.config.js pour inclure les détails de notre réseau de test.
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config(); // Pour charger les variables d'environnement
const SEPOLIA_RPC_URL = process.env.SEPOLIA_RPC_URL;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.24",
networks: {
sepolia: {
url: SEPOLIA_RPC_URL || "", // Votre URL RPC Sepolia
accounts: PRIVATE_KEY ? [PRIVATE_KEY] : [], // Votre clé privée
chainId: 11155111, // ID de chaîne pour Sepolia
},
// Vous pouvez ajouter d'autres réseaux ici si nécessaire
},
};
Sécuriser votre clé privée et URL RPC :
-
Créez un fichier
.envà la racine de votre projet. -
Ajoutez vos variables d'environnement dedans :
SEPOLIA_RPC_URL="https://sepolia.infura.io/v3/VOTRE_ID_INFURA" PRIVATE_KEY="VOTRE_CLE_PRIVEE_ICI" -
Très important : Ajoutez
.envà votre fichier.gitignorepour ne jamais le pousser sur GitHub !# .gitignore node_modules/ .env artifacts/ cache/
7.3 Écriture du Script de Déploiement
Hardhat utilise des scripts pour le déploiement. Un script de déploiement est un fichier JavaScript qui utilise ethers.js pour interagir avec la blockchain.
Ouvrez le fichier scripts/deploy.js (si Hardhat l'a créé) ou créez-en un nouveau. Remplacez le contenu par :
const hre = require("hardhat"); // Hardhat Runtime Environment
async function main() {
// Récupérer la fabrique du contrat "SimpleStorage"
const SimpleStorage = await hre.ethers.getContractFactory("SimpleStorage");
console.log("Déploiement du contrat SimpleStorage...");
// Déployer le contrat
const simpleStorage = await SimpleStorage.deploy();
// Attendre que le contrat soit déployé (transaction confirmée)
await simpleStorage.waitForDeployment();
// Afficher l'adresse du contrat déployé
console.log(`Contrat SimpleStorage déployé à l'adresse : ${simpleStorage.target}`);
}
// Nous recommandons que ce modèle soit suivi pour gérer les erreurs.
// C'est un pattern courant pour les scripts Hardhat.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Explication du Script :
hre.ethers.getContractFactory("SimpleStorage"): Similaire au test, cela récupère l'objetContractFactorypour notre contrat.SimpleStorage.deploy(): Lance la transaction de déploiement du contrat.await simpleStorage.waitForDeployment(): Attend que la transaction de déploiement soit confirmée sur la blockchain.simpleStorage.target: Contient l'adresse à laquelle le contrat a été déployé.
7.4 Exécution du Déploiement
Assurez-vous que votre fichier .env est correctement configuré avec votre URL RPC et votre clé privée, et que vous avez des ETH de test sur le compte associé à votre clé privée sur le réseau Sepolia.
Dans votre terminal, exécutez la commande :
npx hardhat run scripts/deploy.js --network sepolia
Si tout se passe bien, vous devriez voir un message indiquant l'adresse à laquelle votre contrat a été déployé sur le réseau Sepolia. Vous pouvez ensuite copier cette adresse et la consulter sur un explorateur de blockchain comme Sepolia Etherscan.
Félicitations ! Vous venez de déployer votre premier Smart Contract sur un réseau de test public !
Conclusion
Vous avez franchi une étape majeure dans votre parcours Web3 ! Dans cette leçon, vous avez appris à :
- Définir et comprendre le rôle fondamental des Smart Contracts dans le paysage Web3.
- Mettre en place un environnement de développement Hardhat pour Solidity.
- Écrire un Smart Contract simple en Solidity pour stocker et récupérer une valeur.
- Compiler votre contrat en bytecode et ABI.
- Tester votre contrat pour garantir sa fiabilité.
- Déployer votre Smart Contract sur un réseau de test public comme Sepolia.
Ce contrat SimpleStorage n'est que la pointe de l'iceberg. Les concepts que vous avez appris ici – la structure du projet, l'écriture Solidity, le test et le déploiement – sont les piliers pour construire des DApps beaucoup plus complexes.
Dans les prochaines leçons, nous explorerons comment interagir avec ce Smart Contract depuis une application front-end (par exemple, en utilisant React et Ethers.js), comment créer des contrats plus sophistiqués (comme des jetons ERC-20), et les meilleures pratiques de sécurité pour le développement de Smart Contracts.
Ressources Supplémentaires
- Documentation Hardhat : hardhat.org/docs
- Documentation Solidity : docs.soliditylang.org
- Ethers.js : docs.ethers.org (La bibliothèque JavaScript utilisée par Hardhat pour interagir avec Ethereum)
- Sepolia Faucet : faucet.sepolia.dev
- Sepolia Etherscan : sepolia.etherscan.io