ブロックチェーンをpythonで1から書いてみた
« 一覧に戻る

ブロックチェーンをpythonで1から書いてみた

Programming

最近ふと、ブロックチェーンへの興味がより一層深まってきて、自分でコードを書きたくなりました。

ブロックチェーンは何かを、文章としての説明では理解していたつもりでしたが、やっぱり論理的にコードで理解するのが一番だろうと思いまして、今回助けを借りつつ書いてみました。

ブロックチェーンは分かったつもりになりやすいものだと思うので、概念的ではなくロジックとして理解していこうと思います。

ブロックチェーンはその名の通り、取引データが入った「ブロック」がチェーンのように繋がっていきます。

今日は久しぶりにpythonに触れたので、クラスやインスタンスの部分の理解が曖昧で、すごい苦労しました。

完成品コード

以下がコードです。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

本当に簡易的ですが、自分で書いてみるのは概念を理解する上で非常におすすめです。

解説

手順を自分なりに解説していきます。

まず、hashlibというライブラリをimportします。
これはハッシュ関数ですね。チェーンとしてつなぐうえで最も重要な一方向性をもちます。

import hashlib

Blockクラス

Blockというクラスを定義します。

これはその名の通りブロックそのもののクラスです。

インスタンス作成時には、インスタンスに引数のdataやprevious_hash、そしてハッシュ後のvalueを保存するようにします。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

calculate_hashが肝心で、自分自身の現在のデータと、一つ前のブロックのハッシュ値を足し合わせたものをハッシュします。その値を返します。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

最後に、そのブロック自身が正しいかを検証するものとして、is_validという関数を定義します。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

これでブロックそのもののロジックは完了です。

Blockchainクラス

次は実際に繋いで、チェーンにしていきましょう。

まずBlockchainというクラスを定義します。

self.chainに、空のリストをセットします。
これがチェーンのリストです。
この中にはBlockのインスタンスが入っていきます。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

最初のブロック

次に、最初のブロック(ジェネシスブロック)を作成します。これだけは特別なので、create_genesis_blockという関数を定義します。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

これはprevious_valueが0、つまり一つ前のブロックが存在しないという状態で、Blockのインスタンスを作成し、それを返します。valueには適当に”genesis”を入れました。

その値を、genesis_blockという変数に保管し、chainリストに追加します。これで最初のブロックは完成です。

接続

では次は2つ目のブロックを繋いでみましょう。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

ここからは前のものに追加する形なので、add_blockという関数を定義すれば、使い続けられます。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

この関数は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を作っていきます。
このような形になります。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

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になりますが、まあ一旦ここまでにします)

というようなことになっていました!
あとはブロックチェーンを作成して、正しいかの検証結果をプリントするようにしましょう。

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

これで完了です!

おわりに

今回、超超簡易的ではあるものの、ブロックチェーンをコードとして書いてみて、仕組みの理解がより進んだと感じました。

これから、ブロックをループで作成したり、タイムスタンプやデータの入力を取り入れたり、PoW入れたりしていきたいです。

githubはこちらです!
https://github.com/Ryt890/toy-blockchain1

Ryo

Ryo

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