1
0

Go言語でブロックチェーンのシステムを作成する(その4)

Last updated at Posted at 2024-04-14

はじめに

前回は、transactionsの実装までやりましたが、今回はnonceの実装をしていきます。

  • 前回までの記事

  • バージョン
    • Go 1.22.0

nonceとは

nonceは、新しいブロックを作成する時に、そのブロックが正しいものだと証明するために使われます。
下の図のように新しいブロックを作成する時に、challenge、prev hashとtransactionsを使用してハッシュを生成します。このときchallengeはnonceに入れる候補となる値です。
例えば下の図では、生成したハッシュの先頭が000となるまでchallengeを増やしていって、challengeが10の時ハッシュの先頭が000になったので、challengeの値である10をnonceに入れてブロックを作成します。
今回は、先頭3文字が0になるまで計算する実装にしています。この先頭何文字までが0になるまで計算するかの値をdifficultyと呼び、実際はもっと大きな値が設定されます。
ブロックチェーン5.png

実装

イメージ図

下の図のnonceの実装をしていきます。

ブロックチェーン2.png

nonceの実装

まず、nonceの実装をしていきます。

const MINING_DIFFICULTY = 3

func (bc *Blockchain) CopyTransactionPool() []*Transaction {
	transactions := make([]*Transaction, 0)
	for _, t := range bc.transactionPool {
		transactions = append(transactions,
			NewTransaction(t.senderBlockchainAddress,
				t.recipientBlockchainAddress,
				t.value))
	}
	return transactions
}

func (bc *Blockchain) ValidProof(nonce int, previousHash [32]byte, transactions []*Transaction, difficulty int) bool {
	zeros := strings.Repeat("0", difficulty)
	guessBlock := Block{0, nonce, previousHash, transactions}
	guessHashStr := fmt.Sprintf("%x", guessBlock.Hash())
	return guessHashStr[:difficulty] == zeros
}

func (bc *Blockchain) ProofOfWork() int {
	transactions := bc.CopyTransactionPool()
	previousHash := bc.LastBlock().Hash()
	nonce := 0
	for !bc.ValidProof(nonce, previousHash, transactions, MINING_DIFFICULTY) {
		nonce += 1
	}
	return nonce
}

今回は、difficultyを3として実装するので、MINING_DIFFICULTY=3で定数を定義します。
CopyTransactionPoolでは、Poolにあるtransactionsをコピーしています。
ValidProofでは、引数で受け取ったnonceとpreviousHashとtransactionsを使ってハッシュを生成し、そのハッシュが有効なものか(今回の実装では、生成されたハッシュの先頭3文字が000であるとき有効)を求めています。
ProofOfWorkでは、nonceを1ずつ増やしながら、ValidProofをループさせて実行して、解答となるnonceを求めています。

おわりに

今回は、nonceの実装をしていきました。
次回は、マイニングの実装をしていきます。

次の記事

参考

1
0
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
1
0