區塊鏈(Blockchain) 可簡單形象化地可理解為很多分散在世界各地的區塊(Block)以 "鏈"(Chain)的形式串連在一起,就猶如一串鐵鏈一樣,由很多小鐵環串成一條鐵鏈。這就是區塊鏈的形象化概念。
那麼,區塊鏈中的區塊實際上是什麼呢?以下以比特幣(BitCoin)區塊鏈中的區塊為例:
區塊(Block)
上述這張簡化版的比特幣區塊鏈圖中有三個區塊 Block 1, Block 2, Block 3.
每個區塊都包含兩個部份:區塊頭(Block Header)及區塊體(Block Body)
- 區塊頭(Block Header)
先看看區塊頭的數據結構
[cc lang="c"]
struct header_structure {
uint32_t nVersion; // 4 bytes - Version
uint8_t hashPrevBlock[32]; // 32 bytes - Previous block header hash
uint8_t hashMerkleRoot[32]; // 32 bytes - Merkle root hash
uint32_t nTime; // 4 bytes - Timestamp
uint32_t nBits; // 4 bytes - Difficulty Target
uint32_t nNonce; // 4 bytes Nonce
};
[/cc]
- 版本號(Version)
- 前一個區塊的 Hash值
- 能讓當前區塊與上一個區塊形成一個連結,而且能確保區塊的順序及過去區塊的準確性;
- 當前區塊的Hash值一定比這個Hash值小;
- Merkle Tree Root(Merkle樹根節點的Hash值)
- Timestamp 時間戳
- Difficulty Target 困難值
- 這個困難值每2016個區塊會調整一次;
- Nonce 隨機數
- 表示當前區塊工作量證明 PoW演算法進行的隨機數;
- 總區塊大小固定為80 Bytes
- 區塊體(Block Body)
- 包含了產生該區塊的所有數據,以比特幣區塊鏈為例,這裡數據即交易記錄(Transactions),並以 Merkle Tree形式表示;
在比特幣區塊中,比特幣支出和接收交易是一起記錄的,整個收支記錄包括很多筆記錄,而每一筆記錄都有自己的索引編號,方便查詢。
同時,每筆記錄中還包含了生成時間、引用交易的Hash值、交易記錄索引編號、比特幣支出地址等等的數據。而每一筆收支交易記錄都有一個 Merkle 節點 Hash值,這也是 Merkle Tree的一部份,決定了每一個地址都不能夠重複交易或被偽造。
每筆記錄的數據結構如下:
以上就是比特幣區塊鏈中區塊(Block)的結構,那剛才一直說的 Merkle Tree 又是怎麼一回事呢?
Merkle Tree
Merkle Tree 是一種用來表示 Hash 值的數據結構。它的基本結構就是 Binary Tree(二元樹),每一個非葉子節點(Node),都被標示一個 Hash 值。由於 Merkle Tree 的發明人是 Ralph Merkle,當然這就是這個資料結構的名稱由來。
他是會把每一筆交易的TxID透過SHA256做加密
HA = SHA256(SHA256(TxA))
HB = SHA256(SHA256(TxB))
HC = SHA256(SHA256(TxC))
HD = SHA256(SHA256(TxD))
如此類推,然後兩兩連接(Concat)在一起,再進行加密:
HAB = SHA256(SHA256(HA+HB))
HCD = SHA256(SHA256(HC+HD))
直至出現 Merkle Tree Root為止:
HABCD = SHA256(SHA256(HAB+HCD))
這樣就得出與上圖一樣的 Merkle Tree。
而這裡 Merkle Tree Root 也就是上面提到的頭塊頭中的 Merkle Tree Root 部份,而下面的部份就是所有的交易記錄。
創世區塊 Genesis Block
創世區塊 Genesis Block 這個名字聽起來很像很了不起的樣子,實際上就是區塊鏈的第一個區塊,結構上與鏈中其他區塊都沒差別。
那麼區塊鏈中的創世區塊 、區塊 、Mrekle Tree的關係是怎樣的?
在創建區塊鏈時,首先要建立創世區塊 Genesis Block,此時,Genesis Block 就會有屬於它的Hash值,然後使用演算法運算,得出第一個區塊 Block #1,那麼,Block #1也會有屬於它的Hash值,還記得區塊頭結構中有個叫"前一個區塊的記錄"(Hash Of Previous Block Header)嗎?沒錯,Block #1 就會把 Genesis Block的值放進這個位置,這樣,就相當於連結到前一個Block,即創世區塊 Genesis Block ,如此類推,不斷產生的區塊都使用這種方式連接起來,這樣,就形式大家耳熟能詳的區塊鏈 Blockchain了。
區塊到底能做什麼呢?每一個區塊,都能用來「記帳」,整個區塊鏈 Blockchain 串接起來就是一本完整的帳冊,所以說,區塊鏈 Blockchain 也叫做 Distributed Ledger(分散式帳本)。
慢著,上面一直在說的 Hash值又是什麼啊?
Hash
Hash 詳細解釋可查閱維基百科 雜湊函數
Hash值比較
在工作量證明 PoW時,到底是怎樣比較 Hash 值的大小?其實就是將 Hash值先轉換為 big integer再比較。
Hash值對區塊的影響
- 每個區塊的 Hash 都是不一樣的,可以通過 Hash 標識區塊;
- 如果區塊的內容變了,它的 Hash 一定會改變;
Hash的不可修改性
由於區塊與 Hash 是一一對應的,每個區塊的 Hash 都是針對"區塊頭"(Head)計算的。
上面提到,區塊頭包含很多內容,其中有當前區塊體的 Hash(注意是"區塊體"的 Hash,而不是整個區塊),還有上一個區塊的 Hash。這也意味著,如果當前區塊的內容變了,或者上一個區塊的 Hash 變了,一定會引起當前區塊的 Hash 改變。
這一點對區塊鏈有重大意義。如果有人修改了一個區塊,該區塊的 Hash 就變了。為了讓後面的區塊還能連到它,該人必須同時修改後面所有的區塊,否則被改掉的區塊就脫離區塊鏈了。由於Hash 的計算非常耗時,同時修改多個區塊幾乎不可能發生,除非有人掌握了全網 51% 以上的計算能力。
正是通過這種聯動機制,區塊鏈保證了自身的可靠性,數據一旦寫入,就無法被篡改。這就像歷史一樣,發生了就是發生了,從此再無法改變。
看到這裡,如果還不清楚,可以從這裡倒著向上看一次,應該就會很清楚區塊到底實際上是怎麼一回事了。
區塊是區塊鏈中的基本組成部份,每個區塊鏈的數據結構、每個在結構內包含的元素(前一個區塊的 Hash值、加密運算方式、時間戳、簽名等等)都與整個區塊、甚至整個區塊鏈息息相關,正因為這種巧妙設計,令到區塊鏈可靠性、不可逆、無法篡改的特性更為突出。而深入地了解區塊中各項的組成部份及相互之間的關係,將對接下來學習建立屬於自己的區塊鏈及應用,打下良好的基礎。
參考文章出處:
Jollen's Blog - Blockchain Developer - 認識 Genesis Block