- 區塊鏈+技術與實踐
- 王小峰等主編
- 2572字
- 2023-09-26 18:49:59
1.1.2 區塊和區塊鏈的由來
1. 區塊結構
比特幣網絡中,數據以文件的形式被永久記錄,稱之為區塊。一個區塊是一些或所有最新比特幣交易的記錄集,且未被其他先前的區塊記錄。區塊可以想象為一個城市記錄者的記錄本上的單獨一頁紙(對房地產產權的變更記錄)或者股票交易所的總賬本。在絕大多數情況下,新區塊被加到記錄最后,一旦寫上,就再也不能改變或刪除。每個區塊記錄了它被創建之前發生的所有事件。
每個區塊都包括一個被稱為“魔數”的常數0xD9B4BEF9、區塊的大小、區塊頭、區塊所包含的交易數量,以及一些或者所有近期的新交易。在每個區塊中,對整個區塊鏈起決定作用的是區塊頭,如表1-1所示。
表1-1 區塊頭示意圖

這里的hashPrevBlock的數值就是區塊連成區塊鏈的關鍵字段,該字段使得各個區塊之間可以連接起來,形成一個巨大的“鏈條”。每個區塊都必須指向前一個區塊,否則無法通過驗證。這個區塊鏈條一直追溯到源頭,也就是指向創世區塊。很顯然,創世區塊的hashPrevBlock的值為零或者為空。在區塊頭中,最關鍵的一個數據項是隨機數Nonce。這串數字是一個答案,而這個答案對于每個區塊是唯一的。
● 這個答案很難獲得。
● 有效答案有多個,不過只需要找到一個答案就可以了。
● 其他區塊對有效答案的驗證很容易。
正是因為問題很難解答,沒有固定的算法可以求出答案,所以唯一的做法就是不斷嘗試,找尋這個答案的做法就是“挖礦”,同時有很多人在“挖礦”,他們之間是相互競爭的關系。
區塊內包含許多交易,它們通過Merkle根節點間接被哈希,因為所有交易不可能直接被哈希,哈希包含一個交易的區塊所花的時間,和哈希包含1萬個交易的區塊所花的時間一樣。
目標哈希值的壓縮格式是一個特殊的浮點編碼類型,首字節是指數(僅使用了5個最低位),后3個字節是尾數,它能表示256位的數值。一個區塊頭的SHA256值必定要小于或等于目標哈希值,該區塊才能被網絡所接受,目標哈希值越低,產生一個新區塊的難度越大。
Merkle樹是哈希的二叉樹。在bitcoin中使用兩次SHA256算法來生成Merkle樹,如果葉子個數為奇數,則要重復計算最后一個葉子的兩次SHA256值,以達到偶數葉子節點的要求。計算過程:首先按照區塊中交易的兩次SHA256值,然后按照哈希值大小排序,生成最底層。第二層的每個元素是相連續的兩個哈希值的兩次哈希值,重復這個過程,直到某一層只有一個哈希值,這就是Merkle根。例如,想象有3個交易a、b、c,生成過程如下:
d1 = dhash(a) d2 = dhash(b) d3 = dhash(c) d4 = dhash(c) # 只有3個元素,是奇數,因而把最后一個元素重算一次 d5 = dhash(d1 concat d2) d6 = dhash(d3 concat d4) d7 = dhash(d5 concat d6)
這里的d7就是以上3個交易的Merkle根。需要注意的是,Merkle樹的哈希值是小頭位序(即高位在后,一種數字在計算機中的表示形式)。對于某些實現和計算,在哈希計算前應該先按位反轉,在哈希計算后再反轉一次。
2. 創世區塊
創世區塊是指區塊鏈的第一個區塊,現在的比特幣客戶端版本把該區塊號定為0,以前的版本把該區塊號定為1。以下是創世區塊的一種表示,它出現在以前的比特幣代碼的注釋中,第一個代碼段定義了創建該區塊所需的所有變量,第二個代碼段是標準的區塊類格式,包含第一個代碼段中縮短版本的數據。
GetHash()= 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab212 7b7afdeda33b txNew.vin[0].scriptSig = 4866047994 0x736B6E616220726F662074756F6C6961 6220646E6 F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2 F33302073656D695420656854 txNew.vout[0].nValue = 5000000000 txNew.vout[0].scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6 DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG block.nVersion = 1 block.nTime = 1231006505 block.nBits = 0x1d00ffff block.nNonce = 2083236893 CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot =4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65 732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66 207365636f6e64206261696c6f757420666f722062616e6b73) CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) vMerkleTree: 4a5e1e
3. 區塊鏈的原理
區塊鏈是所有比特幣節點共享的交易數據庫,這些節點基于比特幣協議參與到比特幣網絡中。區塊鏈包含每個曾在比特幣系統執行過的交易,根據這個信息,人們可以找到任何時候任一個地址中的幣的數量。
每個區塊包含前一個區塊的哈希值,這就使得從創世區塊到當前區塊形成了一條區塊鏈,每個區塊必定按時間順序跟隨在前一個區塊之后,區塊鏈結構如圖1-4所示。如果不知道前一個區塊的哈希值就沒法生成當前區塊,要改變一個已經在區塊鏈中存在一段時間的區塊,從計算上來說是不可行的。因為如果它被改變,它之后的每個區塊必須隨之改變。這些特性使得雙花比特幣非常困難,區塊鏈是比特幣的最大創新。
如果一個區塊是最長區塊鏈的最后一個區塊,誠實的礦工只會在這個區塊的基礎上生成后續區塊(創建新區塊時通過引用該區塊來實現)。“長度”是被計算成區塊鏈的所有聯合難度,而不是區塊數目,盡管這個區別僅僅在防御幾個潛在攻擊時有用。如果一個區塊鏈中的所有區塊和交易有效,則該區塊鏈有效,并且要以創世區塊開頭。
對于區塊鏈中的任何區塊來說,只有一條通向創世區塊的路徑。然而,從創世區塊出發,卻可能有分叉。當兩個區塊產生的時間僅相差幾秒時,可能會產生包含一個區塊的分叉。當出現以上現象時,礦工節點會根據收到區塊的時間,在先收到的區塊基礎上繼續挖礦。哪個區塊的后續區塊先出現,這個區塊就被包括進主鏈,因為這條塊鏈更長。在修正需要向后兼容的程序bug后,出現過更嚴重的分叉。

