
ブロックチェーンをpythonで1から書いてみた
最近ふと、ブロックチェーンへの興味がより一層深まってきて、自分でコードを書きたくなりました。
ブロックチェーンは何かを、文章としての説明では理解していたつもりでしたが、やっぱり論理的にコードで理解するのが一番だろうと思いまして、今回助けを借りつつ書いてみました。
ブロックチェーンは分かったつもりになりやすいものだと思うので、概念的ではなくロジックとして理解していこうと思います。
ブロックチェーンはその名の通り、取引データが入った「ブロック」がチェーンのように繋がっていきます。
今日は久しぶりにpythonに触れたので、クラスやインスタンスの部分の理解が曖昧で、すごい苦労しました。
完成品コード
以下がコードです。
本当に簡易的ですが、自分で書いてみるのは概念を理解する上で非常におすすめです。
解説
手順を自分なりに解説していきます。
まず、hashlibというライブラリをimportします。
これはハッシュ関数ですね。チェーンとしてつなぐうえで最も重要な一方向性をもちます。
import hashlib
Blockクラス
Blockというクラスを定義します。
これはその名の通りブロックそのもののクラスです。
インスタンス作成時には、インスタンスに引数のdataやprevious_hash、そしてハッシュ後のvalueを保存するようにします。
calculate_hashが肝心で、自分自身の現在のデータと、一つ前のブロックのハッシュ値を足し合わせたものをハッシュします。その値を返します。
最後に、そのブロック自身が正しいかを検証するものとして、is_validという関数を定義します。
これでブロックそのもののロジックは完了です。
Blockchainクラス
次は実際に繋いで、チェーンにしていきましょう。
まずBlockchainというクラスを定義します。
self.chainに、空のリストをセットします。
これがチェーンのリストです。
この中にはBlockのインスタンスが入っていきます。
最初のブロック
次に、最初のブロック(ジェネシスブロック)を作成します。これだけは特別なので、create_genesis_blockという関数を定義します。
これはprevious_valueが0、つまり一つ前のブロックが存在しないという状態で、Blockのインスタンスを作成し、それを返します。valueには適当に”genesis”を入れました。
その値を、genesis_blockという変数に保管し、chainリストに追加します。これで最初のブロックは完成です。
接続
では次は2つ目のブロックを繋いでみましょう。
ここからは前のものに追加する形なので、add_blockという関数を定義すれば、使い続けられます。
この関数はdataを引数として受け取ります。
new_blockというBlockのインスタンスを作成します。
ここで重要なのが引数で、dataを渡すとともに、chainリストの最後の要素のハッシュ値を渡します。
self.chain[-1]はchainリストの最後の要素つまり、 今作成しているものの一つ前のBlockインスタンスですよね。
それのvalueはハッシュ値です。それを引数として渡すのです。
そうしてその材料をもとに完成したブロックを、add_blockが返します。
ここがブロックチェーンの核心ですね。
今回はdataに”second”を入れています。
self.chain.append(second_block)
最後にその作成したブロックをリストに追加します。
これで2つ目のブロックが入ったブロックチェーン完成です!
ブロックチェーンを検証
では今度はブロックチェーン自体が正しいかを検証するis_chain_validを作っていきます。
このような形になります。
forループで、最初のブロックを除いたブロックについて、ひとつひとつ見ていきます。
iには最初1が入りますから、current_blockはself.chain[1]となり、chainリストの2つ目の要素です。
previous_blockは、self.chain[0]なので、current_blockの一つ前のものです。
今見ているブロックの「一つ前のブロックの値」と、一つ前のブロックの値が同じであれば、それは繋がっていることになります。
ですから、もし current_block.previous_hash == previous_block.valueであるならば、次に移る。
そうでないなら、Falseを返す。
という風なことにすれば、正しく検証できるのです。(現時点では正しくてもTrueを返さずNoneになりますが、まあ一旦ここまでにします)
というようなことになっていました!
あとはブロックチェーンを作成して、正しいかの検証結果をプリントするようにしましょう。
これで完了です!
おわりに
今回、超超簡易的ではあるものの、ブロックチェーンをコードとして書いてみて、仕組みの理解がより進んだと感じました。
これから、ブロックをループで作成したり、タイムスタンプやデータの入力を取り入れたり、PoW入れたりしていきたいです。
githubはこちらです!
https://github.com/Ryt890/toy-blockchain1

Ryo
CS好きの高校一年生。現在は米大学のラボでエネルギー制約下の分散コンピューティング経済学の研究をしています。


