


200 lignes de code pour implémenter la blockchain Explication détaillée des exemples de 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(); } }
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(); };
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); };
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()];
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; };
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'); } };
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();
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
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!

Outils d'IA chauds

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

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

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

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

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.

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 : <!doctypehtml>

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 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.

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.

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 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

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
