區塊鏈研究實驗室|實現Merkle-Tree和Patricia-Trie教程詳解

本文介紹了Node.js中Merkle Tree和Patricia Trie的實現,還介紹了這兩種數據結構的一些理論方面。

介   紹

Merkle和Patricia是以太坊區塊鏈中使用的兩種最受歡迎的數據結構,其背後的Bloom Filters非常接近。在本文中,我將介紹以下內容:

1. 關於Merkle和Patricia嘗試

2. 算法

3. 在Node.js中實現

默克爾樹Merkle Tree

默克爾樹Merkle Tree不是計算機科學中的新概念,它已經存在了數十年,起源於密碼學領域。

簡而言之,默克爾樹Merkle Tree本質上是一種樹數據結構,其中數據存儲在葉節點中,非葉節點存儲數據散列,每個非葉節點是其下兩個節點的組合哈希值。

從數學上講,它可以表示爲

例如:給定一個字母表列表,從中創建一個默克爾樹merkel tree。默克爾樹merkel tree的最底層將包含所有字母作爲葉節點。

上面的層包含其哈希值。

第二層之後的層中的節點包含子節點的哈希值。通常我們從第二層獲取兩個節點,並將它們合併以形成另一個節點。我們也可以採用兩個以上的節點,但是二叉默克爾樹merkel tree是所有節點中最簡單的,增加節點的程度只會增加計算和算法的複雜性。

如果節點數爲偶數,則取兩個連續的節點並形成父層。但是如果節點數爲奇數,我們將使用兩個連續的節點,直到剩下一個以形成父層爲止,然後通過將哈希值複製到父層來重複剩餘的節點。

第3層具有第2層的2個連續節點的值的哈希值,如果我們在一層中有奇數個節點,則最後一個節點將被重複

類似地,使用第三層的值形成第四層。

第四層由第2層的2個連續節點的值的散列形成

默克爾樹merkel tree的最後一層或根由保留在最頂層的最後兩個節點的哈希值組成。在任何情況下,奇數或偶數葉節點,我們始終在最頂層具有兩個節點。

數據驗證

默克爾樹merkel tree的重要性在於其高效驗證數據的能力。在給定列表中的任何數據,我們可以在O(h)時間複雜度中驗證此數據是否有效。而且我們不需要整個列表進行驗證。

默克爾樹merkel tree的一種更簡單形式表現是哈希鏈或只是一個區塊鏈,其中每個節點都具有前一個節點值的哈希值。如果我們篡改中間的任何節點,則可以在O(n)時間內確定該節點是否被篡改。哈希鏈中的驗證可以通過計算所有節點的哈希值(從所討論的節點開始直至結束)來執行。在需要驗證多個節點的情況下,我們從所有可疑節點中的第一個節點開始,然後計算最後一個節點的哈希。現在我們有了最後一個節點的哈希,可以比較並檢查此哈希是否匹配。哈希鏈看起來很簡單,但對於大型數據對象而言並不是一個有效的選擇。由於我們需要物理上存在的整個鏈來驗證數據,因此這也會使哈希鏈空間效率低下。

默克爾樹merkel tree的驗證情況並非如此。爲了說明驗證過程,請考慮下面的示例。

假設我從另一臺服務器收到了數據C。可以說這是C’。我們要驗證C’是否未被篡改。我們沒有列表中所有數據的默克爾樹merkel tree。

如果是哈希鏈,我們將需要整個數據列表來驗證C’是正確的。在默克爾樹merkel tree中,我們只需要哈希即可。下圖說明了如何在沒有其他可用數據對象的情況下驗證C'。

過對將我們引向根的所有節點進行散列來驗證C’

1. 在列表中找到C’的位置。可通過ID搜索。

2. 計算C’的哈希值

3. 通過將當前節點與其鄰居進行哈希運算來計算父節點的值(如果位置爲奇數,則爲下一個;如果位置爲偶數,則爲上一個),然後將父節點設置爲當前節點。

4. 重複步驟3,直到找到根

