LoginSignup
8
10

More than 3 years have passed since last update.

PoWにおけるマイニングのプログラムを作ってみた

Last updated at Posted at 2019-10-08

はじめに

こんにちは。ブロックチェーン技術関連の記事になります。
この記事では、コンセンサスアルゴリズムであるPoWにおけるマイニングのプログラムについて書いていきます。
ブロックチェーン技術の詳しい内容についてはこちらの「ブロックチェーン技術及び関連技術(ブロックチェーン実装あり)」の記事を参照してください。

よろしくお願いします。

環境

  • Windows 10 home
  • Python 3.7.3

プログラム

mining.py
import hashlib
import random
import string

class Mining():
    def __init__(self,difficulty):
        self.data = self.calcRandomText(10) #データ
        self.difficulty = difficulty #求める規定のハッシュ値の難易度(何文字か)
        self.nonce = 0 #ナンス
        self.answerText = self.calcRandomHexDigitsText(self.difficulty) #求める規定のハッシュ値を算出
        self.nonceDataText = self.calcNonceDataText() #データとナンス値を合わせる
        self.hashText = self.calcHash(self.nonceDataText) #ハッシュ値を算出する

        self.miningLoop() #マイニング開始

    def calcRandomText(self,num): #ランダムな文字列を返す
        _randTextList = [random.choice(string.ascii_letters + string.digits) for i in range(num)]
        return "".join(_randTextList)

    def calcRandomHexDigitsText(self,num): #16進数のランダムな文字列を返す
        _randHexDigitsTextList = [random.choice(string.hexdigits) for i in range(num)]
        return "".join(_randHexDigitsTextList)

    def calcNonceDataText(self): #データのナンス値を合わせる
        return self.data + str(self.nonce)

    def calcHash(self,text): #ハッシュ値を算出する
        return hashlib.sha256(text.encode("utf-8")).hexdigest()

    def miningLoop(self): #マイニングのメソッド
        while self.hashText[-1*self.difficulty:] != self.answerText.lower():
            print("マイニング中  試行回数:" + str(self.nonce+1) + "  求める規定のハッシュ値:"+ self.answerText.lower() + "  算出ハッシュ値:" + self.hashText[-1*self.difficulty:])
            self.nonce += 1 #ナンス値に1を加算していく
            self.nonceDataText = self.calcNonceDataText() #データとナンス値を合わせる
            self.hashText = self.calcHash(self.nonceDataText) #ハッシュ値を算出する
        print("マイニング中  試行回数:" + str(self.nonce+1) + "  求める規定のハッシュ値:"+ self.answerText.lower() + "  算出ハッシュ値:" + self.hashText[-1*self.difficulty:] + "\n")

        print("マイニング成功!" + "  データ:" + self.data + "  ナンス値:" + str(self.nonce))
        print("マイニングに成功したハッシュ値:" + self.calcHash(self.data + str(self.nonce)))

def main():
    difficulty = 3 #求める規定のハッシュ値の難易度(何文字か)
    mining = Mining(difficulty) #インスタンスの生成

if __name__ == "__main__":
    main()

マイニングを成功させるには、規定のハッシュ値を算出するためにナンスの計算をし続けます

このプログラムでは、既定のハッシュ値というのはメイン関数にあるdifficultyの値によって決まる特定の値と算出されたハッシュ値の末の値が一致しているハッシュ値のことです。

ハッシュ値から入力データを予測することは困難なので、規定のハッシュ値を算出できるまで、ハッシュ関数にいろんなデータを突っ込みます。そこでいろんなデータにするために使うものがナンスです。
ナンスの使い方としては、ナンスに1を加算しては、ナンスをデータに足して、ハッシュ関数に突っ込むといった感じです。
これを繰り返し、規定のハッシュ値を算出していきます。

ぜひdifficultyの値を変えてみて、マイニングの試行がどのくらいの間隔を生み出すのか試してみてください。

これがプルーフオブワーク!仕事量の証明です!
ここまで読んでいただき、ありがとうございました。

8
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
10