Cum să construiți un blockchain simplu de criptomonede în Node.js

Publicat: 2022-03-10
Rezumat rapid ↬ Acest tutorial demonstrează cum să creați o criptomonedă simplă, numită smashingCoin , folosind conceptele claselor JavaScript și Node.js. Încercați - este mai simplu decât credeți!

Creșterea fără precedent a criptomonedelor și tehnologia blockchain care stau la baza acestora au luat lumea cu asalt - de la începuturile umile de a fi un concept academic în urmă cu peste un deceniu până la adoptarea actuală sporită în diverse industrii.

Tehnologia blockchain primește multă atenție datorită capacității sale de a îmbunătăți securitatea în medii fără încredere, de a impune descentralizarea și de a eficientiza procesele.

În mod tradițional, Python a fost limbajul de programare de facto pentru dezvoltarea blockchain. Cu toate acestea, odată cu proliferarea acestei tehnologii uimitoare, și opțiunile de dezvoltare au crescut - iar Node.js nu a fost lăsat în urmă.

În acest tutorial, voi vorbi despre cum să construiți un blockchain simplu de criptomonede în Node.js. Nu va fi prea elegant, ci suficient pentru a vă ajuta să înțelegeți cum funcționează un blockchain.

Voi numi această simplă criptomonedă smashingCoin .

Dacă sunteți un dezvoltator JavaScript care dorește să facă un salt în domeniul în plină dezvoltare al criptomonedei, acest articol vă va dota cu abilitățile necesare pentru a începe. Sau, dacă sunteți curios despre cum funcționează lucrurile în lumea criptomonedelor, atunci acest tutorial vă poate ajuta să vă răspundeți la unele dintre întrebările dvs.

Lectură recomandată : Înțelegerea integrității subresursei de Drew McLellan

Cerințe preliminare

Pentru a urma cu succes acest tutorial, va trebui să aveți următoarele:

  • Node.js instalat pe computer. Îl poți descărca de aici;
  • Un editor de cod, cum ar fi Visual Studio Code, Sublime Text sau orice altul.

Să începem…

Mai multe după săritură! Continuați să citiți mai jos ↓

Ce este un blockchain?

Blockchain este tehnologia care alimentează monedele digitale, cum ar fi Bitcoin și Ethereum. Este o tehnologie inovatoare de registru public distribuit, care menține o listă în continuă creștere de înregistrări, denumite blocuri, care sunt conectate în siguranță folosind criptografia.

Termenul blockchain și-a câștigat numele datorită modului în care păstrează datele tranzacțiilor, adică în blocuri care sunt conectate între ele pentru a crea un lanț . Dimensiunea blockchain-ului crește odată cu creșterea numărului de tranzacții efectuate.

Orice date valide ale tranzacțiilor sunt conectate în rețeaua blockchain, care este guvernată de regulile peer-to-peer pe care le stipulează participanții. De exemplu, aceste date ar putea conține „valoarea” blocului, cum ar fi în monedele digitale, o înregistrare a tranzacțiilor (cum ar fi atunci când părțile fac schimb de bunuri și servicii) sau privilegii de drept, cum ar fi atunci când lanțul înregistrează informații de proprietate.

Pe lângă datele tranzacției, fiecare bloc poate conține propriul hash criptografic (un identificator unic sau amprentă digitală), propria sa valoare nonce (un număr aleatoriu arbitrar folosit o dată în calculele criptografice), hash-ul blocului anterior și un marcaj de timp recent. tranzactii autentificate.

Deoarece fiecare bloc nou ar trebui să indice blocul anterior, dacă un bloc este încorporat în lanț fără a conține hash-ul corect al ultimului bloc, ar putea face întregul blockchain invalid. Această proprietate de imuabilitate este cheia securității blockchain-urilor.

Mai mult, diferite tipuri de protocoale de consens sunt adesea aplicate pentru a menține autenticitatea blockchain-ului. Consensul asigură că toți participanții sunt de acord cu tranzacțiile validate de rețea.

De exemplu, un protocol de consens utilizat în mod obișnuit este dovada muncii, care are ca scop identificarea unui număr care găsește o soluție la o problemă matematică complicată după finalizarea unei anumite lucrări de calcul.

Ideea principală a lucrărilor de dovezi este că orice participant în rețeaua blockchain ar trebui să găsească acest număr greu de identificat, dar ușor de verificat. În consecință, descurajează spam-ul și modificarea structurii blockchain-ului.

În cazul majorității criptomonedelor, adăugarea unui nou bloc la blockchain necesită rezolvarea unei ecuații matematice complexe, care crește în dificultate în timp pe măsură ce blockchain-ul crește. În consecință, orice persoană care demonstrează că a lucrat prin rezolvarea acestei probleme este compensată cu o monedă digitală, într-un proces denumit „minerit”.

Cum se creează un bloc

Acum, după ce am introdus tehnologia blockchain și cum funcționează, să vedem cum putem aplica conceptele în crearea unui bloc. După cum am menționat mai devreme, blocurile sunt cele care se interacționează între ele pentru a forma un blockchain.

