


200 Codezeilen zur Implementierung der Blockchain. Ausführliche Erläuterung der Blockchain-Beispiele
Dieser Artikel stellt hauptsächlich das relevante Wissen über Blockchain in 200 Zeilen Code vor. Er ist sehr gut und hat Referenzwert. Freunde, die ihn benötigen, können darauf zurückgreifen
Das Konzept der Blockchain zu verstehen ist sehr einfach. Blockchain, Transaktionskettenblock): Es wird verteilt (d. h. nicht auf demselben Computer, sondern auf verschiedenen Netzwerkgeräten platziert). Die Datenbank unterstützt das Hosten einer wachsenden Liste von Datensätzen. Aber es ist auch leicht, Blockchain mit dem Ziel zu verwechseln, das wir zu lösen versuchen – in diesem Moment ist das Wort in den Köpfen der Menschen ziemlich stark mit dem Konzept von Transaktionen, Verträgen oder intelligenten Kryptowährungen verbunden.
Nur hier ist Blockchain nicht dasselbe wie Bitcoin, und das Verständnis der Grundlagen der Blockchain ist einfacher als es scheint, insbesondere wenn sie auf Quellcode basiert. In diesem Artikel schlagen wir ein einfaches Modell vor, das mit 200 Codezeilen in JavaScript erstellt wurde. Der Quellcode für dieses Projekt, das wir NaiveChain nennen, finden Sie auf GitHub. Teil 1 und 2: Wenn Sie die Funktionalität flashen müssen, verwenden Sie unseren Spickzettel und wir verwenden Standard-ECMAScript 6.
Blockstruktur
Schritt 1 – Identifizieren Sie die Elemente, die den Block enthalten sollen. Der Einfachheit halber geben wir nur das Nötigste an: Index des vorherigen Blocks (Exponent), Zeitstempel (Zeitstempel), Daten (Daten), Hash und Hash, die aufgezeichnet werden sollen, um die strukturelle Integrität aufrechtzuerhalten die Schaltung.
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(); } }
Hash-Einheit
Hash-Block muss die Datenintegrität halten . In unserem Fall gilt dies für den Algorithmus SHA-256. Diese Art des Hashings ist für das Mining nicht relevant, da wir in diesem Fall keinen Schutz mit Leistungsnachweis implementieren.
var calculateHash = (index, previousHash, timestamp, data) => { return CryptoJS.SHA256(index + previousHash + timestamp + data).toString(); };
Generierungseinheit
Um einen Block zu generieren, müssen wir den Hash des vorherigen Blocks kennen Die Struktur bestimmt bereits die restlichen Elemente. Die Daten werden vom Endbenutzer bereitgestellt.
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); };
Speichereinheit
Blockchain-Speicherarray verwenden. Der erste Block ist immer fest codiert „Genesis Block“.
var getGenesisBlock = () => { return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7"); }; var blockchain = [getGenesisBlock()];
Bestätigung der Integrität des Blocks
Wir müssen immer in der Lage sein, die Integrität einer Einheit zu bestätigen oder Schaltung. Gerade wenn man neue Einheiten von anderen Einheiten bekommt, muss man sich entscheiden, ob man diese annimmt oder nicht.
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; };
Wählen Sie die längste Kette aus
Die Reihenfolge der Schaltungsblöcke muss explizit angegeben werden, aber im Fall Im Falle eines Konflikts (z. B. wenn zwei Knoten gleichzeitig denselben Block und dieselbe Anzahl erzeugen) wählen wir die Schaltung, die eine größere Anzahl von Blöcken enthält.
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'); } };
Nachrichten an andere Netzwerkknoten
Ein integraler Bestandteil der Website – der Datenaustausch mit anderen Knoten . Die folgenden Regeln werden verwendet, um die Netzwerksynchronisierung aufrechtzuerhalten:
Wenn ein Knoten eine neue Einheit generiert, meldet er diese an das Netzwerk.
Wenn der lokale Computer eine Verbindung zu einem neuen Fest herstellt, fragt er nach Informationen über den zuletzt generierten Block ;
Wenn ein Knoten mit einem Block konfrontiert wird, dessen Indikator größer ist, und er einen Block zur Schaltung hinzufügt oder die Informationen der gesamten Kette anfordert.
Eine automatische Suche nach Peers wird nicht durchgeführt und alle Links werden manuell hinzugefügt.
Steuerung von Einheiten
Benutzer sollten in der Lage sein, Knoten auf irgendeine Weise zu steuern, indem sie den HTTP-Server als Lösung einsetzen. Bei der Interaktion mit Knoten stehen folgende Funktionen zur Verfügung:
eine Liste aller Einheiten drucken;
neue Einheiten mit benutzergenerierten Inhalten erstellen;
eine Liste drucken oder ein Festival hinzufügen.
Der direkteste Weg zur Interaktion – über Curl:
Liste aller Blocknummern auf einem Knoten
curl http://localhost: 3001 /blocks
Architektur
Es ist erwähnenswert, dass die Website auf zwei Webserver verweist: HTTP auf das benutzergesteuerte Gerät und WebSocket auf die P2P-Verbindungen des HTTP-Geräts zwischen Knoten.
Das Folgende sind 200 Zeilen JS-Code
'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();
Das Obige habe ich für alle zusammengestellt. Ich hoffe, es wird für alle hilfreich sein in der Zukunft.
Verwandte Artikel:
Vue implementiert die aktive Klickwechselmethode
Das obige ist der detaillierte Inhalt von200 Codezeilen zur Implementierung der Blockchain. Ausführliche Erläuterung der Blockchain-Beispiele. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Stead ist ein RWA-Projekt mit Sitz in Südostasien. Es dient als dezentrale Finanzierungsplattform für schwimmende Infrastruktur, darunter Fischerei- und Transportboote, Fischkäfige und schwimmende Häuser.

