Maison interface Web js tutoriel 200 lignes de code pour implémenter la blockchain Explication détaillée des exemples de blockchain

200 lignes de code pour implémenter la blockchain Explication détaillée des exemples de blockchain

May 30, 2018 pm 02:15 PM
Blockchain 区块 实例

Cet article présente principalement les connaissances pertinentes de la blockchain en 200 lignes de code. Il est très bien et a une valeur de référence. Les amis qui en ont besoin peuvent s'y référer

Comprendre le concept de blockchain est très simple (. Block Chain, bloc de chaîne de transactions) : il est distribué (c'est-à-dire non placé sur la même machine, mais sur différents périphériques réseau). La base de données prend en charge l'hébergement d'une liste croissante d'enregistrements. Mais il est également facile de confondre la blockchain avec l'objectif que nous essayons de l'aider à atteindre : à ce moment-là, dans l'esprit des gens, le mot est assez fortement associé au concept de transactions, de contrats ou de crypto-monnaies intelligentes.

Seulement ici, la blockchain n'est pas la même chose que Bitcoin, et comprendre les bases de la blockchain est plus facile qu'il n'y paraît, surtout lorsqu'elle est basée sur le code source. Dans cet article, nous proposons un modèle simple construit avec 200 lignes de code en JavaScript. Le code source de ce projet, que nous appelons NaiveChain, peut être trouvé sur GitHub. Partie 1 et 2 : Si vous avez besoin de flasher ses fonctionnalités, utilisez notre aide-mémoire et nous utiliserons le standard ECMAScript 6.
Structure du bloc

Étape 1 - Identifiez les éléments qui doivent contenir le bloc. Par souci de simplicité, nous n'incluons que l'essentiel : index du bloc précédent (exposant), horodatage (horodatage), données (data), hachage et hachage, à enregistrer afin de maintenir l'intégrité structurelle de le circuit.

class Block { 
  constructor(index, previousHash, timestamp, data, hash) { 
    this.index = index; 
    this.previousHash = previousHash.toString(); 
    this.timestamp = timestamp; 
    this.data = data; 
    this.hash = hash.toString(); 
  } 
}
Copier après la connexion

L'unité de hachage

Le bloc de hachage doit être maintenu Intégrité des données. Dans notre cas, cela s'applique à l'algorithme SHA-256. Ce type de hachage n'est pas pertinent pour le minage car dans ce cas nous ne mettons pas en œuvre de protection avec preuve de performance.

var calculateHash = (index, previousHash, timestamp, data) => { 
  return CryptoJS.SHA256(index + previousHash + timestamp + data).toString(); 
};
Copier après la connexion

Unité de génération

Pour générer un bloc nous avons besoin de connaître le hachage du bloc précédent, Nous avons donc déterminé le reste des éléments de la structure. Les données sont fournies par l'utilisateur final.

var generateNextBlock = (blockData) => { 
  var previousBlock = getLatestBlock(); 
  var nextIndex = previousBlock.index + 1; 
  var nextTimestamp = new Date().getTime() / 1000; 
  var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData); 
  return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash); 
};
Copier après la connexion

Unité de stockage

Utilisez une matrice de stockage blockchain. Le premier bloc est toujours "Genesis Block" codé en dur.

var getGenesisBlock = () => { 
  return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7"); 
}; 
var blockchain = [getGenesisBlock()];
Copier après la connexion

Confirmation de l'intégrité du bloc

Nous devons toujours être en mesure de confirmer l'intégrité d'une unité ou d'un circuit . Surtout lorsque vous recevez de nouvelles unités d'autres unités, vous devez décider de les accepter ou non.

var isValidNewBlock = (newBlock, previousBlock) => { 
  if (previousBlock.index + 1 !== newBlock.index) { 
    console.log('invalid index'); 
    return false; 
  } else if (previousBlock.hash !== newBlock.previousHash) { 
    console.log('invalid previoushash'); 
    return false; 
  } else if (calculateHashForBlock(newBlock) !== newBlock.hash) { 
    console.log(typeof (newBlock.hash) + ' ' + typeof calculateHashForBlock(newBlock)); 
    console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash); 
    return false; 
  } 
  return true; 
};
Copier après la connexion

