マイニング報酬の鍵はnonceのイメージ画像

マイニング報酬の鍵はnonce

  • 公開日:2018/03/12
  • 更新日:2018/10/19
  • 投稿者:n bit

マイニング時の計算競争で適切な解を見つけるためにはnonceの働きが重要になってきます。nonceはどのようなものか、そしてどの様な働きを持っているのか事例を使って説明していきます。

  • ブロックチェーン
  • 仮想通貨

この記事は約 分で読めます。(文字)

マイニング報酬の鍵 nonceとは?

今回の説明にはハッシュ関数の理解が必要になります。ハッシュ関数はこちらのページで解説していますので「ハッシュ関数」や「ハッシュ値」と言う言葉がよくわからない方は一度ご参照頂けると幸いです。

まず、nonceとは?

Note

ノンス(英: nonce、ナンスとも)は、暗号通信で用いられる、使い捨てのランダムな値のこと

出典:ノンス - Wikipedia

では、この使い捨てのランダムな値はどのように利用されているのでしょうか。マイニング時の計算競争にはnonceの働きが重要となります。まずはどのような競争しているのか確認してnonceの関わりを見ていきます。

頭に0が一定数続くハッシュ値を探し当てる競争

マイニングの計算力競争で行っているのは頭に0が一定数続くハッシュ値を探し当てることです。頭3桁0が続くハッシュ値であれば以下のようになります。

000f23878fbc8bdd2290902560ada43021e3dfa4ee80f23bfc2a500c462221a9

頭に何桁の0が続くものを探すのかと言う条件は、その時々によって変わります。マイニングは約10分間で1つのブロックの解が見つかるように調整されています。それは何桁の0が続くハッシュ値を探すのかを設定することで調整しています。

例えば、6桁頭に0が続くハッシュ値を探すことよりも、10桁頭に0が続くハッシュ値を探す方が難しくなります。頭に続く0の桁数が増えるほど絶対数が少なくなるためです。

Note

3桁位の数字で考えるとこれはすぐに理解できると思います。

全部で4桁の数値で頭に2桁の0が続く値と、頭に3桁の0が続く値の数を比べてみましょう。

頭に2桁の0が続く値:0010〜0099(全部で90個)

頭に3桁の0が続く値:0001〜0009(全部で9個)

「頭に2桁の0が続く値」は「頭に3桁の0が続く値」に比べ10倍多いことになります。つまり、それだけ見つけることが簡単です。

そのため、マイニングの時間がコンピュータの進化等により計算時間が10分よりも早くなるようであれば頭に続く0の桁数を増やし、逆に10分よりも計算が遅くなるようであれば頭に続く0の桁数を減らすことで時間が早くなるように調整します。

鍵となる入力値はnonce

このハッシュ値を探すためハッシュ関数を利用します。ハッシュ関数は何かしらの値を入力するとハッシュ値を返してくれる関数です。マイニング時の計算競争でハッシュ関数に入力している入力値は主に3つです。

  • 1:トランザクションデータを集めたもの
  • 2:一つ前のブロックをハッシュ値化したもの
  • 3:nonce(内容についてはこの後詳しく説明します)

ハッシュ関数には「同じ入力値に対しては必ず同じハッシュ値が出力される」と言う特徴があります。

ハッシュ関数の特性

  • 同じ入力値に対しては必ず同じハッシュ値が出力される
  • 入力値に対して規則性のないハッシュ値が出力される
  • ハッシュ値から元の入力データに復元することはほぼ不可能

ハッシュ関数への入力値「1:トランザクションデータを集めたもの」と「2:一つ前のブロックをハッシュ値化したもの」は値が変わる事はありません。そのため、この2つだけの入力では何回ハッシュ関数に入力しても返されるハッシュ値は常に同じになってしまいます。

そこで、nonceの登場です。nonceの値を変化させることでハッシュ関数に入力される値に違いが出ますので、ハッシュ関数の特性「入力値に対して規則性のないハッシュ値が出力される」により、nonceを変更するたび全く違うハッシュ値が出力されます。

ハッシュ関数のページでも使った例を再び利用してnonceの働きをもう少し見ていきます。

固定値のテキスト「dot blog」の後ろに、変動値として0〜の数字を連番で順に足してハッシュ値を求めました。

入力値:dot blog0

f5ae7a49152e8ff79d02dfe3e14d18e701cd2888f7e91997f3a44be557df6109

入力値:dot blog1

78d2bbafa47c589193f525207643ee1df2009bd60841698383fbee8395812508

入力値:dot blog2

6e501130a32a4edf937b3f45b2053154256574bcda1304f7a90edd95205ee59d

この時連番で「dot blog」の後ろに足していった数字がnonceだと理解すればよいでしょう。

  • dot blog = 固定値:「1:トランザクションデータを集めたもの」と「2:一つ前のブロックをハッシュ値化したもの」
  • 0〜2の数字 = 変動値:「3:nonce」

上記事例の様にnonceの値のみをどんどん変化させていくことで条件に合うハッシュ値(頭に何桁かの0が続くハッシュ値)を探していきます。試しにこの事例で頭3桁が0になるハッシュ値を探す計算を行ってみました。0から順に開始して行ったところ921で頭に0が3桁続く最初のハッシュ値が計算されました。

入力値:dot blog921

000f23878fbc8bdd2290902560ada43021e3dfa4ee80f23bfc2a500c462221a9

計算の解の条件が頭に3桁0が続くハッシュ値であればこの答えを最初に見つけたノードに報酬が与えられることになります。つまり、マイニングを行って報酬をもらうために、この条件に見合うnonceを見つける計算力競争行っています

試しにnonceを見つける計算をしてみる

nonceを見つける計算がどのようなものか体験してみたい方は下記のコードでも実験できます。(Python3系)実際のnonceを見つける計算はもう少し複雑ですが基本的にやっていることが理解できると思います。

# -*- coding: utf-8 -*-

import sys
import hashlib

def hash_out(string):
nonce = 0
while True:
string_nonce = string + str(nonce)
hash_value = hashlib.sha256(string_nonce.encode('utf-8')).hexdigest()
print(str(nonce) + ':' + str(hash_value))
if hash_value.startswith('000'):
print('clear!')
break
else:
nonce += 1

if __name__ == '__main__':
string = sys.argv[1]
hash_out(string)

ターミナルで以下のように入力してください。

$ python hash.py 入力文字列

下記のように計算されれば成功です。

dot blog + nonce の場合

0:a4d2b537441d7cab9d9df61d406dc13cb16c1a00f3b4a24bd211bf2ddf2661bf

1:d00402c3ec646610caefcdf5f7ada7c5f70c7ce651dc05dcd67a3204a88faa93



920:1c5602683f1b5c80b870c087a639d26ec194d379e0221b88607ecd937f67ccc6
921:000f23878fbc8bdd2290902560ada43021e3dfa4ee80f23bfc2a500c462221a9
clear!

今日のdot

マイニングの計算力競争で行っているのは頭に0が一定数続くハッシュ値を探し当てることです。計算競争でハッシュ関数に入力している入力値は主に3つです。

  • 1:トランザクションデータを集めたもの
  • 2:一つ前のブロックをハッシュ値化したもの
  • 3:nonce

nonceは使い捨てのランダムな値で、マイニングを行って報酬をもらうためには、条件に見合う頭に0が一定数続くハッシュ値を出力できるnonceを見つける計算を行います。