Passer au contenu principal




Dans cette première partie de la série Blockchain Javascript, nous couvrirons le objet de bloc et le objet blockchain et nous discuterons de sa structure et de ses implications.

Je crois fermement en l'idée que la meilleure façon d'apprendre une technologie est de la construire. Naturellement, mon intérêt pour la technologie blockchain m'a conduit à essayer de construire ma propre blockchain. Je vais vous guider à travers les étapes pour créer une blockchain de base avec un système de preuve de travail intégré. En cours de route, je discuterai des implications des différentes fonctionnalités.

De quoi avez-vous besoin?

  • La dernière version de Node.js (j'utilise la v8.7.0)
  • La dernière version de npm (Node Package Manager) (j'utilise la v5.6.0)

Créez un dossier appelé js-blockchain et créez un fichier appelé main.js Dans ce guide, nous utiliserons un seul fichier afin que vous puissiez toujours vous référer au code source si vous rencontrez des problèmes.

Structure de la blockchain

Les blockchains sont construites à l'aide d'une combinaison de listes chaînées et d'arbres de merkle. La structure de la liste chaînée permet à la chaîne de se construire continuellement sur elle-même et c'est de là que vient le nom blockchain. Ongle chaîne de bloc c'est littéralement une chaîne de blocs liés entre eux via la structure de liste chaînée. Une chose à noter, cependant, est qu'au lieu de tenir un pointeur traditionnel pour faire référence au bloc précédent, vous utilisez le hacher du bloc précédent pour y faire référence.

Si vous ne savez pas ce qu'est un hacher, voici un manuel. Les hachages sont simplement des fonctions déterministes qui créent des sorties spécifiques pour chaque entrée, et sont généralement irréversibles, ce qui signifie qu'il est extrêmement difficile de dériver l'entrée de la sortie. Ils sont essentiels au verrouillage de la chaîne, car ils sont la clé pour rendre la chaîne immuable et maintenir l'intégrité des données.

Un bloc comme objet

Nous allons d'abord créer un classe appelée Block qui aura une fonction constructeur, une fonction calculerHash et une fonction mineBlock. On part de la fonction constructeur qui instancie les objets Bloquer et vous fournit ses propriétés.

class Block {constructeur (horodatage, données) {this.index = 0; this.timestamp = horodatage; this.data = données; this.previousHash = "0"; this.hash = this.calculateHash (); this.nonce = 0; } CalculateHash () {} mineBlock (difficulté) {}}

Entrées de bloc

Chaque objet de bloc prend un horodatage et des données de bloc. L'horodatage indique quand le bloc a été créé. Ceci est utile, par exemple, dans Bitcoin (BTC), car BTC il est conçu pour être si difficile que le temps d'extraction moyen par bloc est de 10 minutes. Par conséquent, le système peut utiliser ces données de date et d'heure pour rééquilibrer la difficulté d'extraction chaque mois. Les données de bloc contiennent les informations stockées dans la chaîne. Dans de nombreuses devises comme BTC, C'est là que les données variables sont stockées sous la forme d'arbres de merkle.

Bloquer les données

Comme vous pouvez le voir, en plus des 3 champs de saisie, notre Objet de bloc contient également un indice, une hacher précédent, un hacher et un nonce. L'index communique où se trouve le bloc dans la chaîne. le hacher du bloc précédent est ce qui maintient l'intégrité de la chaîne. Le hachage de bloc contient simplement le hachage du bloc dérivé d'une fonction calculerHash. le nonce est un autre élément important du bloc qui est essentiel à la construction d'un mécanisme de minage pour notre blockchain que nous discuterons dans la partie 2: Construire votre propre blockchain en JavaScript - partie 2 de cette série. Pour l'instant, nous allons mettre notre variable nonce au 0.

Gardez à l'esprit que le hachage du bloc précédent est ce qui maintient l'intégrité de la chaîne. Pour vérifier l'intégrité de la chaîne, nous parcourons la chaîne en calculant le hachage de chaque bloc et en le comparant aux données de hachage précédentes. Si une seule information dans le bloc est modifiée, un hachage complètement différent sera craché et immédiatement détectable par rapport au données de hachage les fichiers précédents stockés dans le bloc qui suit le bloc modifié. Plus tard, nous créerons une fonction checkValide pour le prouver.

Bibliothèque Crypto-JS

Maintenant, nous allons ajouter une fonction calculerHash à notre bloc. Pour notre rôle hacher, nous emprunterons à la bibliothèque crypto-js et nous utiliserons votre fonction Hachage SHA256. La fonction de Hachage SHA256 a été développé par NSA y est une fonction de hacher irréversible. Ceci est utilisé dans l'exploitation minière BTC comme algorithme de preuve de travail et dans la création d'adresses de BTC grâce à votre sécurité.

Pour installer la bibliothèque crypto-js, allez dans votre terminal et entrez votre dossier js-blockchain puis installez la bibliothèque avec npm avec le code suivant:

npm install --save crypto-js

Ensuite, vous verrez le message suivant:

npm WARN saveError ENOENT: aucun fichier ou répertoire de ce type, ouvrez '/Users/spenserhuang/Desktop/js-blockchain/package.json'
npm WARN enoent ENOENT: aucun fichier ou répertoire de ce type, ouvrez '/Users/spenserhuang/Desktop/js-blockchain/package.json'
npm WARN js-blockchain Aucune description
npm WARN js-blockchain Pas de champ de référentiel.
npm WARN js-blockchain Pas de données README
npm WARN js-blockchain Pas de champ de licence.

+ [email protected]
mis à jour 1 paquet en 1,75s

Ne vous inquiétez pas de l'avertissement pour le moment car cela ne nous affectera pas dans le contexte de ce projet. L'erreur existe car le dossier que nous avons créé est extrêmement baronne et ne contient aucun fichier supplémentaire comme package.json ou d'autres fichiers de nœuds et de référentiels.

Calculer le hachage

Cependant, maintenant que la bibliothèque est installée, vous pouvez créer une constante SHA256 et extraire les informations directement avec une phrase exiger. Nous allons l'utiliser pour créer notre fonction calculerHash.

const SHA256 = require ('crypto-js / sha256') class Block {constructeur (horodatage, données) {this.index = 0; this.timestamp = horodatage; this.data = données; this.previousHash = "0"; this.hash = this.calculateHash (); this.nonce = 0; } CalculateHash () {return SHA256 (this.index + this.previousHash + this.timestamp + this.data + this.nonce) .toString (); } mineBlock (difficulté) {}}

Nous créons notre propre fonction appelée calculerHash que nous utiliserons pour donner à chaque bloc le sien hacher. Comme vous pouvez le voir avec la fonction, le hachage prend chaque morceau de l'objet bloc, le jette dans une fonction SHA256 et le convertit en une chaîne. Dans ce projet, nous tournons notre résultat SHA256 dans une chaîne, car les chaînes sont plus faciles à traiter et à combiner.

La fonction calculerHash vous acceptez CHAQUE une partie des données de bloc. En conséquence, si un élément de données est falsifié, même s'il s'agit d'un nouveau point décimal, le hachage du bloc sera immédiatement différent. C'est une excellente fonctionnalité pour sécuriser la blockchain.

Construire la blockchain

Maintenant que nous avons créé la structure de bloc individuelle, nous devons créer une structure, un Objet de classe Blockchain, pour les relier et créer la fonctionnalité de base fournie avec les blocs normaux. Pour garder les choses aussi simples que possible, notre blockchain n'en aura qu'un fonction constructeur, ongle fonction createGenesis, ongle fonction latestBlock, ongle fonction addBlock et une checkValid fonction.

Objet blockchain

Notre classe Blockchain Il a besoin de quelques fonctionnalités clés, à savoir la possibilité d'être instancié, de démarrer, d'accéder aux informations du bloc le plus récent et de s'étendre en y ajoutant un nouveau bloc.

class Blockchain {constructeur () {this.chain = [this.createGenesis ()]; } createGenesis () {return new Block (0, "01/01/2017", "Genesis block", "0")} latestBlock () {return this.chain [this.chain.length - 1]} addBlock (newBlock ) {newBlock.previousHash = this.latestBlock (). hash; newBlock.hash = newBlock.calculateHash (); this.chain.push (newBlock); } checkValid () {for (let i = 1; i <this.chain.length; i ++) {const currentBlock = this.chain [i]; const previousBlock = this.chain [i - 1]; if (currentBlock.hash! == currentBlock.calculateHash ()) {return false; } if (currentBlock.previousHash! == previousBlock.hash) {return false; }} retourne vrai; }}

Fonction constructeur

Premièrement, nous avons besoin d'une fonction de constructeur pour instancier notre blockchain. Ce sera une fonction simple qui crée simplement un objet de verrouillage avec la propriété chaîne dans une structure de liste. C'est la raison pour laquelle nos objets Bloquer ils avaient des indices. Les propriétés d'index de nos blocs sont utilisées pour trouver leur position dans notre liste de chaînes.

Créer la fonction Genesis

Deuxièmement, notre blockchain a besoin d'une fonction createGenesis ce qui crée le premier bloc de notre chaîne. Dans la convention blockchain, le premier bloc de toute chaîne est également connu sous le nom de «Bloc Genesis»d'où le nom createGenesis. Avec ce bloc, nous saisissons normalement vos informations manuellement. Puisqu'il s'agit du premier bloc de la chaîne, il a une valeur d'index de 0. Pour son horodatage et ses champs de données, nous pouvons mettre la date du jour et le «Bloc Genesis» ou ce que vous voulez. Comme sur le terrain Hacher ci-dessus, on peut simplement mettre «0» pour l'instant car il n'y a pas de hachage précédant le bloc Genesis.

Obtenez la dernière fonctionnalité de verrouillage

Troisièmement, notre chaîne a besoin d'une fonction latestBlock. Utilisé pour obtenir des informations sur le bloc le plus récent. Cette fonctionnalité sera utilisée pour implémenter notre fonctionnalité addBlock.

Ajouter une nouvelle fonction de bloc

Quatrièmement, pour étendre continuellement notre bloc, nous avons besoin d'une fonction addBlock. Les blockchains ont des fonctionnalités telles qu'elles ont besoin de s'allonger de plus en plus à mesure que davantage d'informations y sont entrées. Ainsi, dans le cas de BTC, par exemple, un nouveau bloc est créé environ toutes les 10 minutes et chacun de ces nouveaux blocs contiendra toutes les informations de la transaction qui a eu lieu dans cette période de 10 minutes.

La mise en œuvre d'une fonction addBlock est simple. Notre fonction prend un objet Bloquer comme une entrée qui a déjà un horodatage et des données. Puis notre fonction addBlock utilisera la fonction latestBlock pour donner à notre nouveau bloc un index et un champ Hacher précédent. Après cela, nous donnons le sien à notre nouveau bloc hacher en utilisant la fonction calculerHash que nous avons écrit plus tôt. Enfin, nous poussons ce nouveau bloc sur notre chaîne et maintenant notre blockchain a un nouveau bloc.

Fonction de contrôle de validité

La fonction finale que nous allons implémenter est la fonction checkValid. Ceci est utilisé pour vérifier l'intégrité de la blockchain et pour détecter si quelque chose a été falsifié.

Comme indiqué ci-dessus, le hachages sont essentiels pour détecter les modifications de notre blockchain, car même le plus petit changement de l'objet entraînera un hacher complètement différent. Par conséquent, pour notre fonction checkValide, nous utiliserons une boucle pour passer à travers la blockchain et nous essaierons de faire correspondre leur hachages pour détecter les changements.

Il y a deux parties dans notre boucle, la première est de correspondre currentBlock.hash avec currentBlock.calculateHash () et l'autre est de correspondre currentBlock.previousHash avec previousBlock.hash. Le premier permet de vérifier si les informations de currentBlock a été falsifié sans mise à jour currentBlock.hash Le second permet de vérifier si un bloc précédent a été altéré ou non.

Vous pouvez avoir la question de savoir si oui ou non il peut mettre dans la condition if

if (currentBlock.previousHash! == previousBlock.calculateHash ()) {return false; }

Cela semble théoriquement que cela devrait fonctionner. Cependant, précédentBlock il s'agit en fait d'un objet légèrement différent de l'objet bloc réel dans la chaîne, bien qu'il contienne fondamentalement toutes les mêmes informations que le bloc réel. En conséquence, ils produisent des hachages différents. Par exemple, lors de mon test, le hachage de bloc réel est 0c27196c36691e915fb2a2f83e63867ec5042abfda4832b02383a6ab40aaa075c tandis que le hachage du bloc précédent est e6a312951e9e4ed6e4b2ef049246b282f7114459993939ff6a5b97b0c53c941295
Voici à quel point les hachages sont sensibles.

Mettre tous ensemble

Maintenant, votre code en général devrait ressembler à ceci:

const SHA256 = require ('crypto-js / sha256') class Block {constructeur (horodatage, données) {this.index = 0; this.timestamp = horodatage; this.data = données; this.previousHash = "0"; this.hash = this.calculateHash (); this.nonce = 0; } CalculateHash () {return SHA256 (this.index + this.previousHash + this.timestamp + this.data + this.nonce) .toString (); } mineBlock (difficulté) {}} classe Blockchain {constructeur () {this.chain = [this.createGenesis ()]; } createGenesis () {return new Block (0, "01/01/2017", "Genesis block", "0")} latestBlock () {return this.chain [this.chain.length - 1]} addBlock (newBlock ) {newBlock.previousHash = this.latestBlock (). hash; newBlock.hash = newBlock.calculateHash (); this.chain.push (newBlock); } checkValid () {for (let i = 1; i <this.chain.length; i ++) {const currentBlock = this.chain [i]; const previousBlock = this.chain [i - 1]; if (currentBlock.hash! == currentBlock.calculateHash ()) {return false; } if (currentBlock.previousHash! == previousBlock.hash) {return false; }} retourne vrai; }} let jsChain = new Blockchain (); jsChain.addBlock (nouveau bloc ("25/12/2017", {montant: 5})); jsChain.addBlock (nouveau bloc ("26/12/2017", {montant: 10})); console.log (JSON.stringify (jsChain, null, 4)); console.log ("La blockchain est-elle valide?" + jsChain.checkValid ());

Vous pouvez tester votre blockchain en ajoutant les lignes suivantes à la fin

let jsChain = new Blockchain (); jsChain.addBlock (nouveau bloc ("25/12/2017", {montant: 5})); jsChain.addBlock (nouveau bloc ("26/12/2017", {montant: 10})); console.log (JSON.stringify (jsChain, null, 4)); console.log ("La blockchain est-elle valide?" + jsChain.checkValid ());

Ensuite, allez dans votre terminal et exécutez

nœud main.js

Vous devriez maintenant voir le message suivant:

{
"chain": [
{
"index": 0,
"timestamp": 0,
"data": "01/01/2017",
"previousHash": "Genesis block",
"hash": "8163cbd8feafd38a96cd193f2b44940473c22b21ddbb7445bd99ee310dac28ae",
"nonce": 0
},
{
"index": 1,
"timestamp": "12/25/2017",
"data": {
"amount": 5
},
"previousHash": "8163cbd8feafd38a96cd193f2b44940473c22b21ddbb7445bd99ee310dac28ae",
"hash": "744ce201216f78bba5b87e371579898b97e473ac644d6a13ddda9cdbe05100f6",
"nonce": 0
},
{
"index": 2,
"timestamp": "12/26/2017",
"data": {
"amount": 10
},
"previousHash": "744ce201216f78bba5b87e371579898b97e473ac644d6a13ddda9cdbe05100f6",
"hash": "9e3cf69ee7a3f3f651b33500ea3f32ccf1a13590115c6739dda74920d54702c8",
"nonce": 0
}
]
}
Is blockchain valid? true

résumer

Vous avez maintenant la version 1 d'une blockchain fonctionnelle. Cependant, il existe un petit problème de sécurité avec cette blockchain. Je vous encourage à créer une blockchain comme celle-ci et à l'essayer. Essayez d'identifier où se trouve la faille de sécurité en essayant de manipuler les données.

Suggestion: Cette faille de sécurité est directement liée à l'implémentation de la fonction de minage que nous aborderons dans la partie 2 Construire votre propre blockchain en JavaScript - partie 2 de ce tutoriel.

R Marketing Numérique