マイニングの実験

Google Colab上でPythonを使って、いくつかの実験を行いました。

1.難易度を変化させた時のマイニングの成功時間

 まず、マイニングの難易度を変化させたとき、計算時間がどのように変わるのかを実験しました。
 以下のプログラム[リスト2]は、テキストと難易度を指定したとき、ナンス、ナンスとテキストを合わせたもののハッシュ値、マイニングにかかった時間を出力します。
 ナンスとテキストを合わせたもののハッシュ値targetより小さければマイニング成功となります。
 今回はtargetをtarget = 2**(256-difficulty_bits)で設定しました。
実験手順
1. text = ‘目白祭’、target = 2**(256-difficulty_bits)で固定します。
2. difficulty_bitsを0から徐々に数を上げていき、計算時間を記録します。
3. 設定をGPU(計算処理を行う半導体チップ)ありにして、1,2をもう一度行います。

[リスト2]難易度を指定した時のマイニングにかかる計算時間
[input]

実験結果

[グラフ1] 各ブロックのマイニングにかかる計算時間

 グラフのようにGPUありの場合は難易度を上げていった時にGPUなしと比較して格段と計算時間が早くなり、difficulty_bitsを22より大きくしたあたりから、計算に急激に時間がかかるようになりました。

2.プレーンブロックチェーンでのマイニングの成功時間

 次に、ジェネシスブロックを含めた31個のブロックチェーンが生成されるのにかかる時間を難易度(Difficulty bits)を変えて比較しました。
 [リスト3]で変数INITIAL_BITSとして入力される、難易度(Difficulty bits)は0x1e777777のような形で記述されています。
実験手順
1.以下の仕組みを備えたプレーンなブロックチェーン[リスト3]をpythonで実装します。
 ・ブロックの構築
 ・Difficulty bitsからのターゲットの計算
 ・マイニング
 ・ジェネシスブロックの生成
 ・新規ブロックの接続
2.INITIAL_BITSの値を”1e777777”にして[リスト3]を実行します。
3.INITIAL_BITSの値を”1d777777”に変更して[リスト3]を実行します。

[リスト3]プレーンブロックチェーン
[input]

実験結果

以下のような出力結果になりました。

[output] INITIAL_BITS = ”1e777777”のとき

省略

[output] INITIAL_BITS = ”1d777777”のとき

省略

ここで、各ブロックのマイニングにかかる計算時間(elapsed_time)を[グラフ2]にまとめました。

[グラフ2] 各ブロックのマイニングにかかる計算時間

 INITIAL_BITSを”1e777777”に設定したとき、平均所要時間は0.524[s]、31個のブロックを生成するのにかかった合計所要時間は16.24[s]だったのに対し、”1d777777”に設定したとき、平均所要時間は163.291[s]、合計所要時間5062.011[s]と約84分かかりました。
 このことから、bitsを少し変更しただけでもマイニングにかかる計算時間が大きくが変わることが分かりました。
 また、同じ難易度に設定していてもマイニングにかかる計算時間はブロックごとにばらつきがあることが分かります。特に、”1d777777”に設定したとき、最短の計算時間は13.624[s]であったのに対し、最長の計算時間は987.637[s]になり、同一の難易度でも約273倍も時間がかかったことが分かりました。
 次に、ブロックのハッシュ値(block_hash)の先頭に並ぶ0の数に注目してみました。
“1e777777”のときは最低4つの0が並びますが、”1d777777”のときは最低6つ並んでいます。これはマイニングにおける成功条件において、0が多い方が小さい値を要求される、すなわち難易度が高くなることを表しています。
 また、マイニングに時間がかかっているブロックのナンス値は値が大きくなる傾向にあることも分かりました。これは、nonceを発見するためのfor文の部分でたくさんの値を0から順に試行したことになります。