這一篇我們介紹“區塊”的“五臟六腑”,也就是它的詳細組成,如圖
看不懂沒關系,對著這張圖我給大家一一剖析。
首先,每一個區塊都有一個父區塊和子區塊,分別對應圖中的左邊的“父區塊”和右邊的“子區塊”,中間也是一個區塊,因為是作為典型來講,所以圖中我們列舉了它的核心元素。
人們根據職能將每個區塊劃分為兩個部分,區塊頭(Block Header)和區塊體(Block Body)。
先了解一下區塊體,區塊體內包含的是一條條的交易數據,列如張三給李四轉了一筆賬,轉賬者,接收者,金額,時間等等,這些信息構成一條交易數據,每一個區塊的區塊體都包含著大量的交易數據(比特幣的區塊大小是1M,區塊大小決定可容納的數據量),可以理解為,區塊體才是數據真正存儲的地方。
那什么是區塊頭呢,區塊頭是整個區塊的核心也是區塊的元數據,它的成員變量全都是公共的,這使得它可以很方便的向調用者提供關于Block屬性的操作。區塊頭的組成相對復雜,它的一條條信息我們詳細來看。
1、Hash值
由SHA256算法計算得出得當前區塊的哈希值(算法比較復雜,后面會統一講到),也是代表當前區塊的唯一值,可以理解成我們通常開發中Id的概念。每個區塊都有自己的唯一Hash。
2、父哈希(Pre Hash)
上一個區塊的哈希值。每個一區塊當中都保存著上一個區塊的Hash,可以理解為父子關系,因為除了第一個區塊(創世區塊),所有區塊的產生都是基于前一個區塊。
3、子哈希(Next Hash)
基于當前區塊所產生的下一個區塊的哈希值,當前區塊也就是子區塊的父區塊。
看到這里我們明白了,區塊鏈里面的“鏈”是如何體現的?其實就是由于每個區塊有當前Hash 、父Hash、子Hash的概念,這些所謂的“父”,“子”形成了一套完整的順序鏈條,換句話說,區塊與區塊之間并非雜亂無章,而是存在著嚴格的順序關系。而這種順序關系像極了鏈表的概念,二者的邏輯順序均是通過鏈表中的指針鏈接次序實現的。
鏈表:
其實區塊鏈和鏈表二者所謂的“鏈”,其實是同一種技術實現。
注:有一點點小的區別是區塊鏈是非循環的,而鏈表是可以有循環的。
OK,咱們繼續。
4、版本號(Version)
系統版本號,可以理解成日常開發中開發的軟件版本。
5、區塊高度(Height)
區塊鏈網絡中第幾個誕生的區塊序號,例如第一個區塊通常也被稱為創世區塊,高度為0(這很程序員),第十個產生的區塊高度為9(區塊并不是一下子就全有的,例如比特幣區塊就是每10分鐘產生一個,也就說區塊的“出生”都是有著先后順序的,這個順序我們會打上標簽,這個標簽就是”高度“)。
6、時間戳(TimeStamp)
區塊創建的時間,同時也交易數據打包進區塊的時間,區塊的誕生是伴隨著交易數據的打包記錄,保存的地方就是我們前面提到的區塊體。
7、隨機數(Nonce)
一個從0開始,最大長度為32位的隨機數,這里就涉及到挖礦了,所謂的挖礦,就是不停地變更區塊頭中的隨機數,并對每次變更后的區塊頭(block_header,)做雙重SHA-256運算(即SHA256 (SHA 256(Block_Header))),將結果值哈希反轉并與當前網絡的目標值對應的十進制字符串做對比,如果小于目標值,則解題成功,工作量證明完成。(這里先簡單了解即可,后面會重點講到)。
8、難度目標(Target Bits)
難度值是礦工們挖礦的重要參考指標,它決定了礦工大約需要經過多少次Hash運算才能產生一個合法的區塊。比特幣的區塊大約每10分鐘生成一個,如果要在不同的全網算力條件下,新區塊的產生都基本保持這個速率,難度值必須根據全網算力的變化進行調整。簡單地說,難度值被設定在無論挖礦能力如何,新區塊產生速率都保持在10分鐘一個。
難度值的調整是在每個完整節點中獨立自動發生的。每隔2016個區塊,所有節點都會按統一的公式自動調整難度值
公式如下:
新難度值 = 舊難度值*(過去2016個區塊花費時長/20160分鐘)
難度目標值= 最大目標值/新難度值
而最大目標值為一個恒定值(常量):0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
解題(挖礦)成功的依據是:
SHA256(SHA256(block_header)) < F(nBits)
即,挖礦結果的值 < 最大目標值
9、Merkle Root(默克爾樹根)
Merkle Root的計算過程相對復雜,一起放到最后的算法環節進行統一詳細講解。
實際上,區塊頭的組成遠不止這么點,這里只是為了方便講解不讓大家產生眩暈,我們只挑了一些核心元素講解,當然,對于我們簡單理解區塊的概念來說已經夠了。
OK,看完以上部分,相信大家對區塊已經有些許理解了,不過還沒完,好戲才剛剛開始,接下來才上重點中的重點。