本系列內容包含:基本概念及原理、密碼學、共識演算法、錢包及節點原理、挖礦原理及實現。
區塊結構構成
每個區塊主要包括區塊頭(下圖灰色的部分)和交易主體(下圖橙色的部分)兩部分。
整個區塊頭中內容包含:
第一個是前序區塊的雜湊,這樣區塊才能跟前面區塊鏈起來,形成一個鏈;
第二個是時間戳,表明區塊是在什麼時間被挖出來的;
第三個是難度的目標值,礦工挖礦的過程,其實就是在不斷的計算挖出來的區塊是否和難度值相匹配;
第四個Nonce 是一個隨機數;
最後 Merkle root ,記錄的是整個包含在當前區塊中所有交易的交易雜湊,Merkle root是透過交易雜湊計算出來的。
我們透過下圖比特幣的一個區塊結構來具體分析一些。
1、Magic Number(魔數)佔4個位元組,一般是固定值;
2、Block Size(區塊大小)佔4個位元組,可變值;
3、Version(版本)佔4個位元組,標明當前版本,固定值;
4、Previous Block Hash(前序區塊雜湊)佔32個位元組,可變值;
5、Merkle Root(默克爾根)佔32個位元組,可變值;
6、Timestamp(時間戳)佔4個位元組,可變值;
7、Difficulty(難度值)佔4個位元組,可變值;
8、Nonce(隨機數)佔4個位元組,可變值;
9、Transaction Counter(交易的數量)佔1-9個位元組,可變值;
10、總共的Transaction List(交易列表)加在一起總共是1MB。
區塊雜湊
每個區塊都有其唯一標識,這就是區塊的雜湊,區塊雜湊是由區塊頭中的幾部分來構成。
從上圖可以看出
區塊0對區塊頭中的中間標紅部分進行雜湊計算,得到當前區塊0的雜湊,然後區塊0的雜湊會填入下一個區塊(區塊1)中,作為下一個區塊頭的一部分。
以此類推,所有的區塊都會按照這個順序不斷的加下去,所以透過前序區塊的雜湊就可以找到唯一的前一個區塊,從而達到所有區塊可追溯的目的,這樣也保證了區塊鏈是完整的,唯一的。
雜湊運算
上圖中大家可以看到左側有五句話,中間是雜湊演算法,經過運算之後得到對左側話語的雜湊運算結果。
圖中的第一句話只有三個字,第二、三、四句話的區別只有一個字,第五句話完全不同。
我們可以看出,不管字數多少,哪怕只改一個字,最終結果卻是完全不同的,並且完全沒有任何規律。
雜湊運算的這種特性,保證了資料的不可變更。因為一旦變更之後,整個結果就變了。所以在很多場合中,我們可以透過驗證雜湊來保證被加密文字有沒有被改變。
雜湊運算的這個特點保證了,即使區塊中有即使兩個區塊只有一個位元組不一樣,這兩個區塊的雜湊也是完全不一樣的,從而保證區塊鏈中所有的區塊雜湊都是完全唯一的。
Merkle root
Merkle root 涉及一個區塊頭中非常重要的一個部分,但是它卻和區塊頭中其它幾個部分是沒有任何關係的。
與 Merkle root 最大關係的就是整個區塊頭區塊中的所有交易,這些交易決定了 Merkle root 的值,然後透過Merkle root 的值來影響整個區塊的雜湊。
Merkle root 是如何計算的呢?
從上圖中我們看到是由16個交易組成了 Merkle root,也稱之為默克爾根。
所有的這16個交易,都排布在交易的最底層,AB是一對,CD是一對,一直到OP。其中HA呢表示交易A的雜湊,以此類推。
計算的過程中,是將HA和HB拼成一個字串,然後對這個字串進行哈運算,得到了HAB。以此類推,分別計算後面的雜湊。
第一層算完以後,所有的雜湊由16個縮短為8個,繼續按照同樣的方式經過第二層計算以後,雜湊縮短為4個……以此類推,最終得到Merkle root,這種結構也稱之為默克爾樹。
這種結構不單單標記了所有交易的順序,也標記了所有交易的關係,並且透過這種非常巧妙的方式,也降低了Merkle root的計算次數。因為整個的計算層次是2的冪指數的情況,即使交易呈指數的增加,其計算次數也不會增加很多。
有一種情況是假如默克爾根不正好是2的冪指數怎麼辦?比如說只有3個或者5個交易,這種情況該如何計算呢?
上圖圖中我們看到只有3個交易,由於HC是單獨的,它的旁邊沒有另外一個交易和它拼成一個字串,這種情況下就會選擇將HC複製,也就是兩個HC拼一個完整字串,從而得到HCC。最後,將HAB和HCC拼成一個字串HABCC進行計算。以此完成這個只有3個交易的Merkle root計算。
總結:計算Merkle root的時候,首先將所有的交易有序的平鋪在一層,然後兩兩一組,逐步獲得上一層的雜湊;
當某個交易雜湊,為單數的時候,這時將這個雜湊複製一份來進行補足,然後繼續進行上層計算,直到最終完成 Merkle root 計算;
透過這種方式,可以將區塊中所有的交易繫結在一起,並且交易的內容和順序都是確定的;
最後將Merkle root填到區塊頭中,既保證了所有的交易摘要在區塊頭中有一個記錄,又保證了區塊中所有交易的不可篡改。
其他
時間戳 記錄當前區塊是在什麼時間被挖出來的,它會在瀏覽器中把時間軸轉換成當地時間的格式,也就是我們在區塊鏈瀏覽器中看到的區塊時間。
挖礦難度 其實是一個目標值,只有礦工挖出來的區塊,滿足這個難度值的時候,這個區塊才會被全網的其它節點來確認。
Nonce 是一個隨機數,礦工挖礦的過程中,就是不斷的在嘗試修改這個隨機數。