Published Date : 2021年7月9日16:43

007 Pythonで遊ぶ (ノンス 1)
007 Playing with Python (nonce 1)


This blog has an English translation


ニコニコ動画にアップした動画のまとめ記事です。

This is a summary blog post about a video I uploaded to NicoNico.

細かい部分は動画を参考にしてください。

Please refer to the video for details.


目次

Table of Contents




① 動画の説明
① Video Description



前回の続きです。

Continued from last time.

ではPythonを使ってハッシュ値からノンスを簡単に計算してみましょう。

Let's simply compute the nonce from the hash value using Python.

物事を簡単にするため、前のブロックのハッシュ値と取引記録のハッシュ値の二つを使います。

To simplify things, I use two hashes the hash value of the previous block and the hash value of the transaction record.

さらに計算時間を短縮するためにノンスを使って計算されるハッシュ値の先頭のゼロの数は少なくします。

To further reduce computation time, reduce the number of leading zeros in hash values computed using nonce.

厳密なノンスの求め方を知りたい人は各自で調べてください。

If you want to know exactly how to get nonce, please check it out by yourself.

適当な取引記録を文字列として作成します。

Creates a set of transaction records as a string.

取引をまとめたもののハッシュ値を計算します。

Computes the hash value of a string of transactions.

前回のブロックのハッシュ値です。

Hash value of the previous block.

取引記録の文字列と、前回のブロックのハッシュ値の文字列と、ノンスの文字列を合わせたテキストを作成します。

Create text that concatenation of the transaction record string, the hash value string from the previous block, and the nonce string.

計算されたハッシュ値

Calculated hash value

試しに予め計算しておいたノンスの値を使って実験してみましょう。

Experiment with the pre-calculated Nonce value.

ゼロの数を3個にした場合

The result when the number of zeros is set to three.

もし計算されたハッシュ値の先頭が指定された桁数のゼロになっていればノンスが見つかったとします。

if the computed hash value begins with a specified number of zeros, a nonce is found.

必要なモジュールをインポートする。

Import the required modules.

from hashlib import sha256
from time import time

何度も使用することとなるので、テキストからハッシュ値を求める関数を作成しておきましょう。

Create a function that calculates a hash value from the text because you will use it many times.

def convert_hash(concat_text):
    return sha256(concat_text.encode('utf-8')).hexdigest()
            

ハッシュ値を計算できるように、文字列をUTF-8でエンコードしてバイト列に直します。

Encodes the string in UTF-8 and turns it into a byte string so that the hash value can be calculated.

そして文字列として処理できるように、hexadigestメソッドを使用して計算されたハッシュ値を16進数表記の文字列に変換します。

The hash value computed using the hexadigest method is then converted to a string in hexadecimal notation so that it can be treated as a string.

ノンスを見つける関数を作成します。引数には、取引記録のハッシュ値と、前回のブロックのハッシュ値、それからゼロの桁数と、時間の計測につかわれる開始時間を渡します。

Create a function to find the nonce. The arguments are the hash value of the transaction record, the hash value of the previous block, the number of zeros, and the start time used to measure the time.

ノンスの値をゼロで初期化します。

Initializes the nonce value with zero.

nonce = 0

取引記録の文字列と、前回のブロックのハッシュ値の文字列と、ノンスの文字列を合わせたテキストを作成します。

Create text that concatenation of the transaction record string, the hash value string from the previous block, and the nonce string.

concat_text = tx_hash + pblock_hash + str(nonce)

計算されたハッシュ値

Calculated hash value

calc_hash = convert_hash(concat_text)

ワイルループ中にもし計算されたハッシュ値の先頭が指定された桁数のゼロになっていれば、ノンスが見つかったので、ループを抜けます。

During WhileLoop, if the computed hash value begins with a specified number of zeros, a nonce is found and the loop is exited.

if calc_hash.startswith('0' * num_zeros):
    return (nonce, calc_hash)

ノンスとハッシュ値はトゥープルにして、関数の結果の戻り値として返してあげます。

The nonce and hash values should be tupled and returned as the result of the function.

