Node.jsで単純な暗号通貨ブロックチェーンを構築する方法
公開: 2022-03-10smashingCoin
と呼ばれる単純な暗号通貨を作成する方法を示します。 試してみてください—思ったより簡単です!前例のない暗号通貨の台頭と、その基盤となるブロックチェーンテクノロジーは、10年以上前の学術的概念の謙虚な始まりから、さまざまな業界での現在の採用の増加まで、世界を席巻しました。
ブロックチェーンテクノロジーは、信頼できない環境でのセキュリティを強化し、分散化を実施し、プロセスを効率化する能力があるため、多くの注目を集めています。
伝統的に、Pythonはブロックチェーン開発のための事実上のプログラミング言語でした。 ただし、この驚くべきテクノロジーの急増に伴い、開発オプションも増えました—そしてNode.jsは取り残されていません。
このチュートリアルでは、Node.jsで単純な暗号通貨ブロックチェーンを構築する方法について説明します。 あまり凝ったものにはなりませんが、ブロックチェーンがどのように機能するかを理解するのに十分です。
これを単純な暗号通貨smashingCoin
と呼びます。
あなたが暗号通貨の急成長している分野に飛躍したいJavaScript開発者なら、この記事はあなたが始めるために必要なスキルを身につけるでしょう。 または、暗号通貨の世界で物事がどのように機能するかについて興味がある場合は、このチュートリアルがいくつかの質問に答えるのに役立つ可能性があります。
推奨読書: DrewMcLellanによるサブリソースの整合性の理解
前提条件
このチュートリアルを正しく実行するには、次のものが必要です。
- マシンにインストールされているNode.js。 ここからダウンロードできます。
- Visual Studio Code、SublimeTextなどのコードエディター。
始めましょう…
ブロックチェーンとは何ですか?
ブロックチェーンは、ビットコインやイーサリアムなどのデジタル通貨を動かすテクノロジーです。 これは、暗号化を使用して安全に接続されている、ブロックと呼ばれるレコードの継続的に増加するリストを維持する革新的な分散型台帳テクノロジーです。
ブロックチェーンという用語は、トランザクションデータを保持する方法、つまり、チェーンを作成するために相互に接続されたブロックにあるため、その名前が付けられました。 ブロックチェーンのサイズは、実行されるトランザクションの数が増えるにつれて大きくなります。
有効なトランザクションデータはすべてブロックチェーンネットワークに記録されます。ブロックチェーンネットワークは、参加者が規定するピアツーピアルールによって管理されます。 たとえば、このデータには、デジタル通貨などのブロックの「値」、トランザクションの記録(当事者が商品やサービスを交換する場合など)、またはチェーンが所有権情報を記録する場合などの資格特権を含めることができます。
トランザクションデータに加えて、すべてのブロックには、独自の暗号化ハッシュ(一意の識別子またはデジタルフットプリント)、独自のナンス値(暗号化計算で一度使用される任意のランダム番号)、前のブロックのハッシュ、および最近のタイムスタンプが含まれる場合があります認証されたトランザクション。
すべての新しいブロックは前のブロックを指す必要があるため、最後のブロックの正しいハッシュを含まずにブロックがチェーンに組み込まれると、ブロックチェーン全体が無効になる可能性があります。 この不変性のプロパティは、ブロックチェーンのセキュリティの鍵となります。
さらに、ブロックチェーンの信頼性を維持するために、さまざまなタイプのコンセンサスプロトコルが適用されることがよくあります。 コンセンサスは、すべての参加者がネットワークで検証されたトランザクションに同意することを保証します。
たとえば、一般的に使用されるコンセンサスプロトコルは、プルーフオブワークです。これは、一定量のコンピューティング作業を完了した後、複雑な数学的問題の解決策を見つける数を特定することを目的としています。
証明作業の主な考え方は、ブロックチェーンネットワークの参加者は、この番号を特定するのは難しいが、簡単に検証できるようにする必要があるということです。 その結果、ブロックチェーンの構造をスパムしたり改ざんしたりすることを思いとどまらせます。
ほとんどの暗号通貨の場合、ブロックチェーンに新しいブロックを追加するには、複雑な数式を解く必要があります。これは、ブロックチェーンが成長するにつれて時間の経過とともに難易度が増します。 その結果、この問題を解決することによって仕事をしたことを証明する人は誰でも、「マイニング」と呼ばれるプロセスでデジタル通貨で補償されます。
ブロックを作成する方法
ここで、ブロックチェーンテクノロジーとその仕組みを紹介した後、ブロックの作成に概念を適用する方法を見てみましょう。 前述のように、ブロックは相互にリンクしてブロックチェーンを形成するものです。
smashingCoin
通貨を作成するには、ES6で導入されたJavaScriptクラスを使用します。
準備?
手を汚しましょう…
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(); } }
上記のコードでわかるように、他のJavaScriptクラスで行われているのと同じように、 CryptoBlock
クラスを作成し、それにconstructor()
メソッドを追加しました。 次に、そのプロパティを初期化するために、 constructor
メソッドに次のパラメーターを割り当てました。
index | これは、ブロックチェーン全体のすべてのブロックの位置を追跡する一意の番号です。 |
timestamp | 完了した各トランザクションの発生時刻の記録を保持します。 |
data | 送信者の詳細、受信者の詳細、取引量など、完了した取引に関するデータを提供します。 |
precedingHash | これは、ブロックチェーンの前のブロックのハッシュを指します。これは、ブロックチェーンの整合性を維持する上で重要なことです。 |
さらに、上記のデータに示されているように、 computeHash
メソッドを使用して、ブロックのプロパティに基づいてブロックのハッシュを計算しました。
ご覧のとおり、crypto-js JavaScriptライブラリをインポートし、そのcrypto-js/sha256
モジュールを使用して各ブロックのハッシュを計算しました。 モジュールは数値オブジェクトを返すため、 toString()
メソッドを使用して文字列に変換しました。
プロジェクトにcrypto-jsライブラリを追加するには、ターミナルに移動し、次のコマンドを実行してnpm
を使用してインストールします。
npm install --save crypto-js
上記のコマンドを実行すると、ライブラリやその他の重要なファイルを含むノードモジュールディレクトリがプロジェクトのフォルダに追加されます。
ブロックチェーンを作成する方法
前に説明したように、ブロックチェーンテクノロジは、すべてのブロックが相互にチェーンされるという概念に基づいています。 それでは、チェーン全体の操作を処理するCryptoBlockchain
クラスを作成しましょう。 これは、ゴムが道路に出会う場所です。
CryptoBlockchain
クラスは、新しいブロックの作成やチェーンへの追加など、さまざまなタスクを実行するヘルパーメソッドを使用して、ブロックチェーンの操作を維持します。
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); } }
CryptoBlockchain
クラスを構成する各ヘルパーメソッドの役割について説明します。
1.コンストラクターメソッド
このメソッドは、ブロックチェーンをインスタンス化します。 コンストラクター内で、ブロックの配列を参照するblockchain
プロパティを作成しました。 チェーンに最初のブロックを作成するstartGenesisBlock()
メソッドを渡したことに注意してください。
2.ジェネシスブロックの作成
ブロックチェーンでは、ジェネシスブロックは、ネットワーク上で作成された最初のブロックを指します。 ブロックがチェーンの残りの部分と統合されるときはいつでも、それは前のブロックを参照する必要があります。
逆に、この最初のブロックの場合、ポイントする前のブロックはありません。 したがって、ジェネシスブロックは通常、ブロックチェーンにハードコードされています。 このようにして、後続のブロックをその上に作成できます。 通常、インデックスは0です。
startGenesisBlock()
メソッドを使用してジェネシスブロックを作成しました。 以前に作成したCryptoBlock
クラスを使用して作成し、 index
、 timestamp
、 data
、およびprecedingHash
パラメーターを渡したことに注意してください。
3.最新のブロックを取得する
ブロックチェーン内の最新のブロックを取得すると、現在のブロックのハッシュが前のブロックのハッシュを指すようになり、チェーンの整合性が維持されます。
obtainLatestBlock()
メソッドを使用して取得しました。
4.新しいブロックの追加
addNewBlock()
メソッドを使用して、チェーンに新しいブロックを追加しました。 これを実現するために、新しいブロックの以前のハッシュをチェーンの最後のブロックのハッシュと等しくなるように設定しました。これにより、チェーンが改ざんされないようにします。
新しいブロックのプロパティは新しい計算のたびに変更されるため、暗号化ハッシュを再度計算することが重要です。 ハッシュを更新した後、新しいブロックはブロックチェーン配列にプッシュされます。
実際には、いくつかのチェックが行われているため、ブロックチェーンに新しいブロックを追加するのはそれほど簡単ではありません。 それにもかかわらず、この単純な暗号通貨の場合、ブロックチェーンが実際にどのように機能するかを示すだけで十分です。
ブロックチェーンのテスト
それでは、単純なブロックチェーンをテストして、機能するかどうかを確認しましょう。
コードは次のとおりです。
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));
上記のコードでわかるように、 CryptoBlockchain
クラスの新しいインスタンスを作成し、 smashingCoin
という名前を付けました。 次に、任意の値を使用して2つのブロックをブロックチェーンに追加しました。 data
パラメータでは、オブジェクトを使用し、送信者の詳細、受信者の詳細、および取引量を追加しました。
ターミナルでコードを実行すると、次のような出力が得られます。
それがsmashingCoin
の外観です! これは、チェーン内のすべてのブロックを含む配列であるblockchain
プロパティを含むオブジェクトです。 上の画像でわかるように、各ブロックは前のブロックのハッシュを参照しています。 たとえば、2番目のブロックは最初のブロックのハッシュを参照します。 ブロックチェーンが機能することをテストして確認した後、 smashingCoin
の機能を強化するためにいくつかの機能を追加しましょう。
ブロックチェーンの整合性を確認する方法
前述のように、ブロックチェーンの重要な特徴は、ブロックがチェーンに追加されると、チェーンの残りの部分の整合性を無効にすることなく変更できないことです。
したがって、ブロックチェーンの整合性を検証するために、 checkChainValidity()
メソッドをCryptoBlockchain
クラスに追加します。
ブロックの内容を変更すると、まったく新しいハッシュが生成され、ブロックチェーンが無効になるため、ハッシュはブロックチェーンの有効性とセキュリティを確保するために重要です。
そのため、 checkChainValidity()
メソッドは、 if
ステートメントを使用して、すべてのブロックのハッシュが改ざんされているかどうかを検証します。 最初に作成されたブロックから開始して、ブロックチェーン全体をループし、その有効性を確認します。 ジェネシスブロックはハードコーディングされているため、チェックされないことに注意してください。
また、このメソッドは、2つの連続する各ブロックのハッシュが互いに向き合っているかどうかを確認します。 ブロックチェーンの整合性が損なわれていない場合は、trueを返します。 それ以外の場合、異常が発生した場合はfalseを返します。
コードは次のとおりです。
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; }
プルーフオブワークを追加する方法
前述のように、プルーフオブワークは、ブロックチェーンへの新しいブロックのマイニングまたは追加に伴う困難を増大させるために適用される概念です。
smashingCoin
の場合、新しいブロックを簡単に生成したり、ブロックチェーンをスパムしたりするのを防ぐ簡単なアルゴリズムを採用します。
そのため、 CryptoBlock
クラスに、 proofOfWork().
基本的に、この単純なアルゴリズムは、 difficulty
プロパティとして渡される数値を識別し、すべてのブロックのハッシュに、このdifficulty
度レベルに対応する先行ゼロが含まれるようにします。
すべてのブロックのハッシュがdifficulty
度レベルで設定されたゼロの数で始まることを保証するには、多くの計算能力が必要です。 難易度が高いほど、新しいブロックのマイニングにかかる時間が長くなります。
さらに、ハッシュされたすべてのブロックにランダムなnonce
値を追加して、再ハッシュが行われたときに難易度の制限を満たすことができるようにします。
コードは次のとおりです。
proofOfWork(difficulty){ while(this.hash.substring(0, difficulty) !==Array(difficulty + 1).join("0")){ this.nonce++; this.hash = this.computeHash(); } }
そして、これが、 nonce
変数が含まれている更新されたcomputeHash()
メソッドです。
computeHash(){ return SHA256(this.index + this.precedingHash + this.timestamp + JSON.stringify(this.data)+this.nonce).toString(); }
さらに、新しいブロックの生成にプルーフオブワークメカニズムを実装するために、それをaddNewBlock()
メソッドに含めます。
addNewBlock(newBlock){ newBlock.precedingHash = this.obtainLatestBlock().hash; //newBlock.hash = newBlock.computeHash(); newBlock.proofOfWork(this.difficulty); this.blockchain.push(newBlock); }
まとめ
Node.jsを使用してsmashingCoin
暗号通貨を構築するためのコード全体を次に示します。
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));
ターミナルでコードを実行すると、次のような出力が得られます。
上の画像でわかるように、ハッシュは4つのゼロで始まります。これは、プルーフオブワークメカニズムで設定された難易度に対応しています。
結論
それでおしまい! これが、Node.jsを使用して単純な暗号通貨ブロックチェーンを構築する方法です。
もちろん、 smashingCoin
暗号通貨は完全にはほど遠いです。 実際、それ以上の改善を行わずにリリースした場合、安全で信頼性が高く、直感的なデジタル通貨に対する現在の市場の要求を満たすことはできません。これを使用するのはあなただけです。
それでも、このチュートリアルで、スリル満点の暗号の世界に足を踏み入れるための基本的なスキルが身に付いていることを願っています。
コメントや質問がある場合は、以下に投稿してください。
その他のリソース
- 「Blockchain101」、CoinDesk
- 「ビットコイン:ピアツーピアの電子キャッシュシステム」、Bitcoin.orgの中本聡