Merkle 樹

默克爾樹(又叫哈希樹)是一種二叉樹,由一個根節點、一組中間節點和一組葉節點組成。最下面的葉節點包含存儲數據或其哈希值,每個中間節點是它的兩個孩子節點內容的哈希值,根節點也是由它的兩個子節點內容的哈希值組成。
進一步的,默克爾樹可以推廣到多叉樹的情形。
默克爾樹的特點是,底層數據的任何變動,都會傳遞到其父親節點,一直到樹根。
默克爾樹的典型應用場景包括:
- 快速比較大量數據:當兩個默克爾樹根相同時,則意味着所代表的數據必然相同。
- 快速定位修改:例如上例中,如果 D1 中數據被修改,會影響到 N1,N4 和 Root。因此,沿着 Root --> N4 --> N1,可以快速定位到發生改變的 D1;
- 零知識證明:例如如何證明某個數據(D0……D3)中包括給定內容 D0,很簡單,構造一個默克爾樹,公布 N0,N1,N4,Root,D0 擁有者可以很容易檢測 D0 存在,但不知道其它內容。
摘自:https://yeasy.gitbooks.io/blockchain_guide/content/crypto/merkle_trie.html
假如是 15,16.......30是一個個數據塊的hash值,我把這些數據從A傳輸到B,數據傳輸到B后,我想驗證下傳輸到B上的數據的有效性型(驗證數據是否在傳輸過程中發生變化),只需要驗證A 和 B上所構造的Merkle
Tree 的root節點值是否一致即可,如果一致,表示數據是有效的,傳輸過程中沒有發生改變。假如在傳輸過程中,15對應的數據被人篡改,通過Merkle Tree很容易定位找到(因為此時,節點0,1,3,7,15對應的hash值都發生了變化),定位的時間復雜度為O(log(n))
Merkle Tree的優點
相對於 Hash List,Merkle Tree 的明顯的一個好處是可以單獨拿出一個分支來(作為一個小樹)對部分數據進行校驗,這個很多使用場合就帶來了哈希列表所不能比擬的方便和高效。
Merkle Hash Tree 簡介
上圖(來自Wikipedia[1])給出了一個二進制的哈希樹(二叉哈希樹, 較常用的tiger hash tree也是這個形式). 據稱哈希樹經常應用在一些分布式系統或者分布式存儲中的反熵機制(Anti-entropy),也有稱做去熵的.這些應用包括 Amazon的Dynamo 還有Apache的Cassandra數據庫, 通過去熵可以去做到各個不同節點的同步, 即保持各個節點的信息都是同步最新.
哈希樹的特點很鮮明: 葉子節點存儲的是數據文件,而非葉子節點存儲的是其子節點的哈希值(稱為MessageDigest) 這些非葉子節點的Hash被稱作路徑哈希值, 葉子節點的Hash值是真實數據的Hash值. 因為使用了樹形結構, MT的時間復雜度為 O(logn)
比如下圖中, 我們如果使用SHA1算法來做校驗值, 比如數據塊8對應的哈希值是H23
, 則按照這個路徑來看 應該有
其中 ∥
是表聯接的意思.
應用舉例
Amazon Dynamo中同步[4]
在Dynamo中,每個節點保存一個范圍內的key值,不同節點間存在有相互交迭的key值范圍。在去熵操作中,考慮的僅僅是某兩個節點間共有的 key值范圍。MT的葉子節點即是這個共有的key值范圍內每個key的hash,通過葉子節點的hash自底向上便可以構建出一顆MT。Dynamo首 先比對MT根處的hash,如果一致則表示兩者完全一致,否則將其子節點交換並繼續比較的過程, 知道定位到有差異的數據塊. 這種同步方式在分布式中有着節省網絡傳輸量的優點.
摘自:http://yishanhe.net/blog/merkle-hash-tree