Zum Hauptinhalt springen




In diesem ersten Teil der Serie Javascript BlockchainWir werden das abdecken Objekt blockieren und das Blockchain-Objekt und wir werden seine Struktur und Implikationen diskutieren.

Ich bin fest davon überzeugt, dass der beste Weg, eine Technologie zu erlernen, darin besteht, sie zu bauen. Natürlich hat mich mein Interesse an Blockchain-Technologie dazu veranlasst, meine eigene Blockchain aufzubauen. Ich werde Sie durch die Schritte führen, um eine grundlegende Blockchain mit einem integrierten Proof-of-Work-System zu erstellen. Auf dem Weg werde ich die Auswirkungen der verschiedenen Funktionen diskutieren.

Was brauchen Sie?

  • Die neueste Version von Node.js (ich verwende v8.7.0)
  • Die neueste Version von npm (Node Package Manager) (ich verwende v5.6.0)

Erstellen Sie einen Ordner mit dem Namen js-blockchain und erstellen Sie eine Datei mit dem Namen main.js En esta guía, usaremos un solo archivo para que siempre puedas consultar el Quellcode si encuentras algún problema.

Blockchain-Struktur

Blockchains werden aus einer Kombination von verknüpften Listen und Bäumen von erstellt merkle. Die verknüpfte Listenstruktur ermöglicht es der Kette, kontinuierlich auf sich selbst aufzubauen, und daher stammt der Name Blockchain. EIN Blockkette Es ist buchstäblich eine Kette von Blöcken, die über die verknüpfte Listenstruktur miteinander verbunden sind. Beachten Sie jedoch, dass Sie anstelle eines herkömmlichen Zeigers, der auf den vorherigen Block verweist, die Option verwenden Hash des vorherigen Blocks, um darauf zu verweisen.

Wenn Sie nicht wissen, was a Hash, aquí tiene un manual. Los Hashes son simplemente funciones determinísticas que crean salidas específicas para cada entrada, y normalmente son irreversibles, lo que significa que es extremadamente difícil derivar la entrada de la salida. Son fundamentales para el bloqueo de cadenas, ya que son la clave para que la cadena Sein inmutable y para mantener la integridad de los datos.

Ein Block als Objekt

Wir werden zuerst eine erstellen Klasse namens Block das wird eine Funktion haben Baumeister, eine Funktion berechneHasch und eine Funktion mineBlock. Wir beginnen mit der Funktion Baumeister das instanziiert die Objekte Block und bietet Ihnen seine Eigenschaften.

Klasse Block {Konstruktor (Zeitstempel, Daten) {this.index = 0; this.timestamp = timestamp; this.data = data; this.previousHash = "0"; this.hash = this.calculateHash (); this.nonce = 0; } berechneHash () {} mineBlock (Schwierigkeitsgrad) {}}

Eingänge blockieren

Jedes Blockobjekt nimmt einen Zeitstempel und Blockdaten. Der Zeitstempel zeigt an, wann der Block erstellt wurde. Dies ist beispielsweise in nützlich Bitcoin (BTC), wie BTC Es ist so schwierig ausgelegt, dass die durchschnittliche Extraktionszeit pro Block 10 Minuten beträgt. Daher kann das System diese Datums- und Zeitdaten verwenden, um die Mining-Schwierigkeit jeden Monat neu auszugleichen. Die Blockdaten enthalten die in der Zeichenfolge gespeicherten Informationen. In vielen Währungen wie BTC, Hier werden die variablen Daten in Form von Bäumen von gespeichert merkle.

Daten blockieren

Wie Sie sehen können, ist zusätzlich zu den 3 Dateneingabefeldern unser Objekt blockieren enthält auch a Index, ein Hash vorher a Hash und ein nonce. Der Index teilt mit, wo sich der Block in der Kette befindet. Das Hash des vorherigen Blocks ist das, was die Integrität der Kette aufrechterhält. Der Block-Hash enthält einfach den eigenen Hash des Blocks, der von einer Funktion abgeleitet wurde berechneHasch. Das nonce ist ein weiterer wichtiger Teil des Blocks, der für die Erstellung eines Mining-Mechanismus für unsere Blockchain von entscheidender Bedeutung ist. Dies wird in Teil 2 erläutert: Erstellen einer eigenen Blockchain in JavaScript - Teil 2 dieser Serie. Im Moment werden wir unsere Variable setzen nonce im 0.

