/The-Blockchain-Lottery

🎟 A decentralized lottery on the Ethereum blockchain using Chainlink VRF

Primary LanguageJavaScript

The Blockchain Lottery

Un système de loterie décentralisé sur la blockchain publique Ethereum.

IMPORTANT : ce projet est uniquement à but pédagogique et tente de mettre en lumière les potentiels de la technologie blockchain. Il s'inspire notamment du tutoriel https://blog.chain.link/how-to-build-a-blockchain-lottery-2/. Je tiens à préciser que l'intégralité du code n'a ni été suffisamment testé, ni audité, et pourrait présenter des anomalies. De plus, les loteries sont des pratiques commerciales hautement réglementées dans la plupart des pays, dont en France. Vous êtes seul responsable de l'utilisation que vous pourrez en faire !

I. La blockchain : une ( r )Ă©volution

Blockchain France définit la blockchain comme « une technologie de stockage et de transmission d’informations, transparente, sécurisée, et fonctionnant sans organe central de contrôle ». Il s'agit d'une base de données décentralisée et distribuée au sein d'un réseau pair à pair (Bitcoin, Ethereum...), qui contient l'historique de toutes les informations (transactions, titres de propriété, contrats...) effectuées entre ses utilisateurs depuis sa création. Ces informations sont validées par les participants du réseau (les noeuds) selon un algorithme de consensus inscrit dans son protocole, et s'appuyent sur la cryptographie (fonctions de hachage) pour garantir leur intégrité. Pour une démonstration visuelle, voir : https://andersbrownworth.com/blockchain/

Ses fondements s’articulent autour de 6 grands principes :

  • Un registre distribuĂ©, consultable par tous, et contenant un historique de tous les Ă©changes effectuĂ©s entre ses utilisateurs,
  • Le consensus : la validation des Ă©changes rĂ©sulte d’un consensus distribuĂ© et non plus d’une autoritĂ© centrale qui garde le contrĂ´le total sur les donnĂ©es (cela en fait notamment un formidable outil anti-censure),
  • L’immuabilitĂ© : il est impossible de modifier ou supprimer des Ă©critures une fois validĂ©es et enregistrĂ©es dans le registre (Ă  moins d'une attaque des 51%),
  • La sĂ©curitĂ©,
  • La dĂ©sintermĂ©diation : les autoritĂ©s de confiance historiques (avocats, notaires, banques, assurances...) sont "remplacĂ©es" par des programmes informatiques basĂ©s sur des calculs purement mathĂ©matiques,
  • La transparence et la confiance.

Le Bitcoin reste sans doute aujourd'hui l'utilisation la plus connue de la technologie blockchain.

II. QUID des smarts contracts ?

Un smart contract (contrat "intelligent") n'est ni plus ni moins qu'un programme informatique stocké à une adresse sur la blockchain et dont le protocole assure qu'il s'exécutera automatiquement et quoiqu'il arrive dès lors que les conditions codées dans le contrat sont réunies (puisqu'on ne peut plus modifier le code et donc empêcher son exécution une fois que le programme est stocké sur la blokchain).

Couplé à d'autres technologies, comme par exemple les objets connectés, les smart contracts promettent de disrupter de nombreux secteurs. L'exemple le plus simple est peut-être celui des assurances paramétriques : nous pourrions alors imaginer un contrat qui rembourse automatiquement, instantanément et sans contestation possible une somme P à un groupe d'agriculteurs G dès lors qu'il n'a pas plu une certaine quantité d'eau Q dans une zone géographique Z, sur une période de temps T et pendant plus de X jours d'affilés. Tous ces paramètres seraient bien entendu définis à l'avance et inscrits dans le contrat. Le contrat serait ensuite nourri par des données fournies par des API météo et communiquées par l'intermédiaire d'un réseau d'Oracles, puis s'exécuterait de manière autonome dès lors que les conditions seraient remplies.

Nous tenterons ici d'explorer l'ensemble de ces promesses à travers un projet de moins grande envergure : une loterie décentralisée sur la blockchain Ethereum.

III. Une loterie décentralisée : quel intérêt ?