Pentru a crea moneda smashingCoin , voi folosi clase JavaScript, care au fost introduse în ES6.

Gata?

Hai sa ne murdarim mainile...

Iată codul pentru clasa CryptoBlock :

 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(); } }

După cum puteți vedea în codul de mai sus, am creat clasa CryptoBlock și i-am adăugat metoda constructor() - la fel cum se face în orice altă clasă JavaScript. Apoi, pentru a-i inițializa proprietățile, am atribuit următorii parametri metodei constructor :

index Este un număr unic care urmărește poziția fiecărui bloc din întregul blockchain.
timestamp Păstrează o evidență a orei de apariție a fiecărei tranzacții finalizate.
data Furnizează date despre tranzacțiile finalizate, cum ar fi detaliile expeditorului, detaliile destinatarului și cantitatea tranzacționată.
precedingHash Indică hash-ul blocului precedent din blockchain, ceva important în menținerea integrității blockchain-ului.

În plus, am folosit metoda computeHash pentru a calcula hash-ul blocului pe baza proprietăților acestuia, așa cum este prezentat în datele de mai sus.

După cum puteți vedea, am importat biblioteca JavaScript crypto-js și am folosit modulul crypto-js/sha256 pentru a calcula hash-ul fiecărui bloc. Deoarece modulul returnează un obiect numeric, am folosit metoda toString() pentru a-l converti într-un șir.

Pentru a adăuga biblioteca crypto-js la proiectul dvs., mergeți la terminal și rulați următoarea comandă pentru a o instala folosind npm :

 npm install --save crypto-js

După rularea comenzii de mai sus, directorul modulelor de noduri, care conține biblioteca și alte fișiere esențiale, va fi adăugat în folderul proiectului.

Cum se creează un blockchain

După cum sa explicat mai devreme, tehnologia blockchain se bazează pe conceptul că toate blocurile sunt legate între ele. Deci, să creăm o clasă CryptoBlockchain care va fi responsabilă de gestionarea operațiunilor întregului lanț. Aici cauciucul se va întâlni cu drumul.

Clasa CryptoBlockchain va menține operațiunile blockchain-ului folosind metode de ajutor care realizează diferite sarcini, cum ar fi crearea de noi blocuri și adăugarea lor în lanț.

Iată codul pentru clasa CryptoBlockchain :

 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); } }

Permiteți-mi să vorbesc despre rolurile fiecăreia dintre metodele de ajutor care constituie clasa CryptoBlockchain .

1. Metoda constructorului

Această metodă instanțiază blockchain-ul. În interiorul constructorului, am creat proprietatea blockchain , care se referă la o serie de blocuri. Observați că i-am transmis metoda startGenesisBlock() , care creează blocul inițial în lanț.

2. Crearea blocului Genesis

Într-un blockchain, blocul geneză se referă la primul bloc creat vreodată în rețea. Ori de câte ori un bloc este integrat cu restul lanțului, acesta ar trebui să facă referire la blocul precedent.

Dimpotrivă, în cazul acestui bloc inițial, acesta nu are niciun bloc anterior spre care să fie indicat. Prin urmare, un bloc de geneză este de obicei codificat în bloc. În acest fel, blocurile ulterioare pot fi create pe acesta. De obicei are un indice de 0.

Am folosit metoda startGenesisBlock() pentru a crea blocul de geneza. Observați că l-am creat folosind clasa CryptoBlock creată anterior și am transmis parametrii index , timestamp , data și precedingHash .

3. Obținerea celui mai recent bloc

Obținerea celui mai recent bloc din blockchain ajută la asigurarea că hash-ul blocului curent indică hash-ul blocului anterior - menținând astfel integritatea lanțului.

Am folosit metoda obtainLatestBlock() pentru a o recupera.

4. Adăugarea de noi blocuri

Am folosit metoda addNewBlock() pentru a adăuga un nou bloc în lanț. Pentru a realiza acest lucru, am setat ca hashul anterior al noului bloc să fie egal cu hash-ul ultimului bloc din lanț - asigurându-mă astfel că lanțul este inviolabil.

Deoarece proprietățile noului bloc sunt modificate cu fiecare calcul nou, este important să-i calculați din nou hash-ul criptografic. După actualizarea hash-ului, noul bloc este împins în matricea blockchain.

În realitate, adăugarea unui nou bloc la un blockchain nu este atât de ușoară din cauza mai multor verificări care au fost plasate. Cu toate acestea, pentru această criptomonedă simplă, este suficient pentru a demonstra cum funcționează de fapt un blockchain.

Testarea Blockchain-ului

Acum, să testăm blockchain-ul nostru simplu și să vedem dacă funcționează.

Iată codul:

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

După cum puteți vedea în codul de mai sus, am creat o nouă instanță a clasei CryptoBlockchain și am numit-o ca smashingCoin . Apoi, am adăugat două blocuri în blockchain folosind niște valori arbitrare. În parametrul de data , am folosit un obiect și am adăugat detalii despre expeditor, detalii despre destinatar și cantitatea tranzacționată.

Dacă rulez codul pe terminal, iată rezultatul pe care îl primesc:

