Proof Of Work の検証
PoWの検証処理を見てみます。非常にシンプルなので読みやすそう。
見ていく前に、PoW におけるブロックが満たすべき条件を整理します。
ブロックハッシュが難易度よりも小さい値になっている
難易度(nBits)が、難易度の計算ロジックと一致している
code:pow.h
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
code:pow.cpp
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
{
bool fNegative;
bool fOverflow;
arith_uint256 bnTarget;
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
// Check range
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
return false;
// Check proof of work matches claimed amount
if (UintToArith256(hash) > bnTarget)
return false;
return true;
}
引数
引数から見ていきましょう。
uint256 hash
ブロックハッシュです。 uint256 はBitcoinのために定義された数値型です。ブロックのデータに対して SHA256 ハッシュ関数を使い求めます。
unsigned int nBits
難易度を表すブロックのフィールドです。このデータを基にブロックハッシュが満たすべき最小値を求めます。
const Consensus::Params& params
パラメータです。ここで参照しているparams.powLimit はメインネットでは次の値がセットされています。
00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
計算を追ってみる
Hash: 00000000000000000022620c52c2fe010f5aba8ebfa9bfbb035777f0a1e1c6d1
nBits: 389010995
上から見ていきます。
code: cpp
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
ここで、nBits を 256bit の数値型に変換しています。
参考