比特幣的挖礦難度調(diào)整源代碼分析

關(guān)于比特幣難度調(diào)整部分見《精通比特幣》8.7.3節(jié)

先介紹一下CBigNum凤优。

CBigNum

CBigNum是openssl庫(kù)中定義的BIGNUM的包裝類。公鑰密碼學(xué)需要能夠處理非常大的整數(shù)姨蝴。標(biāo)準(zhǔn)的數(shù)據(jù)類型無法滿足要求萝嘁。BIGNUM可以存放任意長(zhǎng)度的整型。
CBigNum類的結(jié)構(gòu)并不復(fù)雜。它是由一堆不同類型構(gòu)造BIGNUM的構(gòu)造器組成靡砌,包括char,short珊楼,int通殃,long,int64厕宗,int256画舌,它們unsigned版本和vector<unsigned char>等。它同樣重構(gòu)操作符已慢,例如加曲聂、減、乘佑惠、除朋腋、位操作等。所有的實(shí)際工作代理給了BIGNUM類行膜楷。大部分CBigNum的代碼僅僅是為BIGNUM的函數(shù)準(zhǔn)備輸入數(shù)據(jù)旭咽。

難度調(diào)整

這部分源代碼比較簡(jiǎn)單,如下:

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
{
    const unsigned int nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
    const unsigned int nTargetSpacing = 10 * 60;
    const unsigned int nInterval = nTargetTimespan / nTargetSpacing;

    // Genesis block
    if (pindexLast == NULL)
        return bnProofOfWorkLimit.GetCompact();

    // Only change once per interval
    if ((pindexLast->nHeight+1) % nInterval != 0)
        return pindexLast->nBits;

    // Go back by what we want to be 14 days worth of blocks
    const CBlockIndex* pindexFirst = pindexLast;
    for (int i = 0; pindexFirst && i < nInterval-1; i++)
        pindexFirst = pindexFirst->pprev;
    assert(pindexFirst);

    // Limit adjustment step
    unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime;
    printf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
    if (nActualTimespan < nTargetTimespan/4)
        nActualTimespan = nTargetTimespan/4;
    if (nActualTimespan > nTargetTimespan*4)
        nActualTimespan = nTargetTimespan*4;

    // Retarget
    CBigNum bnNew;
    bnNew.SetCompact(pindexLast->nBits);
    bnNew *= nActualTimespan;
    bnNew /= nTargetTimespan;

    if (bnNew > bnProofOfWorkLimit)
        bnNew = bnProofOfWorkLimit;

    /// debug print
    printf("\n\n\nGetNextWorkRequired RETARGET *****\n");
    printf("nTargetTimespan = %d    nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
    printf("Before: %08x  %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
    printf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());

    return bnNew.GetCompact();
}

nTargetTimespan 為兩個(gè)星期的秒數(shù)赌厅,nTargetSpacing 為10分鐘的秒數(shù)轻专。nInterval = nTargetTimespan / nTargetSpacing;即為2016個(gè)區(qū)塊。

難度的調(diào)整是在每個(gè)完整節(jié)點(diǎn)中獨(dú)立自動(dòng)發(fā)生的察蹲。每2,016個(gè)區(qū)塊中的所有節(jié)點(diǎn)都會(huì)調(diào)整難度请垛。難度的調(diào)整公式是由最新2,016個(gè)區(qū)塊的花費(fèi)時(shí)長(zhǎng)與20,160分鐘(兩周,即這些區(qū)塊以10分鐘一個(gè)速率所期望花費(fèi)的時(shí)長(zhǎng))比較得出的洽议。難度是根據(jù)實(shí)際時(shí)長(zhǎng)與期望時(shí)長(zhǎng)的比值進(jìn)行相應(yīng)調(diào)整的(或變難或變易)宗收。簡(jiǎn)單來說,如果網(wǎng)絡(luò)發(fā)現(xiàn)區(qū)塊產(chǎn)生速率比10分鐘要快時(shí)會(huì)增加難度亚兄。如果發(fā)現(xiàn)比10分鐘慢時(shí)則降低難度混稽。

首先函數(shù)會(huì)計(jì)算當(dāng)前區(qū)塊是否到達(dá)下個(gè)難度周期,如果沒有達(dá)到审胚,則難度位即為上一區(qū)塊的難度位匈勋。return pindexLast->nBits;
如果已經(jīng)達(dá)到一個(gè)新的難度周期,則通過循環(huán):

for (int i = 0; pindexFirst && i < nInterval-1; i++)
        pindexFirst = pindexFirst->pprev;

向前尋找2016個(gè)區(qū)塊膳叨,此時(shí)pindexFirst指向上一難度周期的第一個(gè)區(qū)塊洽洁。
nActualTimespan = pindexLast->nTime - pindexFirst->nTime
即利用上一難度周期的最后一個(gè)塊的時(shí)間戳減去第一個(gè)區(qū)塊的時(shí)間戳,其結(jié)果為上一難度周期總共花費(fèi)的時(shí)間nActualTimespan 菲嘴。

為了防止難度的變化過快饿自,每個(gè)周期的調(diào)整幅度必須小于一個(gè)因子(值為4)汰翠。如果要調(diào)整的幅度大于4倍,則按4倍調(diào)整昭雌。由于在下一個(gè)2,016區(qū)塊的周期不平衡的情況會(huì)繼續(xù)存在复唤,所以進(jìn)一步的難度調(diào)整會(huì)在下一周期進(jìn)行。因此平衡哈希計(jì)算能力和難度的巨大差異有可能需要花費(fèi)幾個(gè)2,016區(qū)塊周期才會(huì)完成烛卧。

這部分便是將上一難度周期消耗的時(shí)間與期望的時(shí)間作比較佛纫,并根據(jù)結(jié)果進(jìn)行調(diào)整。如果調(diào)整幅度大于4倍总放,則按4倍調(diào)整雳旅。

if (nActualTimespan < nTargetTimespan/4)
        nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
        nActualTimespan = nTargetTimespan*4;

如果小于4倍則根據(jù)比例進(jìn)行調(diào)整。

bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;

此時(shí)便完成了一個(gè)周期的難度調(diào)整间聊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市抵拘,隨后出現(xiàn)的幾起案子哎榴,更是在濱河造成了極大的恐慌,老刑警劉巖僵蛛,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尚蝌,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡充尉,警方通過查閱死者的電腦和手機(jī)飘言,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來驼侠,“玉大人姿鸿,你說我怎么就攤上這事〉乖矗” “怎么了苛预?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)笋熬。 經(jīng)常有香客問我热某,道長(zhǎng),這世上最難降的妖魔是什么胳螟? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任昔馋,我火速辦了婚禮,結(jié)果婚禮上糖耸,老公的妹妹穿的比我還像新娘秘遏。我一直安慰自己,他們只是感情好嘉竟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布垄提。 她就那樣靜靜地躺著榔袋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铡俐。 梳的紋絲不亂的頭發(fā)上凰兑,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音审丘,去河邊找鬼吏够。 笑死,一個(gè)胖子當(dāng)著我的面吹牛滩报,可吹牛的內(nèi)容都是我干的锅知。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼脓钾,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼售睹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起可训,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤昌妹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后握截,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體飞崖,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年谨胞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了固歪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胯努,死狀恐怖牢裳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情叶沛,我是刑警寧澤贰健,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站恬汁,受9級(jí)特大地震影響伶椿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜氓侧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一脊另、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧约巷,春花似錦偎痛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)枚赡。三九已至,卻和暖如春谓谦,著一層夾襖步出監(jiān)牢的瞬間贫橙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工反粥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卢肃,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓才顿,卻偏偏與公主長(zhǎng)得像莫湘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子郑气,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 一幅垮、快速術(shù)語(yǔ)檢索 比特幣地址:(例如:1DSrfJdB2AnWaFNgSbv3MZC2m74996JafV)由一串...
    不如假如閱讀 15,897評(píng)論 4 88
  • 錢包、密鑰 私鑰衍生家族----適用于各種樹形權(quán)限分配尾组,比如企業(yè)錢包 交易 交易費(fèi)按交易數(shù)據(jù)字節(jié)大小計(jì)算忙芒,交易費(fèi)市...
    觀星客閱讀 978評(píng)論 0 2
  • 《禮記·禮運(yùn)篇》云:“故人不獨(dú)親其親,不獨(dú)子其子演怎。使老有所終,壯有所用避乏,幼有所長(zhǎng)爷耀,鰥寡孤獨(dú)廢疾者,皆有所養(yǎng)”拍皮。 0...
    看見繁花閱讀 363評(píng)論 0 3
  • 創(chuàng)業(yè)解惑:一輩子是很短的铆帽。 不要以為自己浪費(fèi)了時(shí)間可以翻盤咆耿,不要以為自己今天不干活沒什么了不起的。 抓緊時(shí)間爹橱,釋放...
    創(chuàng)業(yè)解惑閱讀 206評(píng)論 0 0
  • 感賞自己堅(jiān)持5點(diǎn)鬧鈴起床萨螺,去操場(chǎng)快走25分鐘,買早點(diǎn)帶回家愧驱。 感賞兒子今天起床后便把手機(jī)放到了客廳茶幾上慰技,比昨天還...
    瑾言珅行閱讀 129評(píng)論 2 4