Da die neue Generation von Front-End-Frameworks weiter auf dem Vormarsch ist, erfreut sich VUE3 als schnelles, flexibles und benutzerfreundliches Front-End-Framework großer Beliebtheit. Als Nächstes lernen wir die Grundlagen von VUE3 kennen und erstellen einen einfachen Videoplayer. 1. VUE3 installieren Zuerst müssen wir VUE3 lokal installieren. Öffnen Sie das Befehlszeilentool und führen Sie den folgenden Befehl aus: npminstallvue@next Erstellen Sie dann eine neue HTML-Datei und führen Sie VUE3 ein: <!doctypehtml>

Golang ist eine leistungsstarke und effiziente Programmiersprache, mit der sich verschiedene Anwendungen und Dienste entwickeln lassen. In Golang sind Zeiger ein sehr wichtiges Konzept, das uns helfen kann, Daten flexibler und effizienter zu verwalten. Die Zeigerkonvertierung bezieht sich auf den Prozess der Zeigeroperation zwischen verschiedenen Typen. In diesem Artikel werden anhand konkreter Beispiele die Best Practices der Zeigerkonvertierung in Golang erläutert. 1. Grundkonzepte In Golang hat jede Variable eine Adresse, und die Adresse ist der Speicherort der Variablen im Speicher.

Die Beziehung zwischen der Anzahl der Oracle-Instanzen und der Datenbankleistung Oracle-Datenbank ist eines der bekanntesten relationalen Datenbankverwaltungssysteme in der Branche und wird häufig für die Datenspeicherung und -verwaltung auf Unternehmensebene verwendet. In Oracle-Datenbanken ist die Instanz ein sehr wichtiges Konzept. Instanz bezieht sich auf die laufende Umgebung der Oracle-Datenbank im Speicher. Jede Instanz verfügt über eine unabhängige Speicherstruktur und einen Hintergrundprozess, der zur Verarbeitung von Benutzeranforderungen und zur Verwaltung von Datenbankvorgängen verwendet wird. Die Anzahl der Instanzen hat einen wichtigen Einfluss auf die Leistung und Stabilität der Oracle-Datenbank.

Mit der rasanten Entwicklung des Internets sind Daten zu einer der wichtigsten Ressourcen im heutigen Informationszeitalter geworden. Als Technologie zur automatischen Erfassung und Verarbeitung von Netzwerkdaten erregen Webcrawler immer mehr Aufmerksamkeit und Anwendung. In diesem Artikel wird erläutert, wie Sie mit PHP einen einfachen Webcrawler entwickeln und die Funktion zum automatischen Abrufen von Netzwerkdaten realisieren. 1. Überblick über Web Crawler Web Crawler ist eine Technologie, die automatisch Netzwerkressourcen abruft und verarbeitet. Ihr Hauptarbeitsprozess besteht darin, das Browserverhalten zu simulieren, automatisch auf bestimmte URL-Adressen zuzugreifen und alle Informationen zu extrahieren.

Mit der Popularität des Internets sind Verifizierungscodes zu einem notwendigen Prozess für die Anmeldung, Registrierung, das Abrufen von Passwörtern und andere Vorgänge geworden. Im Gin-Framework ist die Implementierung der Verifizierungscode-Funktion extrem einfach geworden. In diesem Artikel wird erläutert, wie eine Bibliothek eines Drittanbieters zum Implementieren der Verifizierungscodefunktion im Gin-Framework verwendet wird, und es wird Beispielcode als Referenz für die Leser bereitgestellt. 1. Abhängige Bibliotheken installieren Bevor wir den Bestätigungscode verwenden können, müssen wir die Bibliothek goCaptcha eines Drittanbieters installieren. Um goCaptcha zu installieren, können Sie den goget-Befehl verwenden: $goget-ugithub

Schneller Einstieg in das Django-Framework: ausführliche Tutorials und Beispiele Einführung: Django ist ein effizientes und flexibles Python-Webentwicklungs-Framework, das auf der MTV-Architektur (Model-Template-View) basiert. Es verfügt über eine einfache und klare Syntax und leistungsstarke Funktionen, die Entwicklern dabei helfen können, schnell zuverlässige und leicht zu wartende Webanwendungen zu erstellen. In diesem Artikel wird die Verwendung von Django ausführlich vorgestellt und spezifische Beispiele und Codebeispiele bereitgestellt, um den Lesern einen schnellen Einstieg in das Django-Framework zu erleichtern. 1. Installieren Sie D

Die Oracle-Datenbank ist eines der weltweit führenden relationalen Datenbankverwaltungssysteme, das leistungsstarke Funktionen und Flexibilität bietet und in Systemen auf Unternehmensebene weit verbreitet ist. In der Oracle-Datenbank ist die Instanz ein sehr wichtiges Konzept. Sie trägt die Betriebsumgebung und die Speicherstruktur der Datenbank und ist der Schlüssel für die Verbindung mit Benutzern und die Ausführung von SQL-Vorgängen. Was ist eine Oracle-Datenbankinstanz? Eine Oracle-Datenbankinstanz ist eine Sammlung von Prozessen, die beim Start der Datenbank erstellt werden, einschließlich der Speicherstruktur und Hintergrundprozesse der Datenbankinstanz. Beispiele und