計算時間の上限を設定して、その上限を超えたらループを終了して、ノンスが見つけられなかったことをメッセージとして表示させます。

Sets an upper limit on the calculation time, and when that limit is exceeded, terminates the loop and displays a message that the nonce could not be found.

ノンスをインクリメントとして一つずつハッシュ値を検証していきます。

The hash value is verified by increasing the nonce value one by one.

nonce += 1

私の環境と、このアルゴリズムでは1分間で大体約3600万回試せました。

My environment and this algorithm were able to do an average of about 36 million trials per minute.

スクリプトがスタートした時間を記録します。

Record the time the script started.

適当な取引記録を文字列として作成します。

Creates a set of transaction records as a string.

取引をまとめたもののハッシュ値を計算します。

Computes the hash value of a string of transactions.

前回のブロックのハッシュ値です。

Hash value of the previous block.

ハッシュ値の先頭にいくつゼロが続くかを決めます。最初は4つにしてみましょう。

Determines how many zeros follow the beginning of the hash value. Let's try 4 first.

ノンスを見つける関数を発動します。

Invokes a function to find the nonce.

終了時間を計測します。

Measure the end time.

計算結果をコンソール画面に表示させます。

Displays the calculation result on the console screen.

ではスクリプトを試してみましょう。

Let's try the script.

ゼロの数を増やして計算時間とノンスがどう変わるか確かめてみましょう。

Try increasing the number of zeros to see how the computation time and nonce change.

ゼロの数を5個にした場合

The result when the number of zeros is set to five.

ゼロの数を6個にした場合

The result when the number of zeros is set to six.

ゼロの数を7個にした場合

The result when the number of zeros is set to seven.

今回の場合の組み合わせなら7桁までなら素早くノンスを見つけることができたが、8桁になると4時間近くの時間を要することになる。

In this case, it was possible to find Nonce quickly up to 7 digits, but it would take nearly 4 hours to find Nonce at 8 digits.

先頭の0が8個になるノンス(9181716258)を見つけるのに約235分44秒掛かりました。
前のブロックのハッシュ値(da8b70ca315adfce5db80b35129685357748488b6a0aa11f549d42083bc4d8e1)
導かれたノンス(9181716258)
計算されたハッシュ値(000000002b70676dbd21f8d6b15ed4c690b50938f781336aeb463564b0da0b05)

今度は1ループ毎にランダムな数になるように試してみましょう。

Now let's try a random number of nonce values per loop.

ランダムモジュールから指定した範囲の整数をランダムに選ぶrandintメソッドをインポートします。

Imports an randint method that randomly selects a specified range of integers from a random module.

関数に渡す引数にノンスの上限値を加えます。

Adds the nonce upper bound to the argument passed to the function.

randintメソッドがどのように機能するか確かめてみましょう。

Let's see how the randint method works.

ランダムな数をノンスに割り当てます。

Assigns a randomly chosen number to the nonce.

1ループ毎にランダムに選択された数値をナンスに割り当てます。

Assigns a randomly selected number to the nonce per loop.

ノンスの上限を決めます。

Determine the upper limit of the nonce.

後は先ほど作成したスクリプトと内容は殆ど同じです。

The rest is almost the same as the script I just created.

ではスクリプトを試してみましょう。

Let's try the script.

ゼロの数を4個にした場合

The result when the number of zeros is set to four.

ゼロの数を増やして計算時間とノンスがどう変わるか確かめてみましょう。

Try increasing the number of zeros to see how the computation time and nonce change.

ゼロの数を5個にした場合

The result when the number of zeros is set to five.

ゼロの数を6個にした場合

The result when the number of zeros is set to six.

どうやらランダムに選ばれた値を使った方法でも、ゼロの数が大きくなると計算に時間がかかるようです。

Even with randomly chosen values, it seems to take longer to calculate as the number of zeros increases.

ゼロの数を3個にした場合

The result when the number of zeros is set to three.

しかし、どうやら複数のノンスが存在するようです。

However, it seems that there are several nonces.



以上です。お疲れ様です。

That's all. Thank you for your hard work.