ブロックチェーンのマイニング模擬実験
Interface8月号のブロックチェーン特集をちょこちょこ読んでいる。
その中のマイニングの体験が面白かったのでメモしておく。
マイニング
マイニングとは、ブロックチェーン上に新規ブロックを作成するための作業。
実際何をやっているかというと暗号学的ハッシュ関数を用いてハッシュ値を計算している。
ハッシュ値の入力は、前のブロックのハッシュ値と未承認の取引履歴のハッシュ値、そしてナンスと呼ばれる32ビットの数値の3つ。
新規ブロック生成の条件は、そのブロックのハッシュ値がある値以下(例えば0が16個並ぶ)となるようなブロック。
マイニング実施者(マイナー)は、ある数以下のハッシュ値(例えば0が16個並ぶ値)を見つけるため、ナンスをランダムに変化させてひたすらハッシュ値を計算する。
条件を満たすナンスを発見できたらマイニング成功となり、マイナーはマイニング報酬を得ることができる。
Pythonによるマイニングの体験
ナンス値を変えてある値以下(先頭文字に0が複数並ぶ)のハッシュ値を見つける。
コードはInterface8月号のコードを一部改変し使用している(ほぼ引用)。
なお、python3.7.1を使用した。
まずは、先頭4文字が0になるハッシュ値を見つけてみる。
import random import hashlib import re transaction_1 = "A -> B 1BTC" def text2hash(mynonce): hash_object = hashlib.sha256(transaction1.encode() + str(mynonce).encode()) chk = re.match('0000', hash_object.hexdigest()) if chk != None: print("Nonce: " + str(nonce)) print("HASH: " + hash_object.hexdigest()) print("=================================") max_nonce = 10**7 extract_nonce_num = 10**6 nonce_list = random.sample(list(range(0, max_nonce)), k=extract_nonce_num) for nonce in nonce_list: text2hash(nonce)
実行すると以下のような結果になった。すぐ計算結果がでた(1秒もまってない)。
結果を見るとたしかにハッシュ値の先頭4文字が0になっている。
ハッシュ値全体からすると、先頭4文字が0になる確率は16^60/16^64 = 1/16^4 = 1/65536
だから大体0.0015%くらい。
今回、100万個のナンスから12個の条件を満たすナンスを見つけたから確率は12/10^6
で、大体0.0012%くらいなので整合的かな。
Nonce: 6487403 HASH: 00006660c4c89abf1cc9654dff2a5ffac1ed65e7f0d9d43d008924a5d775f6f5 ================================= Nonce: 8845617 HASH: 00005943b43aa3f90987d07d6d6755af11ed20e4096ad5ed30ba466653f8aff1 ================================= Nonce: 8949731 HASH: 000015497ca43abb7e07322361be25955e83dac3f60014a0d253800513ae7092 ================================= Nonce: 7875493 HASH: 0000109c55bb3ae22deba78eccc3fe7ae5e259f2f3f47f407d35ae00a530ef79 ================================= Nonce: 6319689 HASH: 000023b6c8e4f9925c28bb749b7e2b07850471f852e1dfa76615abe0c57a763c ================================= Nonce: 1908741 HASH: 00002634d326f64212aaf6f15b2ea60fd69a0d6c1ef4c8f8c2f3b596f5b83bd5 ================================= Nonce: 1739868 HASH: 0000bd16e990309b203ad6b620e2f59c75747d2fc91a7a6e8d52e958ae02c275 ================================= Nonce: 1579836 HASH: 00009958c87100b48c79e8be3602a5ba94150c5454ad3a9a1b43ce75081fa581 ================================= Nonce: 3768602 HASH: 00005cddc0bac1e2d6c3825bef4a4edc2c0901531d4039822857583bf3cbbbe7 ================================= Nonce: 7397948 HASH: 0000cc416e9872b5af5b45bbf94ba1dbaec984b5f80b7ee86c1268d7ab77dcf3 ================================= Nonce: 2561779 HASH: 0000c4137ca7636f9475069585f170271a899de1c55f20c56507f8d597403b0f ================================= Nonce: 8532683 HASH: 000076388f9767d973ce8090bb3de94759c73f93743d880adbe096573bb3375a =================================
次に、先頭5文字が0になるナンスを見つけてみる。
コード内のtext2hash
関数内のパラメータchk
の値を変えて実行する。
何回か実行すると、条件を満たすナンスが下記のように1件発見できたり、できなかったりする。大体0~2個くらいの発見数。
先頭文字の0を一つ増やすと条件を満たすナンスを見つける確率は16分の1に減るので、先程の結果(発見したナンスの個数:12)と比べるとまあ整合的かと思われる。
Nonce: 4196833
HASH: 000002e0c4d4158f51626be52ea8a53da9bc55cba1a272cfc9509b2548b1889e
=================================
ビットコインでのマイング
ビットコインでは先頭文字が16個(難易度によって増減するが)の0になるハッシュ値を見つけなければならない。
条件を満たすナンスを見つける確率はめちゃくちゃ低い。確率は、1/16^16。約0.00000000000000001% (10^-17 %)
マイニングは大変ってことがよく分かった。勉強になりました。