Sélectionnez la chaîne la plus longue

L'ordre des blocs de circuit doit être explicitement spécifié, mais dans En cas de conflits (par exemple, deux nœuds génèrent le même bloc et le même numéro en même temps), on choisit le circuit qui contient le plus grand nombre de blocs.

var replaceChain = (newBlocks) => { 
  if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) { 
    console.log('Received blockchain is valid. Replacing current blockchain with received blockchain'); 
    blockchain = newBlocks; 
    broadcast(responseLatestMsg()); 
  } else { 
    console.log('Received blockchain invalid'); 
  } 
};
Copier après la connexion

Messages vers d'autres nœuds du réseau

Une partie intégrante du site Web - avec les données d'autres nœuds échange. Les règles suivantes sont utilisées pour maintenir la synchronisation du réseau :
Lorsqu'un nœud génère une nouvelle unité, il la signale au réseau
Lorsque la machine locale se connecte à une nouvelle fête, elle demande des informations sur le dernier bloc généré ; ;
Lorsqu'un nœud est confronté à un bloc qui a un indicateur plus grand que lui, et qu'il ajoute un bloc au circuit ou demande la chaîne complète d'informations.
La recherche automatique de pairs n'est pas effectuée et tous les liens sont ajoutés manuellement.

Contrôle des unités

Les utilisateurs devraient pouvoir contrôler les nœuds d'une manière ou d'une autre, en mettant le serveur HTTP à la solution. Lors de l'interaction avec les nœuds, les fonctions suivantes sont disponibles :
imprimer une liste de toutes les unités ;
créer de nouvelles unités avec du contenu généré par l'utilisateur
imprimer une liste ou ajouter un festival ;
La manière la plus directe d'interagir - via curl :

Liste de tous les numéros de blocs sur un nœud

curl http://localhost : 3001 /blocks

Architecture

Il est à noter que le site Web fait référence à deux serveurs Web : HTTP pour l'installation contrôlée par l'utilisateur et WebSocket pour l'installation HTTP. Connexions P2P entre nœuds .

Ce qui suit est 200 lignes de code js