圖1-4 區塊鏈結構示意圖
短塊鏈(或有效塊鏈)中的區塊沒有作用,當比特幣客戶端轉向另一個長塊鏈時,短塊鏈中所有有效的交易將被重新加入交易隊列池中,將被包括在另一個塊中。短塊鏈中的區塊收益不會在長塊鏈中出現,因而這些收益實際上是丟失了,這就是比特幣網絡強化的100個區塊成熟時間的存在原因。
短塊鏈中的區塊經常被稱為“孤立”區塊,這是因為長塊鏈中的生產交易沒有父區塊,因而這些生產交易在交易列表的RPC調用中表現為孤立。幾個礦池誤解了這些信息并且把這些區塊叫作“孤兒”,事實上這些區塊都有父區塊,可能還有子區塊。
4. 區塊鏈的技術本質
如前所述,比特幣產品誕生后,人們基于比特幣的數據結構(鏈式區塊)創造了“區塊鏈”這個名詞。如今,區塊鏈特指一種綜合了分布式數據存儲、點對點傳輸、加密數據、共識計算等技術,具有去中心化、共識自治、不可篡改等特征的計算機網絡。在該網絡中,信息一旦經過驗證并被添加到區塊鏈網絡中,即實現了數據的分布式存儲和主權保障,數據不僅無法被私自篡改,還可實現數據的主權歸屬和追溯功能。
從宏觀上來看,區塊鏈技術可以構建一種新型網絡,網絡中的每個節點都能夠在去中心化的環境中實現自治的數據信任。簡單來說,區塊鏈是一種達成信任的工具。
通俗地講,區塊鏈通過算法實現了區塊鏈網絡中節點與節點之間的秩序,以及流轉與傳播在區塊鏈網絡中數據的歸屬,基于這種實現了樸素約定的網絡秩序和數據契約的設計,使得區塊鏈被認為是一種社會可編程技術框架,并可為社會的各個領域提供新的治理模式(跨域組織信任與協同),如圖1-5所示。

圖1-5 區塊鏈技術是一種面向人工社會編程的新技術與新的社會治理模式