Beachten Sie, dass der Hash des vorherigen Blocks die Integrität der Kette aufrechterhält. Um die Integrität der Kette zu überprüfen, durchlaufen wir die Kette, berechnen den Hash jedes Blocks und vergleichen ihn mit den vorherigen Hash-Daten. Wenn eine einzelne Information im Block geändert wird, wird ein völlig anderer Hash ausgespuckt und ist im Vergleich zum sofort erkennbar Hash-Daten vorherige Dateien, die in dem Block gespeichert sind, der auf den geänderten Block folgt. Später werden wir eine Funktion erstellen checkValid es zu beweisen.

Crypto-JS-Bibliothek

Jetzt werden wir eine Funktion hinzufügen berechneHasch zu unserem Block. Für unsere Rolle Hash, Wir werden aus der Bibliothek ausleihen crypto-js und wir werden Ihre Funktion nutzen SHA256 Hash. Die Funktion von SHA256 Hash wurde entwickelt von NSA y ist eine Funktion von Hash irreversibel. Dies wird im Bergbau eingesetzt BTC como su Algorithmus de prueba de trabajo y en la creación de direcciones de BTC Dank Ihrer Sicherheit.

So installieren Sie die Bibliothek crypto-js, Gehen Sie zu Ihrem Terminal und geben Sie Ihren Ordner ein js-blockchain und installieren Sie dann die Bibliothek mit npm mit folgendem Code:

npm install --save crypto-js

Dann sehen Sie folgende Meldung:

npm WARN saveError ENOENT: no such file or directory, open '/Users/spenserhuang/Desktop/js-blockchain/package.json'
npm WARN enoent ENOENT: no such file or directory, open '/Users/spenserhuang/Desktop/js-blockchain/package.json'
npm WARN js-blockchain No description
npm WARN js-blockchain No repository field.
npm WARN js-blockchain No README data
npm WARN js-blockchain No license field.

+ [email protected]
1 Paket in 1.75s aktualisiert

Machen Sie sich vorerst keine Sorgen um die Warnung, da dies uns im Rahmen dieses Projekts nicht betrifft. Der Fehler liegt vor, weil der von uns erstellte Ordner extrem baronisch ist und keine zusätzlichen Dateien wie enthält package.json oder andere Knoten- und Repository-Dateien.

Berechnen Sie Hash

Nachdem Sie die Bibliothek installiert haben, können Sie jedoch eine Konstante erstellen SHA256 und extrahieren Sie die Informationen direkt mit einem Satz benötigen. Wir werden das nutzen, um unsere Funktion zu erstellen berechneHasch.

const SHA256 = erfordert ('crypto-js / sha256') Klasse Block {Konstruktor (Zeitstempel, Daten) {this.index = 0; this.timestamp = timestamp; this.data = data; this.previousHash = "0"; this.hash = this.calculateHash (); this.nonce = 0; } berechneHash () {return SHA256 (this.index + this.previousHash + this.timestamp + this.data + this.nonce) .toString (); } mineBlock (Schwierigkeit) {}}

Wir erstellen unsere eigene Funktion namens berechneHasch dass wir verwenden werden, um jedem Block seinen eigenen zu geben Hash. Wie Sie mit der Funktion sehen können, nimmt der Hash jedes Stück des Blockobjekts und wirft es in eine Funktion SHA256 und konvertiert es in eine Zeichenfolge. In diesem Projekt drehen wir unser Ergebnis SHA256 in einer Zeichenfolge, da Zeichenfolgen einfacher zu verarbeiten und zu kombinieren sind.

Die Funktion berechneHasch Sie akzeptieren JEDER Teil der Blockdaten. Wenn ein Datenelement manipuliert wird, auch wenn es sich um einen neuen Dezimalpunkt handelt, ändert sich der Hash des Blocks sofort. Dies ist eine großartige Funktion, um die Blockchain sicher zu machen.