L'organisation d'une loterie peut soulever un certain nombre de problématiques :

  • Qu'est-ce qui nous garantit que le vainqueur sera bien choisi au hasard ?
  • Quelle mĂ©thode est utilisĂ©e pour le tirage au sort ? Est-elle vraiment Ă©quitable pour tous ?
  • Les organisateurs de la loterie ou l'huissier en charge du contrĂ´le du tirage au sort sont-ils des personnes fiables ?
  • Le système de tirage au sort est-il sĂ©curisĂ© ?
  • Ai-je au moins la garantie de recevoir mon argent si je suis tirĂ© au sort ? Et dans quels dĂ©lais ?

De plus, elle demande, dans un système traditionnel et centralisé, de mobiliser de nombreuses ressources pour assurer la vente et la distribution des tickets, ou encore la maintenance et la sécurité des serveurs sur lesquels sont stockées les données afin de prévenir d'éventuelles attaques informatiques (piratage et corruption des données, modification du vainqueur, détournement des fonds récoltés...).

A l'inverse, dans un système décentralisé, quelques heures de travail et un développeur suffisent pour organiser une loterie au moins aussi sécurisée et complètement autonome sur la blockchain Ethereum :

schema-blockchain-lottery.png

Ainsi, une loterie décentralisée sur la blockchain permet de résoudre à moindre coût l'ensemble des problématiques évoquées.

IV. Stack technique du projet

a. Côté front-end :

Nous retrouverons côté front-end une application classique développée avec la librairie React.js. Afin d'intéragir avec la blockchain Ethereum (testnet Kovan) et faire appel aux méthodes de notre contrat de loterie, nous utiliserons la librairie Ethers.js. Nous devrons également pour cela nous fournir une clé API sur Alchemy, Etherscan, et Infura afin de nous connecter à des noeuds du réseau. Enfin, nous utiliserons l'extension Metamask sur notre navigateur web pour gérer un portefeuille qui nous permettra d'acheter un ticket de loterie et de tester notre application.

b. Côté Ethereum :

Nos contrats permettant de gérer notre loterie seront écrits avec le langage de programmation Solidity, créé pour Ethereum. Afin de faciliter le développement du projet et le déploiement des contrats sur le testnet d'Ethereum Kovan, nous utiliserons la suite Truffle. Pour le déploiement, nous utiliserons là encore Infura avec la même clé API.

Enfin, nos contrats intègreront plusieurs fonctionnalités du réseau d'Oracles décentralisé Chainlink, sans lequel notre loterie ne pourrait pas fonctionner :

  • Alarm Clock (testnet) : qui nous permettra de dĂ©clencher la fin de la loterie Ă  une heure programmĂ©e lors du dĂ©ploiement du contrat,
  • Chainlink VRF : qui nous permettra de gĂ©nĂ©rer un nombre alĂ©atoire pour sĂ©lectionner le gagnant Ă  qui transfĂ©rer les fonds de la loterie (et dont le caractère alĂ©toire du nombre gĂ©nĂ©rĂ© pourra ĂŞtre vĂ©rifiĂ© publiquement sur la blockchain).

Note : pour une très bonne introduction à Chainlink et plus globalement, comprendre l'importance des Oracles et leurs enjeux, lire : Completing The God Protocols: A Comprehensive Overview of Chainlink in 2021

V. Installation

Avant de poursuivre : n'oubliez pas de vous inscrire sur Alchemy, Etherscan et Infura afin de récupérer vos clés API. Vous aurez également besoin d'un portefeuille Ethereum afin de déployer les contrats (que vous pouvez créer ici).

Commencez par cloner ce repository :

$ git clone git@github.com:fligflug/TheBlockchainLottery.git

a. Côté Ethereum

Une fois à la racine du projet, exécutez les commandes suivantes :

$ cd ethereum/
$ cp .env.dev .env 
$ npm install 

Dans votre fichier .env, renseignez les informations suivantes :

CREATOR_PRIVATE_KEY="" # clé privée du portefeuille avec lequel vous allez déployer les contrats ; 
INFURA_ENDPOINT="" # lien https Ă  retrouver dans votre projet Infura > onglet settings > rubrique keys > endpoints (choisir "Kovan")
LOTTERY_CONTRACT_ADDRESS="" # adresse du contrat de loterie ; à renseigner après le déploiement
LOTTERY_TICKET_PRICE="" # le prix du ticket, en Ether et non en wei (par exemple, 0.01)
LOTTERY_DURATION="" # la durée de la loterie, en secondes (par exemple, 3600 pour une heure)

