So erstellen Sie eine einfache Kryptowährungs-Blockchain in Node.js
Veröffentlicht: 2022-03-10smashingCoin
erstellt, indem man die Konzepte von JavaScript-Klassen und Node.js verwendet. Probieren Sie es aus – es ist einfacher als Sie denken!Der beispiellose Aufstieg von Kryptowährungen und die ihnen zugrunde liegende Blockchain-Technologie haben die Welt im Sturm erobert – von den bescheidenen Anfängen als akademisches Konzept vor über einem Jahrzehnt bis zur aktuellen zunehmenden Akzeptanz in verschiedenen Branchen.
Die Blockchain-Technologie erhält viel Aufmerksamkeit wegen ihrer Fähigkeit, die Sicherheit in vertrauenswürdigen Umgebungen zu erhöhen, Dezentralisierung zu erzwingen und Prozesse effizient zu gestalten.
Traditionell war Python die De-facto-Programmiersprache für die Blockchain-Entwicklung. Mit der Verbreitung dieser erstaunlichen Technologie haben sich jedoch auch die Entwicklungsmöglichkeiten erhöht – und Node.js wurde nicht zurückgelassen.
In diesem Tutorial werde ich darüber sprechen, wie man eine einfache Kryptowährungs-Blockchain in Node.js erstellt. Es wird nicht zu ausgefallen sein, aber gerade ausreichen, um Ihnen zu helfen, zu verstehen, wie eine Blockchain funktioniert.
Ich nenne diese einfache Kryptowährung smashingCoin
.
Wenn Sie ein JavaScript-Entwickler sind, der einen Sprung in das aufkeimende Gebiet der Kryptowährung wagen möchte, wird dieser Artikel Sie mit den notwendigen Fähigkeiten ausstatten, um loszulegen. Oder wenn Sie neugierig sind, wie die Dinge in der Welt der Kryptowährungen funktionieren, dann kann dieses Tutorial bei der Beantwortung einiger Ihrer Fragen helfen.
Empfohlene Lektüre : Understanding Subresource Integrity von Drew McLellan
Voraussetzungen
Um diesem Tutorial erfolgreich zu folgen, benötigen Sie Folgendes:
- Node.js auf Ihrem Computer installiert. Sie können es hier herunterladen;
- Ein Code-Editor wie Visual Studio Code, Sublime Text oder ein anderer.
Lass uns anfangen…
Was ist eine Blockchain?
Blockchain ist die Technologie, die digitale Währungen wie Bitcoin und Ethereum antreibt. Es handelt sich um eine innovative verteilte öffentliche Ledger-Technologie, die eine ständig wachsende Liste von Datensätzen verwaltet, die als Blöcke bezeichnet werden und die mithilfe von Kryptografie sicher verbunden sind.
Der Begriff Blockchain hat seinen Namen aufgrund der Art und Weise verdient, wie Transaktionsdaten gespeichert werden, dh in Blöcken , die miteinander verbunden sind, um eine Kette zu bilden. Die Größe der Blockchain wächst mit der Anzahl der durchgeführten Transaktionen.
Alle gültigen Transaktionsdaten werden in das Blockchain-Netzwerk eingeloggt, das den von den Teilnehmern festgelegten Peer-to-Peer-Regeln unterliegt. Diese Daten könnten beispielsweise den „Wert“ des Blocks enthalten, z. B. in digitalen Währungen, eine Aufzeichnung von Transaktionen (z. B. wenn Parteien Waren und Dienstleistungen austauschen) oder Berechtigungsprivilegien, z. B. wenn die Kette Eigentumsinformationen aufzeichnet.
Neben den Transaktionsdaten kann jeder Block seinen eigenen kryptografischen Hash (eine eindeutige Kennung oder einen digitalen Fußabdruck), seinen eigenen Nonce-Wert (eine willkürliche Zufallszahl, die einmal in kryptografischen Berechnungen verwendet wird), den Hash des vorherigen Blocks und einen Zeitstempel der letzten Zeit enthalten authentifizierte Transaktionen.
Da jeder neue Block auf den vorherigen Block zeigen sollte, könnte ein Block, der in die Kette aufgenommen wird, ohne den richtigen Hash des letzten Blocks zu enthalten, die gesamte Blockchain ungültig machen. Diese Unveränderlichkeitseigenschaft ist der Schlüssel zur Sicherheit von Blockchains.
Darüber hinaus werden häufig verschiedene Arten von Konsensprotokollen angewendet, um die Authentizität der Blockchain aufrechtzuerhalten. Der Konsens stellt sicher, dass alle Teilnehmer den netzwerkvalidierten Transaktionen zustimmen.
Ein häufig verwendetes Konsensprotokoll ist beispielsweise der Arbeitsnachweis, der darauf abzielt, eine Zahl zu identifizieren, die nach Abschluss einer bestimmten Menge an Rechenarbeit eine Lösung für ein kompliziertes mathematisches Problem findet.
Die Hauptidee der Beweisarbeit ist, dass jeder Teilnehmer am Blockchain-Netzwerk diese Nummer schwer identifizieren, aber leicht überprüfbar finden sollte. Folglich wird von Spamming und Manipulationen an der Struktur der Blockchain abgeraten.
Bei den meisten Kryptowährungen erfordert das Hinzufügen eines neuen Blocks zur Blockchain das Lösen einer komplexen mathematischen Gleichung, die mit der Zeit immer schwieriger wird, wenn die Blockchain wächst. Folglich wird jede Person, die beweist, dass sie Arbeit geleistet hat, indem sie dieses Problem gelöst hat, mit einer digitalen Währung entschädigt, in einem Prozess, der als „Mining“ bezeichnet wird.
So erstellen Sie einen Block
Nun, nachdem wir die Blockchain-Technologie und ihre Funktionsweise vorgestellt haben, wollen wir sehen, wie wir die Konzepte beim Erstellen eines Blocks anwenden können. Wie bereits erwähnt, sind Blöcke miteinander verbunden, um eine Blockchain zu bilden.
Um die smashingCoin
Währung zu erstellen, verwende ich JavaScript-Klassen, die in ES6 eingeführt wurden.
Bereit?
Machen wir uns die Hände schmutzig…
Hier ist der Code für die CryptoBlock
-Klasse:
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(); } }
Wie Sie im obigen Code sehen können, habe ich die CryptoBlock
-Klasse erstellt und ihr die Methode constructor()
hinzugefügt – genau wie in jeder anderen JavaScript-Klasse. Dann habe ich der constructor
die folgenden Parameter zugewiesen, um ihre Eigenschaften zu initialisieren:
index | Es ist eine eindeutige Nummer, die die Position jedes Blocks in der gesamten Blockchain verfolgt. |
timestamp | Es zeichnet den Zeitpunkt des Auftretens jeder abgeschlossenen Transaktion auf. |
data | Es liefert Daten über die abgeschlossenen Transaktionen, wie z. B. die Absenderdaten, die Empfängerdaten und die Transaktionsmenge. |
precedingHash | Es zeigt auf den Hash des vorhergehenden Blocks in der Blockchain, was wichtig ist, um die Integrität der Blockchain aufrechtzuerhalten. |
Außerdem habe ich die computeHash
Methode verwendet, um den Hash des Blocks basierend auf seinen Eigenschaften zu berechnen, wie in den obigen Daten angegeben.
Wie Sie sehen können, habe ich die JavaScript-Bibliothek crypto-js importiert und ihr Modul crypto-js/sha256
verwendet, um den Hash jedes Blocks zu berechnen. Da das Modul ein Zahlenobjekt zurückgibt, habe ich die Methode toString()
verwendet, um es in einen String umzuwandeln.
Um die crypto-js-Bibliothek zu Ihrem Projekt hinzuzufügen, gehen Sie zum Terminal und führen Sie den folgenden Befehl aus, um sie mit npm
zu installieren:
npm install --save crypto-js
Nachdem Sie den obigen Befehl ausgeführt haben, wird das Knotenmodulverzeichnis, das die Bibliothek und andere wichtige Dateien enthält, dem Ordner Ihres Projekts hinzugefügt.
So erstellen Sie eine Blockchain
Wie bereits erläutert, basiert die Blockchain-Technologie auf dem Konzept, dass alle Blöcke miteinander verkettet sind. Lassen Sie uns also eine CryptoBlockchain
-Klasse erstellen, die für die Abwicklung der Operationen der gesamten Kette verantwortlich ist. Hier trifft der Gummi auf die Straße.
Die CryptoBlockchain
-Klasse verwaltet die Operationen der Blockchain mithilfe von Hilfsmethoden, die verschiedene Aufgaben erfüllen, z. B. das Erstellen neuer Blöcke und das Hinzufügen dieser zur Kette.
Hier ist der Code für die CryptoBlockchain
-Klasse:
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); } }
Lassen Sie mich über die Rollen der einzelnen Hilfsmethoden sprechen, die die CryptoBlockchain
-Klasse bilden.
1. Konstruktormethode
Diese Methode instanziiert die Blockchain. Innerhalb des Konstruktors habe ich die blockchain
-Eigenschaft erstellt, die sich auf ein Array von Blöcken bezieht. Beachten Sie, dass ich ihm die Methode startGenesisBlock()
, die den Anfangsblock in der Kette erstellt.
2. Erstellen des Genesis-Blocks
In einer Blockchain bezieht sich der Genesis-Block auf den allerersten Block, der im Netzwerk erstellt wurde. Immer wenn ein Block in den Rest der Kette integriert wird, sollte er auf den vorhergehenden Block verweisen.
Umgekehrt hat dieser Anfangsblock keinen vorangehenden Block, auf den er zeigen kann. Daher ist ein Genesis-Block normalerweise in der Blockchain fest codiert. Auf diese Weise können nachfolgende Blöcke darauf erstellt werden. Es hat normalerweise einen Index von 0.
Ich habe die Methode startGenesisBlock()
verwendet, um den Genesis-Block zu erstellen. Beachten Sie, dass ich es mit der zuvor erstellten CryptoBlock
-Klasse erstellt und die Parameter index
, timestamp
, data
und precedingHash
übergeben habe.
3. Abrufen des neuesten Blocks
Das Abrufen des neuesten Blocks in der Blockchain hilft dabei, sicherzustellen, dass der Hash des aktuellen Blocks auf den Hash des vorherigen Blocks verweist – und so die Integrität der Kette aufrechterhält.
Zum Abrufen habe ich die obtainLatestBlock()
" verwendet.
4. Hinzufügen neuer Blöcke
Ich habe die Methode addNewBlock()
verwendet, um der Kette einen neuen Block hinzuzufügen. Um dies zu erreichen, setze ich den vorherigen Hash des neuen Blocks auf den Hash des letzten Blocks in der Kette – und stelle so sicher, dass die Kette manipulationssicher ist.
Da sich die Eigenschaften des neuen Blocks mit jeder neuen Berechnung ändern, ist es wichtig, seinen kryptografischen Hash erneut zu berechnen. Nach der Aktualisierung seines Hashs wird der neue Block in das Blockchain-Array geschoben.
In Wirklichkeit ist das Hinzufügen eines neuen Blocks zu einer Blockchain nicht so einfach, da mehrere Überprüfungen vorgenommen wurden. Nichtsdestotrotz reicht es für diese einfache Kryptowährung, zu zeigen, wie eine Blockchain tatsächlich funktioniert.
Testen der Blockchain
Lassen Sie uns nun unsere einfache Blockchain testen und sehen, ob sie funktioniert.
Hier ist der 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));
Wie Sie im obigen Code sehen können, habe ich eine neue Instanz der Klasse CryptoBlockchain
und ihr den Namen smashingCoin
gegeben. Dann fügte ich der Blockchain zwei Blöcke mit einigen willkürlichen Werten hinzu. Im data
habe ich ein Objekt verwendet und Absenderdetails, Empfängerdetails und die Transaktionsmenge hinzugefügt.
Wenn ich den Code auf dem Terminal ausführe, bekomme ich folgende Ausgabe:
So sieht die smashingCoin
aus! Es ist ein Objekt, das die blockchain
-Eigenschaft enthält, bei der es sich um ein Array handelt, das alle Blöcke in der Kette enthält. Wie Sie im obigen Bild sehen können, verweist jeder Block auf den Hash des vorherigen Blocks. Beispielsweise verweist der zweite Block auf den Hash des ersten Blocks. Nachdem wir getestet und festgestellt haben, dass unsere Blockchain funktioniert, fügen wir einige weitere Funktionen hinzu, um die Funktionen von smashingCoin
zu verbessern.
So überprüfen Sie die Integrität der Blockchain
Wie bereits erwähnt, besteht ein Schlüsselmerkmal einer Blockchain darin, dass ein einmal hinzugefügter Block nicht mehr geändert werden kann, ohne die Integrität des Rests der Kette zu beeinträchtigen.
Um die Integrität der Blockchain zu überprüfen, füge ich daher der CryptoBlockchain
-Klasse eine checkChainValidity()
Methode hinzu.
Hashes sind entscheidend für die Gewährleistung der Gültigkeit und Sicherheit einer Blockchain, da jede Änderung des Inhalts eines Blocks zur Erzeugung eines völlig neuen Hashs führt und die Blockchain ungültig macht.
Daher verwendet die Methode checkChainValidity()
if
-Anweisungen, um zu überprüfen, ob der Hash jedes Blocks manipuliert wurde. Beginnend mit dem ersten erstellten Block wird die gesamte Blockchain durchlaufen und auf Gültigkeit geprüft. Beachten Sie, dass der Genesis-Block, da er fest codiert war, nicht überprüft wird.
Außerdem überprüft das Verfahren, ob die Hashes von jeweils zwei aufeinanderfolgenden Blöcken aufeinander zeigen. Wenn die Integrität der Blockchain nicht kompromittiert wurde, wird true zurückgegeben; andernfalls wird bei Anomalien false zurückgegeben.
Hier ist der 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; }
So fügen Sie einen Arbeitsnachweis hinzu
Wie bereits erwähnt, ist Proof of Work das Konzept, das angewendet wird, um die Schwierigkeit zu erhöhen, die mit dem Mining oder dem Hinzufügen neuer Blöcke zur Blockchain verbunden ist.
Im Fall von smashingCoin
verwende ich einen einfachen Algorithmus, der Leute davon abhält, einfach neue Blöcke zu generieren oder die Blockchain zu spammen.
Also füge ich in der CryptoBlock
-Klasse eine weitere Methode namens proofOfWork().
Im Wesentlichen identifiziert dieser einfache Algorithmus eine als difficulty
übergebene Zahl, sodass der Hash jedes Blocks führende Nullen enthält, die diesem difficulty
entsprechen.
Sicherzustellen, dass der Hash jedes Blocks mit der im difficulty
festgelegten Anzahl von Nullen beginnt, erfordert viel Rechenleistung. Je höher der Schwierigkeitsgrad, desto länger dauert es, neue Blöcke abzubauen.
Darüber hinaus füge ich jedem gehashten Block einen zufälligen nonce
-Wert hinzu, sodass beim Rehashing die Einschränkungen des Schwierigkeitsgrades immer noch eingehalten werden können.
Hier ist der Code:
proofOfWork(difficulty){ while(this.hash.substring(0, difficulty) !==Array(difficulty + 1).join("0")){ this.nonce++; this.hash = this.computeHash(); } }
Und hier ist die aktualisierte computeHash()
Methode mit der enthaltenen nonce
-Variablen:
computeHash(){ return SHA256(this.index + this.precedingHash + this.timestamp + JSON.stringify(this.data)+this.nonce).toString(); }
Um den Proof-of-Work-Mechanismus bei der Generierung neuer Blöcke zu implementieren, füge ich ihn außerdem in die Methode addNewBlock()
:
addNewBlock(newBlock){ newBlock.precedingHash = this.obtainLatestBlock().hash; //newBlock.hash = newBlock.computeHash(); newBlock.proofOfWork(this.difficulty); this.blockchain.push(newBlock); }
Einpacken
Hier ist der gesamte Code zum Erstellen der smashingCoin
-Kryptowährung mit 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));
Wenn ich den Code auf dem Terminal ausführe, bekomme ich folgende Ausgabe:
Wie Sie auf dem obigen Bild sehen können, beginnen die Hashes nun mit vier Nullen, was dem im Proof-of-Work-Mechanismus eingestellten Schwierigkeitsgrad entspricht.
Fazit
Das ist es! So können Sie mit Node.js eine einfache Kryptowährungs-Blockchain erstellen.
Natürlich ist die smashingCoin
-Kryptowährung noch lange nicht vollständig. Wenn Sie es veröffentlichen, ohne weitere Verbesserungen vorzunehmen, ist es unwahrscheinlich, dass es die aktuellen Marktanforderungen nach einer sicheren, zuverlässigen und intuitiven digitalen Währung erfüllt – so dass Sie der einzige sind, der es verwendet!
Nichtsdestotrotz hoffe ich, dass dieses Tutorial Sie mit einigen grundlegenden Fähigkeiten ausgestattet hat, um in die aufregende Welt der Kryptos einzutauchen.
Wenn Sie Kommentare oder Fragen haben, posten Sie diese bitte unten.
Weitere Ressourcen
- „Blockchain 101“, CoinDesk
- „Bitcoin: Ein elektronisches Peer-to-Peer-Cash-System“, Satoshi Nakamoto, Bitcoin.org