ブロックチェーンの作り方 #2 と #3 で、トランザクションの送受信と検証処理がほぼ完成しました。今回 #4 では、ブロックチェーンのジェネシスブロックとチェーン部分を実装していきます。
関連記事:開発環境の準備とファイル構成
ジェネシスブロックとチェーンの実装
ブロックチェーンは、複数のトランザクションを含んだブロックがチェーンのようにつながりブロックチェーンを構成します。(詳しくは、ブロックチェーンの作り方 #1 の「今回作成するブロックチェーンの構造」)をご参照ください)
各ブロックはマイナーが作成して追加していくのですが、一番先頭のブロックは「ジェネシスブロック」と呼ばれプログラムにハードコーディングする特別なブロックですので、今回はジェネシスブロックのみが登録されたチェーンの読み出しができるところまでを実装します。
BlockChain.py
BlockChain
クラスにジェネシスブロックをハードコーディングしてチェーンに追加し、チェーンの読出し処理を実装します。
(略) class BlockChain: def __init__(self): (略) (↓変数を追加↓) # ジェネシスブロック self.genesis_block = { 'time': 1736575754.072457, 'previous_hash': 'none', 'nonce': 0, 'txs': [] } # チェーン self.chain = {'blocks': []} self.chain['blocks'].append(self.genesis_block) # チェーンの保存先 self.chain_file = './blockchain/data/chain.pkl' (略) (↓メソッドを追加↓) # ファイルに保存されているチェーンを読み出す def load_chain(self): if os.path.isfile(self.chain_file): return pd.read_pickle(self.chain_file) else: # ファイルが無ければ初期状態のチェーンを返す return self.chain
【コードの要点】
ジェネシスブロック self.genesis_block
の各キーに指定している値の補足です。txs
以外の値には特に決まりはありませんので、適当な値を指定してください。
time
ジェネシスブロックをハードコーディングした時間をUNIX時間で指定しています。
previous_hash
前のブロックのハッシュ値はありませんので「none」を指定しています。
nonce
マイニングの成功条件を満たすための値ですがマイニングをしていないため「0」を指定しています。
txs
空のリスト「[]」を指定してください。
self.chain_file
変数
まだチェーンの保存処理は実装しませんが、下の load_chain
メソッドでチェーンを読み出す際に参照するため追加しておきます。実行ファイルを実行する時のカレントディレクトリからの相対パスで指定してください。ファイルパスを ./blockchain/data/chain.pkl
とした場合は python blockchain/node.py
のように実行する必要があります。
node.py
node.py
のノードの起動処理にチェーンの読出しを追加して、チェーンを返す関数を追加します。
(略) # ブロックチェーンインスタンス bc = BlockChain() # ノードの起動処理 bc.tx_pool = bc.load_tx_pool() # トランザクションプールの読出し (↓起動処理を追加↓) bc.chain = bc.load_chain() # チェーンの読出し (略) (↓関数を追加↓) # チェーンを返す @app.get('/chain') def get_chain(): return bc.chain
【コードの要点】
@app.get('/chain')
このエンドポイントにGETでリクエストすると、直下の関数 get_chain
が実行されチェーンを返します。今の段階では動作確認用に使いますが、後ほどマイニングを実装する時にこのエンドポイントを使います。
動作確認
node.py
を実行します。
python blockchain/node.py
ブラウザで「http://127.0.0.1:8000/chain」にアクセスしてジェネシスブロックが表示されることを確認してください。
今回のまとめ
今回は、ジェネシスブロックとチェーン部分を実装しました。次回はブロックチェーンの中核となるマイニング処理を実装していきます。
コメント