經過源碼學習比特幣 -- 挖礦

挖礦的過程就是區塊生成的過程 同時也是比特幣「發行」的過程。css

1. 礦工節點經過暴力碰撞法找到知足條件的哈希值(下文詳述) 即爲挖礦成功,從而獲取比特幣獎勵算法

  • 大約每十分鐘產生一個區塊, 每210000個區塊(大約4年)獎勵比特幣減半
  • 2009.1 – 50個比特幣, 2012.11 – 25個, 2016 – 12.5個
  • 到2040年, 總比特幣數量達到 2099 9999.98個
  • 2140年後 新區快再也不獎勵新比特幣 礦工收益所有來自交易費

2. 礦工獎勵分爲兩部分:coin base 交易獎勵 + 新建區塊中交易費用總和bash

下面是計算礦工獎勵的比特幣源碼:markdown

int64_t GetBlockValue(int nHeight, int64_t nFees) {// nFees = Sum(vin[i]) - Sum (vout[i]) 區塊包含的交易費用總和

        int64_t nSubsidy = 50 * COIN; //COIN = 100000000 (一億聰),初始獎勵50比特幣

                 int nHalving = nHeight / 210000; //nHeight:區塊高度

                 if (nHalving >= 64) 

                        return nFees;

                nSubsidy >>= nHalving; //每210000個區塊獎勵減半(右移位操做 提升運算效率)

                return nSubsidy + nFees;

}

3. 交易發起者建立交易後,將其broadcast到相鄰節點。每一個節點獨立的對接收到的交易進行驗證函數

下面是比特幣源碼相關函數post

CheckInputs(); CheckTransaction(); AcceptToMemoryPool();

符合規則的交易被加入內存的交易池並broadcast到其餘節點區塊鏈

4. 挖礦節點對內存交易池的交易按優先級排序,因爲區塊大小有限制 ,優先級低的交易不能被打包進區塊ui

交易優先級計算:spa


priority = sum (vin[i].value * vin[i] age)/sizeof(Tx) 
.net

- vin[i].value: 交易輸入金額 以聰爲單位;
- vin[i] age : 交易輸入所指向的utxo所在的區塊的深度 (距離最新區塊高度的距離 天天增大144)

- 轉帳金額越大 所使用的utxo越老 字節數越小 的交易優先級越高! 
- priority > 57600000 的tx 定義高優先級;(100 000 000 satoshi * 144)/ 250 byte 
- 每一個區塊的前50k空間留給高優先級的tx , 剩下的按照」交易費/Kb」由高到低排序 直到達到MAX_BLOCK_SIZE; 
- 節點軟件重啓 內存交易池會被清空; 
- 若是交易長時間未被加入區塊,交易發起節點應提升交易費從新發送;

5. 創幣交易:即上文提到的給礦工的coin base 交易獎勵, 做爲每一個新生成的block的第一筆交易

  • 只有一個vin, 其指向的utxo所在的交易hash爲0x0000…(32字節)
  • utxo 的輸出索引vout nOut 爲0xFFFFFFFF 表示不指向任何UTXO;
  • 交易輸出金額爲系統獎勵(目前爲12.5BTC) 發給挖礦節點本身的地址,比特幣就是這麼發行的
  • 不包含scriptSig腳本, 以區塊高度開頭,剩餘字節可由礦工任意填充 (最大100字節)

6. 挖礦算法:經過不斷變換nNonce值 使SHA256(SHA256(區塊頭))的哈希值小於等於目標哈希值nhashTarget

  • nhashTarget 由區塊頭中的nBits值決定,其大小是依據全網算力不斷調整的,全網算力越高難度越大,從而使區塊生成速度保持在10分鐘左右

  • 難度值調整 函數: GetNextWorkRequired()

詳情請參考另外一篇博客: https://www.jianshu.com/p/122642177711

7. 區塊鏈分叉 
- 節點依據最長鏈(最多工做量)原則選擇主鏈, 幾乎每週都會發生單塊的分叉,雙塊分叉幾乎不多發生; 
- 當兩個塊A,B幾乎同時產生時, 節點會加入先收到的塊A,拋棄後收到的B(另外一部分節點先收到B); 
- 若是先收到B的節點又收到新塊C時,B->C做爲最長鏈(主鏈)廣播到全網,A塊就會變成備用分叉鏈; 
- 孤塊:節點收到一個新塊,它的父塊沒有在本身的鏈中找到,則將其加入孤塊池,直到接收到其父塊後再將其加入主鏈; 
- 每10分鐘產生一個新塊,是在更快的交易確認速度和更少的分叉之間作出的權衡。

8. 51%攻擊:

  • 並非擁有51%以上的算力才能攻擊,只是擁有的算力越高 成功的機率就越大,事實上 擁有30%的算力就能夠嘗試攻擊。

  • 目前全網算力達到近40Eh/s, 承指數級增加

1Eh == 1000Ph; 1Ph == 1000Th; 1Th == 1000Gh; 1Gh == 1000Mh; 1Mh==1000Kh (h:hash/sha256)

9. 雙重支付攻擊

  • 小額交易A時(買咖啡) 商家不等交易A被區塊確認就交付了商品,這時買家又用同一個utxo進行另一筆交易B(轉給本身的另一個地址),這交易B就有可能先被加入礦工的區塊從而使交易A失效

  • 51% 算力使區塊鏈分叉

    當一筆交易A被加入到一個區塊中獲得確認後,買家經過本身控制的擁有超高算力的礦池,生成一個交易B 並將交易A的utxo發給本身錢包 同時刪除交易A, 利用本身強大的算力生成分叉區塊並讓本身的分叉成爲主鏈。以前交易A所在的區塊則成爲了一個分叉…

  • 所以對於大額交易,通常要等至少6個區塊確認以後在交付商品,以免51%算力雙重支付攻擊。

10. 拒絕服務攻擊

  • 擁有超級算力的節點或礦池, 經過刪除區塊中的某些特定地址的交易 從而使某些地址的交易一直不能被加入到區塊鏈。
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息