IMPORTANT : bien entendu, votre fichier .env ne devrait pas être versionné. Aussi, si vous disposez d'un portefeuille personnel et que vous l'utilisez pour déployer les contrats (déconseillé), ne laissez surtout pas trainer votre clé privée !!! :)

Puis exécutez la commande suivante :

$ truffle compile
$ truffle migrate --network kovan 

Suivez enfin les instructions affichées dans le terminal en fin de commande :

   > [OK] contract deployed on Kovan testnet network (see https://kovan.etherscan.io)
   > Next, fund the following contracts with Chainlink Kovan Faucet (see https://kovan.chain.link/): # vous devrez envoyer des faux jetons link (valables uniquement sur le testnet Kovan) à vos contrats qui utiliseront les fonctionnalités du réseau d'Oracles décentralisé Chainlink
   > Lottery contract: # [adresse de votre contrat de loterie]
   > RandomNumberConsumer contract: # [adresse de votre contrat en charge de générer le nombre aléatoire (appelé par votre contrat de loterie)]
   > /!\ Do not forget to add the lottery contract address in your .env file. You can also set the ticket price and duration you want. # Vous pouvez désormais ajouter l'adresse de votre contrat de loterie dans votre .env.LOTTERY_CONTRACT_ADDRESS
   > Then, fund the following wallet with Ethereum Kovan faucet (see https://faucet.kovan.network/): # vous devrez envoyer des faux eth sur votre portefeuille pour démarrer la loterie (attention : seul l'adresse utilisée pour déployer les contrats détient le droit de démarrer la loterie)
   > Wallet: [portefeuille utilisé pour déployer les contrats]
   > This wallet will serve to start the new lottery: 
   > To do that, finally run start_lottery.js script with truffle exec cmd. # voir partie b. Côté front-end

b. Côté front-end

Une fois à la racine du projet, exécutez les commandes suivantes :

$ cd ../front-end/
$ cp .env.dev .env 
$ npm install 

Dans votre fichier .env, renseignez les informations suivantes :

REACT_APP_ENV="" # DEV pour le debug en console
REACT_APP_LOTTERY_CONTRACT_ADDRESS="" # adresse du contrat de loterie 
REACT_APP_INFURA_PROJECT_ID="" # clé project ID de votre projet Infura
REACT_APP_ALCHEMY_API_KEY="" # API key de votre compte Alchemy
REACT_APP_ETHERSCAN_API_KEY="" # API key de votre compte Etherscan

Puis exécutez les commandes suivantes :

$ npm start # votre app react sera disponible sur http://localhost:3000/ 
$ cd ../ethereum/
$ truffle exec ./scripts/start_lottery.js --network kovan

Votre loterie est désormais lancée, et vous n'avez plus rien à faire ! Le gagnant sera automatiquement désigné à l'heure programmée et les fonds transférés dans la foulée. Magique, non ?

VI. DĂ©monstration

Voir la démo

VII. Comment améliorer ce projet ?

Je rappelle que ce projet n'est qu'un prototype à but pédagogique. Il ne respecte donc pas forcément toutes les bonnes pratiques en matière de développement. Voici quelques pistes pour l'améliorer :

  • En prioritĂ© : Ă©crire des tests ! Cet article constituera certainement un bon point de dĂ©part sur les diffĂ©rentes techniques pouvant ĂŞtre utilisĂ©es pour tester des smart contracts avec Chainlink (qui rend la tâche un peu plus compliquĂ©e),
  • Ajouter une fonctionnalitĂ© permettant aux participants de payer leur ticket avec d'autres tokens ERC-20,
  • Ajouter une fonctionnalitĂ© permettant d'acheter, avec un mĂŞme portefeuille, plusieurs tickets afin d'augmenter ses chances d'ĂŞtre tirĂ© au sort,
  • IntĂ©grer d'autres types de wallet,
  • CrĂ©er une interface cĂ´tĂ© front-end permettant Ă  des administrateurs de crĂ©er une nouvelle loterie (piste : crĂ©er un smart contract qui servira de factory).

Flig Flug.