Aufbau der Blockchain

Nachdem wir die individuelle Blockstruktur erstellt haben, müssen wir eine Struktur erstellen, a Blockchain-Klassenobjekt, um sie miteinander zu verknüpfen und die Grundfunktionalität zu erstellen, die mit normalen Blöcken geliefert wird. Um die Dinge so einfach wie möglich zu halten, wird unsere Blockchain nur eine haben Konstruktorfunktion, ein createGenesis-Funktion, ein neuesteBlock-Funktion, ein addBlock-Funktion und ein checkValid Funktion.

Blockchain-Objekt

Unsere Klasse Blockchain Es benötigt einige Schlüsselfunktionen, nämlich die Fähigkeit, instanziiert zu werden, loszulegen, auf die Informationen des letzten Blocks zuzugreifen und sich durch Hinzufügen eines neuen Blocks zu erweitern.

Klasse Blockchain {Konstruktor () {this.chain = [this.createGenesis ()]; } createGenesis () {neuen Block zurückgeben (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 (sei 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; }} return true; }}

Konstruktorfunktion

Erstens brauchen wir eine Funktion von Baumeister um unsere Blockchain zu instanziieren. Dies ist eine einfache Funktion, die einfach ein Sperrobjekt mit der Eigenschaft erstellt Kette in einer Listenstruktur. Dies ist der Grund, warum unsere Objekte Block Sie hatten Indizes. Die Indexeigenschaften unserer Blöcke werden verwendet, um ihre Position in unserer Liste von Zeichenfolgen zu finden.

Genesis-Funktion erstellen

Zweitens braucht unsere Blockchain eine Funktion createGenesis Das schafft den ersten Block in unserer Kette. In der Blockchain-Konvention wird der erste Block einer Kette auch als der bezeichnet «Genesis Block»daher der Name createGenesis. Mit diesem Block geben wir Ihre Daten normalerweise manuell ein. Da es der erste Block in der Kette ist, hat es einen Indexwert von 0. Für seine Zeitstempel- und Datenfelder können wir das heutige Datum und das Datum eingeben «Genesis Block» oder was auch immer du willst. Wie auf dem Feld Hash oben können wir einfach sagen «0» im Moment gibt es keinen Hash vor dem Genesis-Block.

Holen Sie sich die neueste Sperrfunktion

Drittens benötigt unser String eine Funktion letzter Block. Wird verwendet, um Informationen zum neuesten Block abzurufen. Diese Funktionalität wird verwendet, um unsere Funktion zu implementieren addBlock.

Neue Blockfunktion hinzufügen

Viertens brauchen wir eine Funktion, um unseren Block kontinuierlich zu erweitern addBlock. Blockchains verfügen über eine solche Funktionalität, dass sie immer länger werden müssen, wenn mehr Informationen in sie eingegeben werden. So wird beispielsweise im Fall von BTC ungefähr alle 10 Minuten ein neuer Block erstellt, und jeder dieser neuen Blöcke enthält alle Informationen der Transaktion, die innerhalb dieses Zeitraums von 10 Minuten stattgefunden haben.

Die Implementierung einer Funktion addBlock Ist einfach. Unsere Funktion nimmt ein Objekt Block als Eintrag, der bereits einen Zeitstempel und Daten enthält. Dann unsere Funktion addBlock wird die Funktion verwenden letzter Block um unserem neuen Block einen Index und ein Feld zu geben Hash Bisherige. Danach geben wir unserem neuen Block einen eigenen Hash mit Funktion berechneHasch das haben wir früher geschrieben. Schließlich schieben wir diesen neuen Block auf unsere Kette und jetzt hat unsere Blockchain einen neuen Block.

Gültigkeitsprüfungsfunktion

Die letzte Funktion, die wir implementieren werden, ist die Funktion checkValid. Dies wird verwendet, um die Integrität der Blockchain zu überprüfen und festzustellen, ob etwas manipuliert wurde.