5. 比較當前根和先前的根(如果它們匹配,則C')

將新的根與現有的根進行比較。如果新的根匹配,則C’本質上是C,就沒被篡改。

爲了驗證哈希鏈中的數據,我們需要O(n)時間,因爲在最壞的情況下我們將計算n個哈希,就像在默克爾樹的情況下一樣,由於我們僅計算logn哈希,因此可以在O(logn)時間內驗證相同的數據。

默克爾樹merkel tree算法

本節以數學形式描述了用於在默克爾樹merkel tree中創建和驗證的算法。

創建

如前所述,默克爾樹merkel tree是通過從每一層獲取兩個節點並對其進行哈希處理以創建父節點來創建的。通過以矩陣形式表示樹,我們可以在數學上將其寫爲:

 

這使得樹的根在tree [0] [0]可用

數據驗證

數據驗證是一種自下而上的方法,其中我們從數據開始,找到其哈希值並計算父級,然後繼續進行直到找到根。在數學上,我們可以表示爲:

 Patricia Tries

Patricia Tries是n元樹,與默克爾樹不同,它用於存儲數據而不是進行驗證。

簡而言之,Patricia Tries是一種樹型數據結構,其中所有數據都存儲在葉節點中,其中每個非葉節點都是標識數據的唯一字符串的字符。使用唯一的字符串,我們瀏覽字符節點並最終到達數據。

Patricia Trie就像一個哈希表,但有一些細微的差異。

讓我們看一個例子。請考慮以下單詞:

Cat, Cats, Car, Dog, Dogs, Doggo, Ant

patricia trie存放這些物品看起來像這樣:

值爲END的節點表示到現在爲止遍歷的路徑實際上是一個單詞。那些沒有END子節點的節點表示該單詞不存在。

例如在上圖中,由於END節點位於“ T”之後,所以單詞ANT出現在trie中。類似地,對於CATS,END節點位於S之後,這使得它在trie中成爲一個單詞。有趣的是,如果像CAT那樣在END節點之前放置兩個節點,那麼我們將在同一路徑中存儲兩個單詞,但是可以通過不遍歷底部並檢查END之間是否存在END來訪問CAT。

DOG,DOGS和DOGGO也是這樣。對於DOG,我們將只有一個返回值,因爲它具有END節點。但是如果我們使用DOG作爲前綴搜索貴族,則會得到三個返回值。基本上,這裏使用深度優先搜索。

以太坊使用Patricia嘗試將交易存儲在區塊,交易收據中並維護網絡狀態。

數據存儲

爲了存儲數據對象,我們不需要像單詞一樣的前綴。由於我們的數據對象是事務或區塊,並且我們將用於在特里中存儲數據的所有“唯一字符串”將是事務散列或塊散列,它們的長度始終相同,因此我們不必擔心前綴。

如果我們爲事務創建Patricia trie,則它看起來應如下所示,儘管要大得多:

每個交易哈希將具有數字或字符字符(取決於算法)。對於sha256,我們將使用32個字符長的哈希。如果我們假設哈希僅由0–9和A_Z組成,則patricia trie中的每個節點將具有35個子節點。從根開始,我們向下遍歷,同時將每個字符與節點值匹配,直到最後獲得交易數據對象。

算    法

我們可以說trie中的每個節點本身就是一個哈希表,該哈希表將字符作爲鍵進行哈希,將另一個哈希表作爲值進行哈希。所有操作,插入,刪除和訪問都取O(h),其中h是本例中哈希的長度或樹的深度。

通過使用此定義,我們可以編寫以下算法在trie中存儲數據:

在此算法中,我們創建一個空的鍵值對對象,遍歷哈希的整個長度,併爲每個字符設置該值作爲新的empyt鍵值對對象。同樣對於每個字符,我們將curr映射設置爲下一個映射。最後當我們創建了整個分支時,我們在最後一個節點密鑰的標籤“ DATA”處設置數據。

在訪問時,我們返回鍵“ DATA”的最後一個映射的值,在刪除時,我們只刪除給定哈希的葉節點。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章