目錄
0、比特幣交易流程
從交易的生命週期來看,比特幣系統的交易流程如下步驟:
(1)源節點創建交易,並驗證目的節點的地址;
(2)源節點對交易進行簽名加密;
(3)源節點將該交易進行廣播至全網其他節點;
(4)全網節點接收交易並驗證其有效性,直到該交易被全網大多數節點驗證和接受;
(5)交易暫存於節點內存池,並判斷是否孤立交易;
(6)交易被打包至節點本地區塊中;
(7)全網共識結束後,獲勝節點將其本地區塊追加到主鏈;
(8)交易在主鏈上被越來越多的後續區塊確認。
對於區塊鏈的運行過程可以分爲:交易生成、網絡傳播與驗證、交易池管理、交易優先級排序、交易手續費定價、共識競爭與構建區塊、難度調整機制、分叉處理與主鏈判定。
1、生成交易
源節點的錢包將會創建一個新的交易,該交易中使用的比特幣來自於節點的一個或多個UTXO(未花費的交易輸出,Unspent Transaction Output)。源節點將目的節點的公鑰作爲交易的參數,同時使用自己的私鑰對生成的新交易進行簽名。
與以太坊等區塊鏈系統採用的賬戶模型不同,比特幣系統並沒有賬戶和餘額的概念,而是採用UTXO來記錄比特幣資產的歸屬和計算賬戶的餘額。
2、網絡傳播與驗證
傳播:交易被創建後,就由源節點廣播發送至比特幣網絡。由於比特幣網絡是P2P網絡,交易的傳播採用Gossip協議,由源節點首先發送至其相鄰節點,這些相鄰節點再次將交易轉發給他們的相鄰節點。以此類推,一筆交易可以在極短時間內以指數級擴散的速度在全網傳播,直到所有連接到網絡的節點都接收到它,從而最終傳遞到目的節點。
驗證:每個比特幣節點在接收到一筆交易後,都會獨立地對交易的有效性進行驗證,驗證規則(驗證機制)。
驗證機制:以比特幣網絡爲例,節點接收到鄰近節點發來的數據後,首要工作就是驗證數據的有效性。礦工節點會收集和驗證P2P網絡中廣播的尚未確認的交易數據,並對照預定義的標準清單,從以下幾個方面對數據進行有效性驗證:
(1)驗證區塊大小在有效範疇;
(2)確認數據區塊數據結構的有效性;
(3)驗證區塊至少含有一條交易;
(4)驗證第一個交易是CoinBase交易,有且僅有一個。
(5)驗證區塊頭部的有效性;
①確認區塊版本號是本節點可兼容的;
②區塊引用的前一區塊是有效的;
③區塊包含的所有交易構建的默克爾樹是正確的;
④時間戳合理;
⑤區塊難度與本節點計算的相符;
⑥區塊哈希值滿足難度要求。
(6)驗證區塊內的交易有效性。
-檢查交易語法正確性;
-確保輸入與輸出列表都不能爲空;
-lock_time小於或者等於INT_MAX,或者nLockTime和nSequence的值滿足MedianTimePast(當前區塊之前的11個區塊時間的中位數)。
-交易的字節大小大於等於100。
-交易中籤名數量小於簽名操作數量上限(MAX_BLOCK_SIGOPS)。
-解鎖腳本(scriptSig)只能夠將數字壓入棧中,並且鎖定腳本(scriptPubkey)必須要符合isStandard的格式。
-對於coiinbase交易,驗證簽名長度爲2~100字節。
-每個輸出值,以及總量,必須在規定值的範圍內(不超過全網總幣量,大於0)。
-對於每個輸入值,如果引用的輸出存在內存池中任何的交易,該交易將被拒絕。
-驗證孤立交易。
-如果交易費用太低(低於minRelayTxFee)以至於無法進入一個空的區塊,則交易將被拒絕。
-每一個輸入的解鎖腳本必須依據相應輸出的鎖定腳本來驗證。
-如果不是coinbase交易,則確認交易輸入有效,對於每一個輸入:
——驗證引用的交易存於主鏈;
——驗證引用的輸出存於交易;
——如果引用的是Coinbase交易,確認至少獲得COINBASE_MATURITY(100)個確認;
——確認引用的輸出沒有被花費;
——驗證交易簽名有效;
——驗證引用的輸出金額有效;
——確認輸出金額小於等於輸入金額(差額即爲手續費)。
-如果是Coinbase交易,確認金額小於等於交易手續費與新區塊獎勵之和。
3、交易池管理
節點驗證交易後,會將有效的交易添加到自己的內存池中,內存池是節點維護的一份未確認交易的臨時列表,其主要功能是暫時存放那些已在網絡中廣播但尚未打包到區塊中的待確認有效交易;這些交易將會在內存池中等待礦工將它們打包,封裝到下一個區塊中。內存池存儲在節點本地內存而不是硬盤中。
4、交易優先級排序
交易優先級=((UTXO交易額*UTXO存在時間))/交易的字節長度;
5、交易手續費定價
比特幣系統採用0.576作爲交易的基準優先級,如果交易優先級小於該基準優先級則會被收費。
6、共識競爭與構建區塊
一般說來,PoW共識中每個礦工都重複性的完成如下步驟,最快搜索到符合要求的隨機數Nonce的礦工獲勝並取得記賬權:
步驟1:蒐集當前時間段的全網未確認交易,並增加一個用於發行新比特幣獎勵的Coinbase交易,形成當前區塊體的交易集合;
步驟2:計算區塊體交易集合的默克爾根記入區塊頭,並填寫區塊頭的其他元數據,其中隨機數Nonce置爲零。
步驟3:隨機數Nonce加1;
步驟4:如果一定時間內未成功,則更新時間戳和未確認交易集合,重新計算默克爾根後繼續搜索。
7、難度調整機制
難度是區塊鏈系統的重要參數,用來度量礦工成功挖到下一個區塊的難易程度。比特幣的全網難度隨區塊頭目標值的變化而變化,目標值越小,難度值越大。
當前區塊難度Difficulty=(創世區塊Target)/(當前區塊Target)
區塊鏈的網絡難度並非一成不變,而是根據網絡算力的情況不斷調整。
8、分叉處理與主鏈判斷
如果多個礦工節點在同一時間段內成功搜索到符合哈希結果要求的隨機數,則這些礦工都將認爲自己在共識競爭中獲勝並向比特幣網絡中廣播其構造的區塊,從而產生在同一區塊高度出現多個不同的有效區塊的情況,即產生分叉現象。
爲保證區塊鏈系統中僅有唯一的主鏈,必須定義合適的主鏈判斷準則來從多個分叉鏈中選擇符合條件的唯一主鏈。此時不在主鏈上的區塊將成爲“孤塊”,發現孤塊的礦工節點也不會得到相應的比特幣獎勵。因此,區塊鏈的形狀並非單一的“鏈條”,而是一個樹狀結構。每個共識輪次對應的時間點上僅有唯一區塊是有效的,因而樹狀結構中也僅有唯一的主鏈條。
比特幣中根據“最大工作量原則”確定主鏈。