JavaScriptを使用して単純なブロックチェーンを作成する方法
[ブロックチェーン]は、今後10年(2020年代)ほどで考えられる最大のデジタル革命の一つです。
〜ボブグレイフェルド
あなたがテクノロジー業界にいるなら、あなたがブロックチェーンテクノロジーについて見聞きしたことはほぼ確実にあるでしょう。ブロックチェーンは、すべての暗号通貨とほとんどの分散型アプリケーションの背後にあるテクノロジー基盤です。それらはまた、この世代の最も重要な発明の1つであり、世界中で急速に人気を博しています。(日本でも旺盛な成長が見込みますが、法制度が追いついていない現状もあり、優秀なエンジニア、起業家は皆、海外(アラブ諸国、シンガポール等)へビジネス拠点を移してしまっています)
ブロックチェーンは、ネットワークで交換されるすべてのデジタルデータまたは資産を追跡するテクノロジーであり、このレコードは「元帳」と呼ばれます。交換される各データは「トランザクション」であり、検証されたすべてのトランザクションは元帳にブロックとして追加されます。ブロックをいくつかのデータを含むチェーンで繋がれたボックスとイメージすると分かりやすいかと思います。これらのブロックの複数が組み合わされてブロックチェーンが形成されます。同じ例えで、ブロックチェーンは複数のボックスを保持するコンテナとしてもイメージ出来るでしょう。
今日は、JavaScriptでブロックチェーンを構築することにより、ブロックチェーンがどのように機能するかを紹介して行きますので一緒に学んで行きましょう。しかし、プログラミングを始める前に、なぜそもそもそれを学ぶ必要があるのでしょうか。
なぜブロックチェーンなのか?
ブロックチェーンは、デジタル通貨を保存および保護する方法として2008年に開始されました。これは、中本聡がビットコインに対して行った提案の一部でした。そしてビットコインはブロックチェーンネットワークの最初のアプリケーションでした。その主な利点の1つは、記録された情報が、すべての関係者またはノード間の合意なしに変更できないことです。
その他の利点は次のとおりです。
- 分散型:トランザクションはコンピューターのネットワーク上で発生します。
- 不変性:トランザクションが作成された場合、それを変更することはできません
- 開く:すべてのトランザクションがすべてのノードに表示されます。
- セキュリティ:暗号化機能により、ブロックチェーンはほとんどの場合安全です
これで、その機能について理解できました。NodeJSを使用して、独自のブロックチェーンを最初から構築してみましょう。
前提条件
このチュートリアルに従って理解するには、次のことに精通している必要があります。
- JavaScriptのクラスおよびその他のES6機能に関する実用的な知識。
- マシンにインストールされたNodeJS。
ブロック入門
いくつかの有用な情報を含むボックスとして、ブロックについて前述しました。考え方はこうです。
ブロックチェーンをLinkedList(データ構造)として考え、ブロックチェーン内の各ブロックをLinkedList内のノードとして考える。これは、次のプロパティを含むJavaScriptのオブジェクトとして表すことができます。
- ブロックチェーンに記録するデータ(トランザクションデータなど)。
- ブロックハッシュ—暗号化技術を使用して生成されたブロックのIDです。
- チェーン内の前のブロックのハッシュ。チェーンにリンクしてセキュリティを向上させるために、すべてのブロックに記録されます。
- ブロックが作成され、ブロックチェーンに追加されたときのタイムスタンプ。
- プルーフオブワーク(PoW)。これは、現在のブロックのハッシュを導出するために必要な労力の量です(プルーフオブステークはこの記事を超えているため、このコンセンサスを使用します)。
上記のプロパティを持つブロッククラスを定義します。
ブロックのハッシュを計算する
ブロックのハッシュは、暗号化技術を使用して生成された識別子です。SHA256アルゴリズムを使用して、前のブロックハッシュ、現在のブロックデータ、タイムスタンプ、およびPoWをハッシュすることにより、ブロックハッシュを取得します。データをハッシュするために、NodeJSの組み込みライブラリであるcryptoを使用します。https://levelup.gitconnected.com/media/a40a6b8c37511b034a64f2eb8ea7236d
上記のコードでは、次のことを行いました。
- ブロックのデータをJSON形式に変換して、他の情報と文字列として連結できるようにしました。
- ブロックの以前のハッシュ、データ、タイムスタンプ、およびプルーフオブワーク(PoW)を連結しました。
- SHA256アルゴリズムを使用した以前の連結のハッシュを生成します。
- AFの小文字を使用して、基数16のハッシュ結果を返しました。
新しいブロックのマイニング
新しいブロックのマイニングには、特定の数の先行ゼロ(0)を使用してブロックのハッシュを生成することが含まれます。先行ゼロの数は、現在のブロックチェーンの難易度によって提供されます。これは、ブロックチェーンの難易度が3の場合、3つのゼロ「000」で始まるブロックを生成する必要があることを意味します(例:「000f34abad…」)。。
ブロックのコンテンツからハッシュを導出したため、コンテンツを変更することはできませんが、マイニング条件を満たすまで、プルーフオブワーク(PoW)の値を確実に増やすことができます。
これを実装するために、有効なハッシュを取得するまでPoW値をインクリメントし、ブロックハッシュを計算し続けるクラスのmine()
メソッドを作成します。Block
https://levelup.gitconnected.com/media/ac63bcbeca438bd28077f7fe6bc4e07a
ブロックチェーンクラスを定義する
先に述べたように、ブロックチェーンはいくつかのブロックのコレクションです。ブロックチェーンクラスには、ジェネシスブロック、チェーン内の他のブロックを含む配列、難易度を示す番号の3つのプロパティがあります。ジェネシスブロックは、ブロックチェーンに追加された最初のブロックです。https://levelup.gitconnected.com/media/2d53655242a780e71422a013c92e70c9
また、次のような難易度を使用してブロックチェーンを直接初期化できるように、ブロックチェーン内で静的メソッドを宣言しましたconst blockchain = Blockchain.create(2)
—ジェネシスブロックとともに難易度2のブロックチェーンインスタンスを作成します。
ブロックチェーンに新しいブロックを追加する
ブロックのハッシュを計算して自分自身をマイニングする機能を正常に実装しました。次に、Blockchainクラス内にメソッドを定義して、チェーンプロパティに新しいブロックを追加しましょう。https://levelup.gitconnected.com/media/fbd0aba6e3a96572affc8a67be2f2c32
ここでaddBlock
は、Blockchainクラスのプロトタイプにメソッドを追加しました。addBlock
これは、クラス内で直接メソッドを定義することに似ています。
メソッドの説明addBlock
:
- パラメータからトランザクションの詳細(送信者、受信者、および転送金額)を収集します。
- トランザクションの詳細を含む新しいブロックを作成します。
mine
Blockクラスのメソッドを使用して新しいブロックをマイニングします。- 新しく作成されたブロックをブロック
chain
チェーンのプロパティにプッシュします。
ブロックチェーンの検証
ブロックチェーンのすべての機能を実装したので、ブロックチェーンが改ざんされていないことを検証できるように、ブロックチェーンの信頼性を確認する必要があります。isValid
このメソッドをBlockchainプロトタイプに追加します。https://levelup.gitconnected.com/media/4e992e22cac0ac1c0086279167d1a57c
ここでは、チェーン上の各ブロックのハッシュを再計算し、それらを格納されているハッシュIDと比較previousHash
し、現在のブロックのハッシュIDと等しくなるはずの次のブロックのプロパティも比較します。ハッシュはブロックのコンテンツを使用して計算されるため、コンテンツを少し変更すると、まったく異なるハッシュ値が生成されます。
ブロックチェーンのテスト
完全に機能するブロックチェーンがあるので、これまでに実装したすべての機能をテストしてみましょう。ファイルにテスト関数を追加しnode <filename.js>
、コマンドラインからを使用して実行します。https://levelup.gitconnected.com/media/125572eb1aebb45bad81d5dfa443f460
結果は下の画像のようになりますが、タイムスタンプが異なるため、ハッシュ値が異なると予想されます。
ボーナス:ブロック時間と難易度の調整
ブロック時間は、マイニング後に新しいブロックがチェーンに追加されるのにかかる推定時間です。定数値です。一部の一般的なプラットフォームのブロック時間は、ビットコインの場合は10分、イーサリアムの場合は約13秒です。
ビットコインは、2016年にマイニングされたブロックごとに、かかった時間に基づいてブロック時間を調整します。10分ごとに1ブロックという望ましい速度では、2016ブロックを見つけるのにちょうど2週間かかります。以前の2016年のブロックを見つけるのに2週間以上かかった場合、難易度は低下し、それ以外の場合は増加します。難易度の変化は、前の2016ブロックが見つけるのにかかった2週間以上または2週間未満の時間に比例します。こんな感じ→
新しい難易度=古い難易度*(2016ブロック* 10分)/前の2016ブロックのマイニング時間
単純なブロックチェーンの場合、新しいブロックにブロック時間よりも時間がかかる場合は、難易度を調整します。もっと時間がかかる場合は、1つ減らし、それ以外の場合は1つ増やします。
ブロック時間を10秒または10000ミリ秒に宣言します。Blockchainコンストラクターにプロパティを追加し、blockTime
10000のような固定値を指定します。次に、addBlock
メソッドを編集して、各トランザクションの後に難易度を調整します。
注blockTime
:プロパティをBlockchainコンストラクターに追加することを忘れないでください。そうしないと、コードエラーとなります。
まとめ
今日は、ブロックチェーンが内部でどのように機能するか、JavaScriptを使用して独自のブロックチェーンを最初から作成する方法を学びました。ソースコードは、難易度の調整を含むGitHubGistとして入手できます。よりインタラクティブなコードがGitHubリポジトリで利用可能であり、TypeScriptを使用します-ターミナルでプログラムを実行して、今日作成したブロックチェーンと対話します。GitHub-ankanbag101 / blockchain-demo:ブロックチェーンテクノロジーの最低限の実装これは、教育目的でTypeScriptを使用したブロックチェーン機能の最低限の実装です。
次は、今日学んだブロックチェーンを利用して暗号通貨を作成する方法について紹介して行きます。次に、ピアツーピア接続のネットワークを作成し、通貨を起動させます(多分)。次のチュートリアルに関する情報を受け取りたい方は、LINE登録頂ければタイムリーに情報を入手できます。次回以降のブログ公開をするかもしれませんし、しないかもしれません。