Comment créer une chaîne de blocs de crypto-monnaie simple dans Node.js
Publié: 2022-03-10smashingCoin
, en utilisant les concepts de classes JavaScript et Node.js. Essayez-le - c'est plus simple que vous ne le pensez!La montée sans précédent des crypto-monnaies et leur technologie de blockchain sous-jacente ont pris d'assaut le monde - depuis les humbles débuts d'un concept académique il y a plus de dix ans jusqu'à l'adoption croissante actuelle dans diverses industries.
La technologie blockchain fait l'objet de beaucoup d'attention en raison de sa capacité à renforcer la sécurité dans des environnements sans confiance, à appliquer la décentralisation et à rendre les processus efficaces.
Traditionnellement, Python a été le langage de programmation de facto pour le développement de la blockchain. Cependant, avec la prolifération de cette technologie étonnante, les options de développement ont également augmenté - et Node.js n'a pas été laissé pour compte.
Dans ce didacticiel, je vais vous expliquer comment créer une chaîne de blocs de crypto-monnaie simple dans Node.js. Ce ne sera pas trop sophistiqué, mais juste suffisant pour vous aider à comprendre le fonctionnement d'une blockchain.
J'appellerai cette simple crypto-monnaie smashingCoin
.
Si vous êtes un développeur JavaScript qui souhaite faire un saut dans le domaine en plein essor de la crypto-monnaie, cet article vous fournira les compétences nécessaires pour commencer. Ou, si vous êtes curieux de savoir comment les choses fonctionnent dans le monde des crypto-monnaies, ce tutoriel peut vous aider à répondre à certaines de vos questions.
Lecture recommandée : Comprendre l'intégrité des sous-ressources par Drew McLellan
Conditions préalables
Pour suivre ce tutoriel avec succès, vous aurez besoin des éléments suivants :
- Node.js installé sur votre machine. Vous pouvez le télécharger à partir d'ici;
- Un éditeur de code, tel que Visual Studio Code, Sublime Text ou tout autre.
Commençons…
Qu'est-ce qu'une blockchain ?
La blockchain est la technologie qui alimente les monnaies numériques, telles que Bitcoin et Ethereum. Il s'agit d'une technologie innovante de grand livre public distribué qui maintient une liste croissante d'enregistrements, appelés blocs, qui sont connectés en toute sécurité à l'aide de la cryptographie.
Le terme blockchain a gagné son nom en raison de la manière dont il conserve les données de transaction, c'est-à-dire dans des blocs qui sont connectés les uns aux autres pour créer une chaîne . La taille de la blockchain augmente avec l'augmentation du nombre de transactions effectuées.
Toutes les données de transaction valides sont enregistrées dans le réseau blockchain, qui est régi par des règles peer-to-peer que les participants stipulent. Par exemple, ces données peuvent contenir la « valeur » du bloc, comme dans les monnaies numériques, un enregistrement des transactions (comme lorsque les parties échangent des biens et des services) ou des privilèges de droit, comme lorsque la chaîne enregistre les informations de propriété.
Outre les données de transaction, chaque bloc peut contenir son propre hachage cryptographique (un identifiant unique ou une empreinte numérique), sa propre valeur nonce (un nombre aléatoire arbitraire utilisé une fois dans les calculs cryptographiques), le hachage du bloc précédent et un horodatage des dernières opérations authentifiées.
Étant donné que chaque nouveau bloc doit pointer vers le bloc précédent, si un bloc est incorporé dans la chaîne sans contenir le bon hachage du dernier bloc, cela pourrait rendre l'ensemble de la blockchain invalide. Cette propriété d'immuabilité est la clé de la sécurité des blockchains.
De plus, divers types de protocoles de consensus sont souvent appliqués pour maintenir l'authenticité de la blockchain. Le consensus garantit que tous les participants acceptent les transactions validées par le réseau.
Par exemple, un protocole de consensus couramment utilisé est la preuve de travail, qui vise à identifier un nombre qui trouve une solution à un problème mathématique compliqué après avoir terminé une certaine quantité de travail informatique.
L'idée principale du travail de preuve est que tout participant au réseau blockchain devrait trouver ce numéro difficile à identifier mais facilement vérifiable. Par conséquent, cela décourage le spam et la falsification de la structure de la blockchain.
Dans le cas de la plupart des crypto-monnaies, l'ajout d'un nouveau bloc à la blockchain nécessite de résoudre une équation mathématique complexe, dont la difficulté augmente avec le temps à mesure que la blockchain se développe. Par conséquent, toute personne qui prouve qu'elle a travaillé en résolvant ce problème est compensée par une monnaie numérique, dans un processus appelé « minage ».
Comment créer un bloc
Maintenant, après avoir présenté la technologie blockchain et son fonctionnement, voyons comment nous pouvons appliquer les concepts pour créer un bloc. Comme mentionné précédemment, les blocs sont ce qui s'interconnecte pour former une blockchain.
Pour créer la devise smashingCoin
, j'utiliserai les classes JavaScript, qui ont été introduites dans ES6.
Prêt?
Mettons-nous les mains dans le cambouis…
Voici le code de la classe CryptoBlock
:
const SHA256 = require('crypto-js/sha256'); class CryptoBlock{ constructor(index, timestamp, data, precedingHash=" "){ this.index = index; this.timestamp = timestamp; this.data = data; this.precedingHash = precedingHash; this.hash = this.computeHash(); } computeHash(){ return SHA256(this.index + this.precedingHash + this.timestamp + JSON.stringify(this.data)).toString(); } }
Comme vous pouvez le voir dans le code ci-dessus, j'ai créé la classe CryptoBlock
et y ai ajouté la méthode constructor()
- comme cela se fait dans n'importe quelle autre classe JavaScript. Ensuite, pour initialiser ses propriétés, j'ai assigné les paramètres suivants à la méthode constructor
:
index | C'est un numéro unique qui suit la position de chaque bloc dans l'ensemble de la blockchain. |
timestamp | Il conserve un enregistrement de l'heure d'occurrence de chaque transaction terminée. |
data | Il fournit des données sur les transactions terminées, telles que les détails de l'expéditeur, les détails du destinataire et la quantité traitée. |
precedingHash | Il pointe vers le hachage du bloc précédent dans la blockchain, quelque chose d'important pour maintenir l'intégrité de la blockchain. |
De plus, j'ai utilisé la méthode computeHash
pour calculer le hachage du bloc en fonction de ses propriétés, comme indiqué dans les données ci-dessus.
Comme vous pouvez le voir, j'ai importé la bibliothèque JavaScript crypto-js et utilisé son module crypto-js/sha256
pour calculer le hachage de chaque bloc. Comme le module renvoie un objet numérique, j'ai utilisé la toString()
pour le convertir en chaîne.
Pour ajouter la bibliothèque crypto-js à votre projet, allez dans le terminal et exécutez la commande suivante pour l'installer à l'aide de npm
:
npm install --save crypto-js
Après avoir exécuté la commande ci-dessus, le répertoire des modules du nœud, qui contient la bibliothèque et d'autres fichiers essentiels, sera ajouté au dossier de votre projet.
Comment créer une chaîne de blocs
Comme expliqué précédemment, la technologie blockchain est basée sur le concept selon lequel tous les blocs sont enchaînés les uns aux autres. Créons donc une classe CryptoBlockchain
qui sera chargée de gérer les opérations de toute la chaîne. C'est là que le caoutchouc va rencontrer la route.
La classe CryptoBlockchain
maintiendra les opérations de la blockchain en utilisant des méthodes d'assistance qui accomplissent différentes tâches, telles que la création de nouveaux blocs et leur ajout à la chaîne.
Voici le code de la classe CryptoBlockchain
:
class CryptoBlockchain{ constructor(){ this.blockchain = [this.startGenesisBlock()]; } startGenesisBlock(){ return new CryptoBlock(0, "01/01/2020", "Initial Block in the Chain", "0"); } obtainLatestBlock(){ return this.blockchain[this.blockchain.length - 1]; } addNewBlock(newBlock){ newBlock.precedingHash = this.obtainLatestBlock().hash; newBlock.hash = newBlock.computeHash(); this.blockchain.push(newBlock); } }
Permettez-moi de parler des rôles de chacune des méthodes d'assistance qui constituent la classe CryptoBlockchain
.
1. Méthode constructeur
Cette méthode instancie la blockchain. À l'intérieur du constructeur, j'ai créé la propriété blockchain
, qui fait référence à un tableau de blocs. Notez que je lui ai passé la méthode startGenesisBlock()
, qui crée le bloc initial dans la chaîne.
2. Création du bloc Genesis
Dans une blockchain, le bloc de genèse fait référence au tout premier bloc créé sur le réseau. Chaque fois qu'un bloc est intégré au reste de la chaîne, il doit faire référence au bloc précédent.
Inversement, dans le cas de ce bloc initial, il n'a pas de bloc précédent vers lequel pointer. Par conséquent, un bloc de genèse est généralement codé en dur dans la blockchain. De cette façon, des blocs ultérieurs peuvent être créés dessus. Il a généralement un indice de 0.
J'ai utilisé la méthode startGenesisBlock()
pour créer le bloc de genèse. Notez que je l'ai créé en utilisant la classe CryptoBlock
créée ci-dessus et que j'ai passé les paramètres index
, timestamp
, data
et precedingHash
.
3. Obtention du dernier bloc
L'obtention du dernier bloc de la blockchain permet de s'assurer que le hachage du bloc actuel pointe vers le hachage du bloc précédent, maintenant ainsi l'intégrité de la chaîne.
J'ai utilisé la méthode obtainLatestBlock()
pour le récupérer.
4. Ajouter de nouveaux blocs
J'ai utilisé la méthode addNewBlock()
pour ajouter un nouveau bloc à la chaîne. Pour ce faire, j'ai défini le hachage précédent du nouveau bloc pour qu'il soit égal au hachage du dernier bloc de la chaîne, garantissant ainsi que la chaîne est inviolable.
Étant donné que les propriétés du nouveau bloc sont modifiées à chaque nouveau calcul, il est important de recalculer son hachage cryptographique. Après avoir mis à jour son hachage, le nouveau bloc est poussé dans le tableau blockchain.
En réalité, ajouter un nouveau bloc à une blockchain n'est pas si simple à cause des nombreux contrôles qui ont été effectués. Néanmoins, pour cette simple crypto-monnaie, il suffit de démontrer comment fonctionne réellement une blockchain.
Tester la Blockchain
Maintenant, testons notre blockchain simple et voyons si cela fonctionne.
Voici le code :
let smashingCoin = new CryptoBlockchain(); smashingCoin.addNewBlock(new CryptoBlock(1, "01/06/2020", {sender: "Iris Ljesnjanin", recipient: "Cosima Mielke", quantity: 50})); smashingCoin.addNewBlock(new CryptoBlock(2, "01/07/2020", {sender: "Vitaly Friedman", recipient: "Ricardo Gimenes", quantity: 100}) ); console.log(JSON.stringify(smashingCoin, null, 4));
Comme vous pouvez le voir dans le code ci-dessus, j'ai créé une nouvelle instance de la classe CryptoBlockchain
et l'ai nommée smashingCoin
. Ensuite, j'ai ajouté deux blocs dans la blockchain en utilisant des valeurs arbitraires. Dans le paramètre data
, j'ai utilisé un objet et ajouté les détails de l'expéditeur, les détails du destinataire et la quantité traitée.
Si j'exécute le code sur le terminal, voici la sortie que j'obtiens :
Voilà à quoi ressemble le smashingCoin
! C'est un objet qui contient la propriété blockchain
, qui est un tableau contenant tous les blocs de la chaîne. Comme vous pouvez le voir dans l'image ci-dessus, chaque bloc fait référence au hachage du bloc précédent. Par exemple, le deuxième bloc fait référence au hachage du premier bloc. Après avoir testé et vu que notre blockchain fonctionne, ajoutons quelques fonctionnalités supplémentaires pour améliorer les fonctionnalités du smashingCoin
.
Comment vérifier l'intégrité de la blockchain
Comme mentionné précédemment, une caractéristique clé d'une blockchain est qu'une fois qu'un bloc a été ajouté à la chaîne, il ne peut pas être modifié sans invalider l'intégrité du reste de la chaîne.
Par conséquent, pour vérifier l'intégrité de la blockchain, je vais ajouter une méthode checkChainValidity()
à la classe CryptoBlockchain
.
Les hachages sont essentiels pour assurer la validité et la sécurité d'une blockchain, car tout changement dans le contenu d'un bloc entraînera la production d'un hachage entièrement nouveau et l'invalidation de la blockchain.
Ainsi, la méthode checkChainValidity()
utilisera les instructions if
pour vérifier si le hachage de chaque bloc a été falsifié. À partir du premier bloc créé, il bouclera sur l'ensemble de la blockchain et vérifiera sa validité. Notez que puisque le bloc genesis a été codé en dur, il ne sera pas vérifié.
De plus, la méthode vérifiera si les hachages de chacun des deux blocs consécutifs pointent l'un vers l'autre. Si l'intégrité de la blockchain n'a pas été compromise, elle renvoie true ; sinon, en cas d'anomalies, il renvoie false.
Voici le code :
checkChainValidity(){ for(let i = 1; i < this.blockchain.length; i++){ const currentBlock = this.blockchain[i]; const precedingBlock= this.blockchain[i-1]; if(currentBlock.hash !== currentBlock.computeHash()){ return false; } if(currentBlock.precedingHash !== precedingBlock.hash) return false; } return true; }
Comment ajouter une preuve de travail
Comme mentionné précédemment, la preuve de travail est le concept appliqué pour augmenter la difficulté liée à l'extraction ou à l'ajout de nouveaux blocs à la blockchain.
Dans le cas de smashingCoin
, j'utiliserai un algorithme simple qui dissuade les gens de générer facilement de nouveaux blocs ou de spammer la blockchain.
Ainsi, dans la classe CryptoBlock
, j'ajouterai une autre méthode appelée proofOfWork().
Essentiellement, cet algorithme simple identifie un nombre, transmis comme propriété de difficulty
, de sorte que le hachage de chaque bloc contienne des zéros non significatifs correspondant à ce niveau de difficulty
.
S'assurer que le hachage de chaque bloc commence par le nombre de zéros défini dans le niveau de difficulty
nécessite une grande puissance de calcul. Plus le niveau de difficulté est élevé, plus il faut de temps pour extraire de nouveaux blocs.
De plus, j'ajouterai une valeur nonce
aléatoire à chaque bloc haché de sorte que, lors du rehachage, les restrictions de niveau de difficulté puissent toujours être respectées.
Voici le code :
proofOfWork(difficulty){ while(this.hash.substring(0, difficulty) !==Array(difficulty + 1).join("0")){ this.nonce++; this.hash = this.computeHash(); } }
Et voici la méthode computeHash()
mise à jour avec la variable nonce
incluse :
computeHash(){ return SHA256(this.index + this.precedingHash + this.timestamp + JSON.stringify(this.data)+this.nonce).toString(); }
De plus, pour implémenter le mécanisme de preuve de travail dans la génération de nouveaux blocs, je l'inclurai dans la méthode addNewBlock()
:
addNewBlock(newBlock){ newBlock.precedingHash = this.obtainLatestBlock().hash; //newBlock.hash = newBlock.computeHash(); newBlock.proofOfWork(this.difficulty); this.blockchain.push(newBlock); }
Emballer
Voici le code complet pour créer la crypto-monnaie smashingCoin
à l'aide de Node.js :
const SHA256 = require("crypto-js/sha256"); class CryptoBlock { constructor(index, timestamp, data, precedingHash = " ") { this.index = index; this.timestamp = timestamp; this.data = data; this.precedingHash = precedingHash; this.hash = this.computeHash(); this.nonce = 0; } computeHash() { return SHA256( this.index + this.precedingHash + this.timestamp + JSON.stringify(this.data) + this.nonce ).toString(); } proofOfWork(difficulty) { while ( this.hash.substring(0, difficulty) !== Array(difficulty + 1).join("0") ) { this.nonce++; this.hash = this.computeHash(); } } } class CryptoBlockchain { constructor() { this.blockchain = [this.startGenesisBlock()]; this.difficulty = 4; } startGenesisBlock() { return new CryptoBlock(0, "01/01/2020", "Initial Block in the Chain", "0"); } obtainLatestBlock() { return this.blockchain[this.blockchain.length - 1]; } addNewBlock(newBlock) { newBlock.precedingHash = this.obtainLatestBlock().hash; //newBlock.hash = newBlock.computeHash(); newBlock.proofOfWork(this.difficulty); this.blockchain.push(newBlock); } checkChainValidity() { for (let i = 1; i < this.blockchain.length; i++) { const currentBlock = this.blockchain[i]; const precedingBlock = this.blockchain[i - 1]; if (currentBlock.hash !== currentBlock.computeHash()) { return false; } if (currentBlock.precedingHash !== precedingBlock.hash) return false; } return true; } } let smashingCoin = new CryptoBlockchain(); console.log("smashingCoin mining in progress...."); smashingCoin.addNewBlock( new CryptoBlock(1, "01/06/2020", { sender: "Iris Ljesnjanin", recipient: "Cosima Mielke", quantity: 50 }) ); smashingCoin.addNewBlock( new CryptoBlock(2, "01/07/2020", { sender: "Vitaly Friedman", recipient: "Ricardo Gimenes", quantity: 100 }) ); console.log(JSON.stringify(smashingCoin, null, 4));
Si j'exécute le code sur le terminal, voici la sortie que j'obtiens :
Comme vous pouvez le voir sur l'image ci-dessus, les hachages commencent maintenant par quatre zéros, ce qui correspond au niveau de difficulté défini dans le mécanisme de preuve de travail.
Conclusion
C'est ça! C'est ainsi que vous pouvez créer une chaîne de blocs de crypto-monnaie simple à l'aide de Node.js.
Bien sûr, la crypto-monnaie smashingCoin
est loin d'être complète. En fait, si vous le publiez sans apporter plus d'améliorations, il est peu probable qu'il réponde aux demandes actuelles du marché pour une monnaie numérique sécurisée, fiable et intuitive, ce qui fait de vous le seul à l'utiliser !
Néanmoins, j'espère que ce tutoriel vous a doté de quelques compétences de base pour vous familiariser avec le monde passionnant des cryptos.
Si vous avez des commentaires ou des questions, veuillez les poster ci-dessous.
Autres ressources
- "Blockchain 101", CoinDesk
- "Bitcoin : un système de paiement électronique peer-to-peer", Satoshi Nakamoto, Bitcoin.org