Pythonでブロックチェーンを学ぶ -1-
2019年も早いところ2月中旬、まあまあ寒いけれども、澄んだ空気の奥に見える富士山が綺麗だったり、もうすぐ春の訪れを感じるような暖かい日もあったりと日々は淡々と過ぎていくわけです。
さて、思い返すこと昨年の今頃、会社でRaspberryPiを使ってプログラミングをやろうって企画があり、折角の機会なので流行っていた?ブロックチェーン(2017年末から2018年初めは bitcoin含め仮想通貨の急騰、暴落で一喜一憂していた頃)を勉強してみようと、RaspberryPi に python でブロックチェーンを実装した時のコードをまとめてみました。
その際に超参考にさせて頂いたのが以下の記事。
今日はRaspberryPi に実装したブロックチェーンを3回に分けて書いてみることにします。
第1回 Proof of Workの実装
第2回 Transaction処理の実装
第3回 Flaskによる APIの実装
第1回目:Proof of Work
第1回目は ブロックチェーンの肝である、Proof of Work を実装する。
Proof of Work(プルーフ・オブ・ワーク)とは、各トランザクションを認証するために算出しなければならないシステムです。例として、ビットコインをはじめとするほとんどの暗号通貨では、プルーフ・オブ・ワークを計算する手段としてハッシュ関数が用いられますが、その中で"あるゲーム"が行われます。それは 以下の3番目の処理に該当します。
■ブロックチェーンのチェーン処理
1. 直前のブロックのハッシュ値をブロックヘッダに取り込む
2. そのブロック内の取引データを全てハッシュ化して、そのハッシュ値をブロックヘッダに取り込む
3. そのブロック全体をハッシュ化した際に、先頭に0が16〜18個並ぶような乱数を探す
4. 乱数が見つかったら時刻が記録される
5. ブロックが生成される
3番の乱数を探す処理に膨大な計算量が必要であり、世界中で多くの人達が発掘の報酬としてコインをもらえるので(最初に乱数を見つけた者のみ)、膨大なサーバを動かして文字通り発掘処理(マイニング)をしているのです。
ブロックはそのブロック毎に発見された乱数を鍵として繋がれていくので、改竄するには、次のマイニングが終わるまでに改竄したブロック以降全てのブロックの鍵を再計算し直さなければいけないので、事実上、このシステムを偽装することは不可能です。
RaspberryPi で実装した乱数発見処理では、CPUの性能が低くて、とても先頭に0が16〜18個並ぶような乱数を計算するには時間がかかりすぎるので、以下のように0が4個並ぶような乱数を計算するようにした。(RaspberryPiを振ると マイニングが開始される仕組みだが、このプログラミングはブログでは割愛)
乱数計算のプログラミング
python ライブラリの hashlib (sha256) を使用して、整数"x"かけるある整数"y"のhashが"0000"で始まる計算をすると、hash(x * y) = ac23d...0000となる。この例では x = 9と固定してPythonで実装する。
from hashlib import sha256
x = 9
y = 0
while sha256(f'{x*y}'.encode()).hexdigest()[:4] != "0000": # 最初の4桁が 0000
print(sha256(f'{x*y}'.encode()).hexdigest())
y += 1
print(f'The solution is y = {y}')
実際に実行すると y = "107500" が求められた。実際に107500 を代入して再計算してみると、最初が"0" 4桁のハッシュが求められた。
sha256(f'{9*107500}'.encode()).hexdigest()
## 実行結果 ##
'0000e88b7feb46798cb9d3cdc35b387660a3d8bdf2067a6be0659210507b924b'
次回は このProof Of Workを使って、各Transaction処理(ビットコインで言うところの購入・売買処理)を書いてみる。