Cum arată un blockchain sub capotă
Testăm pentru a vedea dacă blockchain-ul nostru funcționează. (Previzualizare mare)

Așa arată smashingCoin ! Este un obiect care conține proprietatea blockchain , care este o matrice care conține toate blocurile din lanț. După cum puteți vedea în imaginea de mai sus, fiecare bloc face referire la hash-ul blocului anterior. De exemplu, al doilea bloc face referire la hash-ul primului bloc. După ce am testat și am văzut că blockchain-ul nostru funcționează, să mai adăugăm câteva funcționalități pentru a îmbunătăți caracteristicile smashingCoin .

Cum să verificați integritatea blockchain-ului

După cum sa menționat mai devreme, o caracteristică cheie a unui blockchain este că, odată ce un bloc a fost adăugat în lanț, acesta nu poate fi schimbat fără a invalida integritatea restului lanțului.

Prin urmare, pentru a verifica integritatea blockchain-ului, voi adăuga o metodă checkChainValidity() la clasa CryptoBlockchain .

Hashurile sunt esențiale pentru asigurarea validității și securității unui blockchain, deoarece orice modificare a conținutului unui bloc va avea ca rezultat producerea unui hash complet nou și va invalida blockchain-ul.

Ca atare, metoda checkChainValidity() va folosi instrucțiunile if pentru a verifica dacă hash-ul fiecărui bloc a fost modificat. Începând de la primul bloc creat, acesta va trece peste întregul blockchain și va verifica valabilitatea acestuia. Rețineți că, deoarece blocul geneză a fost codificat, nu va fi verificat.

De asemenea, metoda va verifica dacă hashe-urile fiecărui două blocuri consecutive indică unul către altul. Dacă integritatea blockchain-ului nu a fost compromisă, acesta revine adevărat; în caz contrar, în cazul oricăror anomalii, se întoarce fals.

Iată codul:

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

Cum să adăugați dovada muncii

După cum am menționat mai devreme, dovada muncii este conceptul aplicat pentru a crește dificultatea implicată în minerit sau adăugarea de noi blocuri la blockchain.

În cazul smashingCoin , voi folosi un algoritm simplu care descurajează oamenii să genereze cu ușurință noi blocuri sau să trimită spam în blockchain.

Deci, în clasa CryptoBlock , voi adăuga o altă metodă numită proofOfWork(). În esență, acest algoritm simplu identifică un număr, trecut ca proprietate de difficulty , astfel încât hash-ul fiecărui bloc conține zerouri de început care corespund acestui nivel de difficulty .

Asigurarea că hash-ul fiecărui bloc începe cu numărul de zerouri stabilit în nivelul de difficulty necesită multă putere de calcul. Cu cât nivelul de dificultate este mai mare, cu atât este nevoie de mai mult timp pentru a extrage blocuri noi.

În plus, voi adăuga o valoare nonce aleatorie la fiecare bloc hashed, astfel încât, atunci când are loc rehașarea, restricțiile de nivel de dificultate pot fi încă îndeplinite.

Iată codul:

 proofOfWork(difficulty){ while(this.hash.substring(0, difficulty) !==Array(difficulty + 1).join("0")){ this.nonce++; this.hash = this.computeHash(); } }

Și, iată metoda computeHash() actualizată cu variabila nonce inclusă:

 computeHash(){ return SHA256(this.index + this.precedingHash + this.timestamp + JSON.stringify(this.data)+this.nonce).toString(); }

În plus, pentru a implementa mecanismul de dovadă a lucrului în generarea de noi blocuri, îl voi include în metoda addNewBlock() :

 addNewBlock(newBlock){ newBlock.precedingHash = this.obtainLatestBlock().hash; //newBlock.hash = newBlock.computeHash(); newBlock.proofOfWork(this.difficulty); this.blockchain.push(newBlock); }

Încheierea

Iată întregul cod pentru construirea criptomonedei smashingCoin folosind 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));

Dacă rulez codul pe terminal, iată rezultatul pe care îl primesc:

Rezultatul creării unei criptomonede simple în Node.js
În sfârșit, criptomoneda noastră smashingCoin ! (Previzualizare mare)

După cum puteți vedea în imaginea de mai sus, hashurile încep acum cu patru zerouri, care corespund nivelului de dificultate stabilit în mecanismul de dovadă a muncii.

Concluzie

Asta e! Așa puteți construi un blockchain simplu de criptomonede folosind Node.js.

Desigur, criptomoneda smashingCoin este departe de a fi completă. De fapt, dacă îl lansați fără a face mai multe îmbunătățiri, este puțin probabil să îndeplinească cerințele actuale ale pieței pentru o monedă digitală sigură, fiabilă și intuitivă - făcându-vă singurul care o folosește!

Cu toate acestea, sper că acest tutorial v-a echipat cu câteva abilități de bază pentru a vă uda picioarele în lumea palpitantă a cripto-urilor.

Dacă aveți comentarii sau întrebări, vă rugăm să le postați mai jos.

Resurse suplimentare

  • „Blockchain 101”, CoinDesk
  • „Bitcoin: un sistem electronic de numerar peer-to-peer”, Satoshi Nakamoto, Bitcoin.org