'use strict'; 
var CryptoJS = require("crypto-js"); 
var express = require("express"); 
var bodyParser = require('body-parser'); 
var WebSocket = require("ws"); 
var http_port = process.env.HTTP_PORT || 3001; 
var p2p_port = process.env.P2P_PORT || 6001; 
var initialPeers = process.env.PEERS ? process.env.PEERS.split(',') : []; 
class Block { 
  constructor(index, previousHash, timestamp, data, hash) { 
    this.index = index; 
    this.previousHash = previousHash.toString(); 
    this.timestamp = timestamp; 
    this.data = data; 
    this.hash = hash.toString(); 
  } 
} 
var sockets = []; 
var MessageType = { 
  QUERY_LATEST: 0, 
  QUERY_ALL: 1, 
  RESPONSE_BLOCKCHAIN: 2 
}; 
var getGenesisBlock = () => { 
  return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7"); 
}; 
var blockchain = [getGenesisBlock()]; 
var initHttpServer = () => { 
  var app = express(); 
  app.use(bodyParser.json()); 
  app.get('/blocks', (req, res) => res.send(JSON.stringify(blockchain))); 
  app.post('/mineBlock', (req, res) => { 
    var newBlock = generateNextBlock(req.body.data); 
    addBlock(newBlock); 
    broadcast(responseLatestMsg()); 
    console.log('block added: ' + JSON.stringify(newBlock)); 
    res.send(); 
  }); 
  app.get('/peers', (req, res) => { 
    res.send(sockets.map(s => s._socket.remoteAddress + ':' + s._socket.remotePort)); 
  }); 
  app.post('/addPeer', (req, res) => { 
    connectToPeers([req.body.peer]); 
    res.send(); 
  }); 
  app.listen(http_port, () => console.log('Listening http on port: ' + http_port)); 
}; 
var initP2PServer = () => { 
  var server = new WebSocket.Server({port: p2p_port}); 
  server.on('connection', ws => initConnection(ws)); 
  console.log('listening websocket p2p port on: ' + p2p_port); 
}; 
var initConnection = (ws) => { 
  sockets.push(ws); 
  initMessageHandler(ws); 
  initErrorHandler(ws); 
  write(ws, queryChainLengthMsg()); 
}; 
var initMessageHandler = (ws) => { 
  ws.on('message', (data) => { 
    var message = JSON.parse(data); 
    console.log('Received message' + JSON.stringify(message)); 
    switch (message.type) { 
      case MessageType.QUERY_LATEST: 
        write(ws, responseLatestMsg()); 
        break; 
      case MessageType.QUERY_ALL: 
        write(ws, responseChainMsg()); 
        break; 
      case MessageType.RESPONSE_BLOCKCHAIN: 
        handleBlockchainResponse(message); 
        break; 
    } 
  }); 
}; 
var initErrorHandler = (ws) => { 
  var closeConnection = (ws) => { 
    console.log('connection failed to peer: ' + ws.url); 
    sockets.splice(sockets.indexOf(ws), 1); 
  }; 
  ws.on('close', () => closeConnection(ws)); 
  ws.on('error', () => closeConnection(ws)); 
}; 
var generateNextBlock = (blockData) => { 
  var previousBlock = getLatestBlock(); 
  var nextIndex = previousBlock.index + 1; 
  var nextTimestamp = new Date().getTime() / 1000; 
  var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData); 
  return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash); 
}; 
var calculateHashForBlock = (block) => { 
  return calculateHash(block.index, block.previousHash, block.timestamp, block.data); 
}; 
var calculateHash = (index, previousHash, timestamp, data) => { 
  return CryptoJS.SHA256(index + previousHash + timestamp + data).toString(); 
}; 
var addBlock = (newBlock) => { 
  if (isValidNewBlock(newBlock, getLatestBlock())) { 
    blockchain.push(newBlock); 
  } 
}; 
var isValidNewBlock = (newBlock, previousBlock) => { 
  if (previousBlock.index + 1 !== newBlock.index) { 
    console.log('invalid index'); 
    return false; 
  } else if (previousBlock.hash !== newBlock.previousHash) { 
    console.log('invalid previoushash'); 
    return false; 
  } else if (calculateHashForBlock(newBlock) !== newBlock.hash) { 
    console.log(typeof (newBlock.hash) + ' ' + typeof calculateHashForBlock(newBlock)); 
    console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash); 
    return false; 
  } 
  return true; 
}; 
var connectToPeers = (newPeers) => { 
  newPeers.forEach((peer) => { 
    var ws = new WebSocket(peer); 
    ws.on('open', () => initConnection(ws)); 
    ws.on('error', () => { 
      console.log('connection failed') 
    }); 
  }); 
}; 
var handleBlockchainResponse = (message) => { 
  var receivedBlocks = JSON.parse(message.data).sort((b1, b2) => (b1.index - b2.index)); 
  var latestBlockReceived = receivedBlocks[receivedBlocks.length - 1]; 
  var latestBlockHeld = getLatestBlock(); 
  if (latestBlockReceived.index > latestBlockHeld.index) { 
    console.log('blockchain possibly behind. We got: ' + latestBlockHeld.index + ' Peer got: ' + latestBlockReceived.index); 
    if (latestBlockHeld.hash === latestBlockReceived.previousHash) { 
      console.log("We can append the received block to our chain"); 
      blockchain.push(latestBlockReceived); 
      broadcast(responseLatestMsg()); 
    } else if (receivedBlocks.length === 1) { 
      console.log("We have to query the chain from our peer"); 
      broadcast(queryAllMsg()); 
    } else { 
      console.log("Received blockchain is longer than current blockchain"); 
      replaceChain(receivedBlocks); 
    } 
  } else { 
    console.log('received blockchain is not longer than received blockchain. Do nothing'); 
  } 
}; 
var replaceChain = (newBlocks) => { 
  if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) { 
    console.log('Received blockchain is valid. Replacing current blockchain with received blockchain'); 
    blockchain = newBlocks; 
    broadcast(responseLatestMsg()); 
  } else { 
    console.log('Received blockchain invalid'); 
  } 
}; 
var isValidChain = (blockchainToValidate) => { 
  if (JSON.stringify(blockchainToValidate[0]) !== JSON.stringify(getGenesisBlock())) { 
    return false; 
  } 
  var tempBlocks = [blockchainToValidate[0]]; 
  for (var i = 1; i < blockchainToValidate.length; i++) { 
    if (isValidNewBlock(blockchainToValidate[i], tempBlocks[i - 1])) { 
      tempBlocks.push(blockchainToValidate[i]); 
    } else { 
      return false; 
    } 
  } 
  return true; 
}; 
var getLatestBlock = () => blockchain[blockchain.length - 1]; 
var queryChainLengthMsg = () => ({'type': MessageType.QUERY_LATEST}); 
var queryAllMsg = () => ({'type': MessageType.QUERY_ALL}); 
var responseChainMsg = () =>({ 
  'type': MessageType.RESPONSE_BLOCKCHAIN, 'data': JSON.stringify(blockchain) 
}); 
var responseLatestMsg = () => ({ 
  'type': MessageType.RESPONSE_BLOCKCHAIN, 
  'data': JSON.stringify([getLatestBlock()]) 
}); 
var write = (ws, message) => ws.send(JSON.stringify(message)); 
var broadcast = (message) => sockets.forEach(socket => write(socket, message)); 
connectToPeers(initialPeers); 
initHttpServer(); 
initP2PServer();
Copier après la connexion

