在比特幣網(wǎng)絡(luò)中,不是每個(gè)節(jié)點(diǎn)都有能力儲(chǔ)存完整的區(qū)塊鏈數(shù)據(jù),受限于存儲(chǔ)空間的的限制,很多節(jié)點(diǎn)是以SPV(Simplified Payment Verification簡(jiǎn)單支付驗(yàn)證)錢(qián)包接入比特幣網(wǎng)絡(luò),通過(guò)簡(jiǎn)單支付驗(yàn)證可以在不必存儲(chǔ)完整區(qū)塊鏈下對(duì)交易進(jìn)行驗(yàn)證,本文將分析區(qū)塊結(jié)構(gòu)Merkle樹(shù)及如何進(jìn)行交易驗(yàn)證。
區(qū)塊結(jié)構(gòu)
在工作量證明中出現(xiàn)過(guò)一個(gè)區(qū)塊信息截圖:
細(xì)心的同學(xué)一定已經(jīng)在里面發(fā)現(xiàn)了很多未講的其他信息,如:時(shí)間戳,版本號(hào),交易次數(shù),二進(jìn)制哈希樹(shù)根(Merkle根)等。
我們來(lái)看看一個(gè)區(qū)塊結(jié)構(gòu)到底是怎樣的:
如上圖(下文稱(chēng):區(qū)塊結(jié)構(gòu)圖)所示:每個(gè)數(shù)據(jù)區(qū)塊包含區(qū)塊頭和區(qū)塊體。
區(qū)塊頭封裝了當(dāng)前版本號(hào)、前一區(qū)塊哈希值、當(dāng)前區(qū)塊PoW要求的隨機(jī)數(shù)(Nonce)、時(shí)間戳、以及Merkle根信息。
區(qū)塊體則包括當(dāng)前區(qū)塊經(jīng)過(guò)驗(yàn)證的、 區(qū)塊創(chuàng)建過(guò)程中生成的所有交易記錄。這些記錄通過(guò) Merkle樹(shù)的哈希過(guò)程生成唯一的Merkle根并記入?yún)^(qū)塊頭.
區(qū)塊哈希值實(shí)際上并不包含在區(qū)塊的數(shù)據(jù)結(jié)構(gòu)里,其實(shí)區(qū)塊打包時(shí)只有區(qū)塊頭被用于計(jì)算哈希(從網(wǎng)絡(luò)被接收時(shí)由每個(gè)節(jié)點(diǎn)計(jì)算出來(lái)),常說(shuō)的區(qū)塊哈希值實(shí)際是區(qū)塊頭哈希值,它可以用來(lái)唯一、明確地標(biāo)識(shí)一個(gè)區(qū)塊。
區(qū)塊頭是80字節(jié),而平均每個(gè)交易至少是250字節(jié),而且平均每個(gè)區(qū)塊包含2000個(gè)交易。因此,包含完整交易的區(qū)塊比區(qū)塊頭的4千倍還要大。
SPV節(jié)點(diǎn)只下載區(qū)塊頭,不下載包含在每個(gè)區(qū)塊中的交易信息。這樣的不含交易信息的區(qū)塊鏈,大小只有完整區(qū)塊鏈的幾千分之1,那SPV節(jié)點(diǎn)是如何驗(yàn)證交易的呢?
哈希驗(yàn)證
上面先留一個(gè)引子,先來(lái)回顧下哈希函數(shù),記賬原理我們知道原始信息任何微小的變化都會(huì)哈希完全不同的哈希值。
簡(jiǎn)單文件驗(yàn)證
我們通常用哈希來(lái)檢驗(yàn)下載的文件是否完整,我經(jīng)??吹竭@樣的下載頁(yè)面:
可以看到下載鏈接后面提供了一個(gè)MD5(MD5也是一種Hash算法),這樣我們可以在下載之后對(duì)文件計(jì)算MD5,如果MD5與提供的MD5相等,說(shuō)明文件有沒(méi)有被損壞,這個(gè)驗(yàn)證過(guò)程相信大家都能理解。
多點(diǎn)文件驗(yàn)證(哈希列表)
現(xiàn)在復(fù)雜度提高一點(diǎn),在P2P網(wǎng)絡(luò)中下載時(shí),會(huì)把大文件切成小文件,同時(shí)從多個(gè)機(jī)器上下載數(shù)據(jù),這個(gè)時(shí)候怎么驗(yàn)證數(shù)據(jù)呢?
以BT下載為例,在下載真正的數(shù)據(jù)之前,我們會(huì)先下載一個(gè)哈希列表的(每個(gè)下小塊計(jì)算出一個(gè)哈希),如果有一個(gè)小塊數(shù)據(jù)在傳輸過(guò)程中損壞了,那我只要重新下載這一個(gè)數(shù)據(jù)塊就行了,這時(shí)有一個(gè)問(wèn)題就出現(xiàn)了,那么多的哈希,怎么保證它們本身(哈希列表中的哈希值)都是正確地呢?
答案是把每個(gè)小塊數(shù)據(jù)的哈希值拼到一起,然后對(duì)這個(gè)長(zhǎng)字符串在作一次哈希運(yùn)算,得到哈希列表的根哈希。只要根哈希校對(duì)比一樣就說(shuō)明驗(yàn)哈希列表是正確的,再通過(guò)哈希列表校驗(yàn)小數(shù)據(jù)塊,如果所有的小數(shù)據(jù)塊驗(yàn)證通過(guò)則說(shuō)明大文件沒(méi)有被損壞。
Merkle樹(shù)
驗(yàn)證交易的過(guò)程和文件驗(yàn)證很相似,可以人為每個(gè)交易是一個(gè)小數(shù)據(jù)塊,但比特幣使用Merkle樹(shù)的方式進(jìn)行驗(yàn)證,相對(duì)于哈希列表,Merkle樹(shù)是一種哈希二叉樹(shù),它的明顯的一個(gè)好處是可以單獨(dú)拿出一個(gè)分支來(lái)(作為一個(gè)小樹(shù))對(duì)部分?jǐn)?shù)據(jù)進(jìn)行校驗(yàn),更加高效。
我們回看下上面的區(qū)塊結(jié)構(gòu)圖,區(qū)塊體就包含這樣一個(gè)Merkle樹(shù),Merkle樹(shù)被用來(lái)歸納一個(gè)區(qū)塊中的所有交易。
每個(gè)葉子節(jié)點(diǎn)是每個(gè)交易信息的哈希,往上對(duì)相鄰的兩個(gè)哈希合并成字符串再哈希,繼續(xù)類(lèi)似的操作直到只剩下頂部的一個(gè)節(jié)點(diǎn),即Merkle根,存入?yún)^(qū)塊頭。
因?yàn)镸erkle樹(shù)是二叉樹(shù),所以它需要偶數(shù)個(gè)葉子節(jié)點(diǎn)。如果僅有奇數(shù)個(gè)交易需要?dú)w納,那最后的交易就會(huì)被復(fù)制一份以構(gòu)成偶數(shù)個(gè)葉子節(jié)點(diǎn),這種偶數(shù)個(gè)葉子節(jié)點(diǎn)的樹(shù)也被稱(chēng)為平衡樹(shù)。
簡(jiǎn)化支付驗(yàn)證
SPV節(jié)點(diǎn)不保存所有交易也不會(huì)下載整個(gè)區(qū)塊,僅僅保存區(qū)塊頭,我們來(lái)看看它是如何對(duì)交易數(shù)據(jù)進(jìn)行驗(yàn)證的。
假如要驗(yàn)證區(qū)塊結(jié)構(gòu)圖中交易6,SPV節(jié)點(diǎn)會(huì)通過(guò)向相鄰節(jié)點(diǎn)索要(通過(guò)Merkleblock消息)包括從交易6哈希值沿Merkle樹(shù)上溯至區(qū)塊頭根哈希處的哈希序列 (即哈希節(jié)點(diǎn)6, 5, 56, 78, 5678, 1234 1~8 - 稱(chēng)為認(rèn)證路徑) 來(lái)確認(rèn)交易的存在性和正確性。(在N個(gè)交易組成的區(qū)塊中確認(rèn)任一交易只需要計(jì)算log2(N)個(gè)字節(jié)的哈希值,非??焖俑咝?
大家明白了嗎?
新聞熱點(diǎn)
疑難解答
圖片精選