- 發行新的貨幣(總量達到之前)
- 維繫貨幣的支付功能
- 透過算力保障系統安全
欄位名 | 含義 | 大小(位元組) |
---|---|---|
version | 版本號 | 4 |
hashprevblock | 上一個block hash值 | 32 |
hashmerkleroot | 上一個block產生之後至新block生成此時間內, 交易資料打包形成的hash | 32 |
time | unix時間戳 | 4 |
bits | 目標值,即難度 | 4 |
nonce | 隨機數 | 4 |
12345678910111213141516171819 |
|
123456 |
|
block欄位詳解
- version,版本號,很少變動,一般用於軟體全網升級時做標識
- hashprevblock,前向block hash值,該欄位強制多個block之間形成連結
- hashmerkleroot,交易hash樹的根節點hash值,起校驗作用,保障block在網路傳輸過程中的資料一致性,有新交易加入即發生變化
- time,unix時間戳,每秒自增一,標記block的生成時間,同時為block hash探尋引入一個頻繁的變動因子
- bits,可以推算出難度值,用於驗證block hash難度是否達標
- nonce,隨機數,在上面數個欄位都固定的情況下,不停地更換隨機數來探尋
最為關鍵的欄位是hashprevblock,該欄位使得block之間連結起來,形成一個巨大的“鏈條”。block本是稀鬆平常的資料結構,但以鏈式結構組織起來後卻使得它們具有非常深遠的意義:
- 形成分支博弈,使得算力總是在主分支上角逐
- 算力攻擊的概率難度呈指數上升(泊松分佈)
每個block都必須指向前一個block,否則無法驗證透過。追溯至源頭,便是高度為零的創世紀塊(genesis block),這裡是block chain的起點,其前向block hash為零,或者說為空。
新block誕生過程
下面是一個簡單的步驟描述,實際礦池運作會有區別,複雜一些:
- 節點監聽全網交易,透過驗證的交易進入節點的記憶體池(tx mem pool),並更新交易資料的merkle hash值
- 更新時間戳
- 嘗試不同的隨機數(nonce),進行hash計算
- 重複該過程至找到合理的hash
- 打包block:先裝入block meta資訊,然後是交易資料
- 對外部廣播出新block
- 其他節點驗證透過後,連結至block chain,主鏈高度加一,然後切換至新block後面挖礦
由於hashprevblock欄位的存在,使得大家總是在最新的block後面開挖,稍後會分析原因。
主鏈分叉
從block hash演算法我們知道,合理的block並不是唯一的,同一高度存在多個block的可能性。那麼,當同一個高度出現多個時,主鏈即出現分叉(fork)。遇到分叉時,網路會根據下列原則選舉出best chain:
- 不同高度的分支,總是接受最高(即最長)的那條分支
- 相同高度的,接受難度最大的
- 高度相同且難度一致的,接受時間最早的
- 若所有均相同,則按照從網路接受的順序
- 等待block chain高度增一,則重新選擇best chain
按照這個規則運作的節點,稱為誠實節點(honest nodes)。節點可以誠實也可以不誠實。
分支博弈
我們假設所有的節點:
- 都是理性的,追求收益最大化
- 都是不誠實的,且不惜任何手段獲取利益
所有節點均獨自挖礦不理會其他節點,並將所得收益放入自己口袋,現象就是一個節點挖一個分支。由於機器的配置總是有差別的,那麼算力最強的節點挖得的分支必然是最長的,如果一個節點的分支不是最長的,意味其收益存在不被認可的風險(即零收益)。為了降低、逃避此風險,一些節點肯定會聯合起來一起挖某個分支,試圖成為最長的分支或保持最長分支優勢。
一旦出現有少量的節點聯合,那麼其他節點必然會效仿,否則他們收益為零的風險會更大。於是,分支迅速合併彙集,所有節點都會選擇算力更強的分支,只有這樣才能保持收益風險最小。最終,只會存在一個這樣的分支,就是主幹分支(best/main chain)。
對於不誠實節點來說,結局是無奈的:能且只能加入主幹挖礦。不加入即意味被拋棄,零收益;加入就是老實幹活,按佔比分成。
hash dance
block hash的計算是隨機概率事件,當有節點廣播出難度更高的block後,大家便跑到那個分支。在比特幣系統執行過程中,算力經常在分支間跳來跳去,此現象稱為hash dance。一般情況下,分支的高度為1~2,沒有大的故障很難出現高於2的分支。
hash dance起名源於google dance.
算力攻擊的概率
算力攻擊是一個概率問題,這裡作簡單敘述:
- p = 誠實節點挖出block概率
- q = 攻擊者挖出block概率,q = 1 – p
- qz = 攻擊者從z個block追上的概率
我們假設p>q,否則攻擊者掌握了一半以上的算力,那麼概率上永遠是贏的。該事件(攻擊者勝出)的概率是固定,且n次事件之間是相互獨立的,那麼這一系列隨機過程符合泊松分佈(poisson distribution)。z個塊時,攻擊者勝出的期望為lambda:
攻擊者在攻擊時已經偷偷的計算了k個塊,那麼這