Ce qui précède est ce que j'ai compilé pour tout le monde, j'espère que cela sera utile. à tout le monde à l'avenir.

Articles connexes :

Principes et méthodes de partage des ressources du processus parent et du processus enfant NodeJS

numéro de téléphone mobile vue, Exemples de vérification régulière par e-mail et d'envoi de code de vérification en 60 secondes

Vue implémente la méthode de changement de clic actif

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Stead : un projet RWA révolutionnaire permettant un financement décentralisé pour les infrastructures flottantes en Asie du Sud-Est Stead : un projet RWA révolutionnaire permettant un financement décentralisé pour les infrastructures flottantes en Asie du Sud-Est Aug 08, 2024 am 06:46 AM

Stead est un projet RWA basé en Asie du Sud-Est. Il sert de plate-forme de financement décentralisée pour les infrastructures flottantes, notamment les bateaux de pêche et de transport, les cages à poissons et les maisons flottantes.

Exemple de démarrage de VUE3 : création d'un lecteur vidéo simple Exemple de démarrage de VUE3 : création d'un lecteur vidéo simple Jun 15, 2023 pm 09:42 PM

Alors que la nouvelle génération de frameworks front-end continue d'émerger, VUE3 est apprécié comme un framework front-end rapide, flexible et facile à utiliser. Ensuite, apprenons les bases de VUE3 et créons un simple lecteur vidéo. 1. Installez VUE3 Tout d'abord, nous devons installer VUE3 localement. Ouvrez l'outil de ligne de commande et exécutez la commande suivante : npminstallvue@next. Ensuite, créez un nouveau fichier HTML et introduisez VUE3 : &lt;!doctypehtml&gt;

Découvrez des exemples de bonnes pratiques de conversion de pointeur dans Golang Découvrez des exemples de bonnes pratiques de conversion de pointeur dans Golang Feb 24, 2024 pm 03:51 PM

Golang est un langage de programmation puissant et efficace qui peut être utilisé pour développer diverses applications et services. Dans Golang, les pointeurs sont un concept très important, qui peut nous aider à exploiter les données de manière plus flexible et plus efficace. La conversion de pointeur fait référence au processus d'opérations de pointeur entre différents types. Cet article utilisera des exemples spécifiques pour découvrir les meilleures pratiques de conversion de pointeur dans Golang. 1. Concepts de base Dans Golang, chaque variable a une adresse, et l'adresse est l'emplacement de la variable en mémoire.