Wie oben erwähnt, ist die Hashes sind entscheidend für das Erkennen von Änderungen an unserer Blockchain, da selbst die kleinste Änderung am Objekt zu a führt Hash völlig anders. Deshalb für unsere Funktion checkValid, Wir werden eine Schleife verwenden zum um durch die Blockchain zu gehen und wir werden versuchen, ihre zu entsprechen Hashes Änderungen erkennen.

Unsere Schleife besteht aus zwei Teilen, der erste besteht darin, zu passen currentBlock.hash mit currentBlock.calculateHash () und der andere ist zu entsprechen currentBlock.previousHash mit previousBlock.hash. Der erste wird verwendet, um zu überprüfen, ob die Informationen von currentBlock wurde ohne Aktualisierung manipuliert currentBlock.hash Der zweite wird verwendet, um zu überprüfen, ob ein vorheriger Block manipuliert wurde oder nicht.

Möglicherweise haben Sie die Frage, ob die if-Bedingung erfüllt werden kann oder nicht

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

Dies scheint theoretisch so, als ob es funktionieren sollte. Dennoch, previousBlock Es ist tatsächlich ein etwas anderes Objekt als das eigentliche Blockobjekt in der Kette, obwohl es im Grunde alle gleichen Informationen wie der eigentliche Block enthält. Infolgedessen erzeugen sie unterschiedliche Hashes. Während meines Tests ist beispielsweise der tatsächliche Block-Hash 0c27196c36691e915fb2a2f83e63867ec5042abfda4832b02383a6ab40aaa075c während der Hash des vorherigen Blocks ist e6a312951e9e4ed6e4b2ef049246b282f7114459993939ff6a5b97b0c53c941295
So empfindlich sind Hashes.

Alles zusammenfügen

Jetzt sollte Ihr Code im Allgemeinen folgendermaßen aussehen:

const SHA256 = erfordert ('crypto-js / sha256') Klasse Block {Konstruktor (Zeitstempel, Daten) {this.index = 0; this.timestamp = timestamp; this.data = data; this.previousHash = "0"; this.hash = this.calculateHash (); this.nonce = 0; } berechneHash () {return SHA256 (this.index + this.previousHash + this.timestamp + this.data + this.nonce) .toString (); } mineBlock (Schwierigkeit) {}} Klasse Blockchain {Konstruktor () {this.chain = [this.createGenesis ()]; } createGenesis () {neuen Block zurückgeben (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 (sei 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; }} return true; }} let jsChain = new Blockchain (); jsChain.addBlock (neuer Block ("25.12.2017", {Betrag: 5})); jsChain.addBlock (neuer Block ("26.12.2017", {Betrag: 10})); console.log (JSON.stringify (jsChain, null, 4)); console.log ("Ist Blockchain gültig?" + jsChain.checkValid ());

Sie können Ihre Blockchain testen, indem Sie am Ende die folgenden Zeilen hinzufügen

let jsChain = new Blockchain (); jsChain.addBlock (neuer Block ("25.12.2017", {Betrag: 5})); jsChain.addBlock (neuer Block ("26.12.2017", {Betrag: 10})); console.log (JSON.stringify (jsChain, null, 4)); console.log ("Ist Blockchain gültig?" + jsChain.checkValid ());

Dann gehen Sie zu Ihrem Terminal und rennen

Knoten main.js

Jetzt sollte folgende Meldung angezeigt werden:

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

zusammenfassend

Jetzt haben Sie Version 1 einer funktionierenden Blockchain. Bei dieser Blockchain besteht jedoch ein kleines Sicherheitsproblem. Ich ermutige Sie, eine Blockchain wie diese zu erstellen und auszuprobieren. Versuchen Sie herauszufinden, wo die Sicherheitslücke liegt, indem Sie versuchen, die Daten zu manipulieren.

Vorschlag: Diese Sicherheitslücke steht in direktem Zusammenhang mit der Implementierung der Mining-Funktion, die in Teil 2 behandelt wird. Erstellen Ihrer eigenen Blockchain in JavaScript - Teil 2 dieses Tutorials.