Angular, Blockchain, Science とか

Angular, Blockchain, Science全般 の情報を主に書いていきます。

ビットコイン difficulty target と retargeting 

difficulty target は係数部/指数部形式で表す。

指数部(exponent),係数部(coefficient)で

target = coefficient * 2^(8 * (exponent - 3))

^はXORです。

またDifficultyはブロックの生成期間を10分に保つように動的に変化します。

Difficultyは2016ブロックごとにretargetされます。

ActualTimespan は 最後の2016ブロックが生成されるのにかかった時間です。

式にすると

New Difficulty = Old Difficulty * (Actual Time of Last 2016 Blocks / 2016 minutes)

ソースコードは

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
    if (params.fPowNoRetargeting)
        return pindexLast->nBits;

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
    
    // difficultyが動きすぎないように、もし調整が 4倍 or 4/1 以上動く場合
    // 最大でも4、最小でも4/1になるようになっている。
    if (nActualTimespan < params.nPowTargetTimespan/4)
        nActualTimespan = params.nPowTargetTimespan/4;
    if (nActualTimespan > params.nPowTargetTimespan*4)
        nActualTimespan = params.nPowTargetTimespan*4;
    // Retarget
    const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
    arith_uint256 bnNew;
    bnNew.SetCompact(pindexLast->nBits);
    bnNew *= nActualTimespan;
    bnNew /= params.nPowTargetTimespan;

    if (bnNew > bnPowLimit)
        bnNew = bnPowLimit;

    return bnNew.GetCompact();
}

のようになります。