La relation entre le nombre d'instances Oracle et les performances de la base de données La relation entre le nombre d'instances Oracle et les performances de la base de données Mar 08, 2024 am 09:27 AM

La relation entre le nombre d'instances Oracle et les performances de la base de données La base de données Oracle est l'un des systèmes de gestion de bases de données relationnelles les plus connus du secteur et est largement utilisée dans le stockage et la gestion de données au niveau de l'entreprise. Dans la base de données Oracle, l'instance est un concept très important. L'instance fait référence à l'environnement d'exécution de la base de données Oracle en mémoire. Chaque instance possède une structure de mémoire et un processus d'arrière-plan indépendants, qui sont utilisés pour traiter les demandes des utilisateurs et gérer les opérations de la base de données. Le nombre d'instances a un impact important sur les performances et la stabilité de la base de données Oracle.

Exemple de développement d'un robot d'exploration Web simple PHP Exemple de développement d'un robot d'exploration Web simple PHP Jun 13, 2023 pm 06:54 PM

Avec le développement rapide d’Internet, les données sont devenues l’une des ressources les plus importantes à l’ère de l’information d’aujourd’hui. En tant que technologie qui obtient et traite automatiquement les données du réseau, les robots d'exploration Web attirent de plus en plus d'attention et d'applications. Cet article explique comment utiliser PHP pour développer un robot d'exploration Web simple et réaliser la fonction d'obtention automatique de données réseau. 1. Présentation de Web Crawler Le robot d'exploration Web est une technologie qui obtient et traite automatiquement les ressources réseau. Son principal processus de travail consiste à simuler le comportement du navigateur, à accéder automatiquement aux adresses URL spécifiées et à extraire toutes les informations.

Exemples d'utilisation du code de vérification dans le framework Gin Exemples d'utilisation du code de vérification dans le framework Gin Jun 23, 2023 am 08:10 AM

Avec la popularité d'Internet, les codes de vérification sont devenus un processus nécessaire pour la connexion, l'enregistrement, la récupération du mot de passe et d'autres opérations. Dans le framework Gin, implémenter la fonction de code de vérification est devenu extrêmement simple. Cet article expliquera comment utiliser une bibliothèque tierce pour implémenter la fonction de code de vérification dans le framework Gin et fournira un exemple de code pour référence aux lecteurs. 1. Installer les bibliothèques dépendantes Avant d'utiliser le code de vérification, nous devons installer une bibliothèque tierce goCaptcha. Pour installer goCaptcha, vous pouvez utiliser la commande goget : $goget-ugithub

Démarrez rapidement avec le framework Django : tutoriels détaillés et exemples Démarrez rapidement avec le framework Django : tutoriels détaillés et exemples Sep 28, 2023 pm 03:05 PM

Démarrez rapidement avec le framework Django : tutoriels détaillés et exemples Introduction : Django est un framework de développement Web Python efficace et flexible piloté par l'architecture MTV (Model-Template-View). Il possède une syntaxe simple et claire et des fonctions puissantes, qui peuvent aider les développeurs à créer rapidement des applications Web fiables et faciles à entretenir. Cet article présentera l'utilisation de Django en détail et fournira des exemples spécifiques et des exemples de code pour aider les lecteurs à démarrer rapidement avec le framework Django. 1. Installez D

Présentation de l'instance dans la base de données Oracle Présentation de l'instance dans la base de données Oracle Mar 07, 2024 pm 04:42 PM

La base de données Oracle est l'un des principaux systèmes de gestion de bases de données relationnelles au monde. Elle offre des fonctions puissantes et une flexibilité et est largement utilisée dans les systèmes d'entreprise. Dans la base de données Oracle, l'instance est un concept très important. Elle porte l'environnement d'exécution et la structure de la mémoire de la base de données et constitue la clé de la connexion avec les utilisateurs et de l'exécution des opérations SQL. Qu'est-ce qu'une instance de base de données Oracle ? Une instance de base de données Oracle est un ensemble de processus créés au démarrage de la base de données, y compris la structure de mémoire et les processus en arrière-plan de l'instance de base de données. Exemples et

See all articles