Patricia trie是一種特殊的基數樹,又稱二叉基數樹。顧名思義,在二叉基數樹中,每個頂點最多有兩條邊。這意味著對於任意給定的頂點,最多隻有兩條路徑。具有相同字元的值儲存在共同字首的文件中。
上圖的例子說明了基數樹的效率。每條邊不再只儲存單一的字元(這將存在很多隻有一個子節點的頂點),而是用部分字串進行標記。
透過共享字首對儲存資料進行組織,最佳化了資料結構的儲存空間,提高了平均的查詢速度。這對於區塊鏈節點而言非常重要,因為節點需要儲存並計算大量的資料。
Merkle樹
Merkle樹是一種以多個資料塊開始的資料結構。對塊中的值進行雜湊處理則可得到樹中的第一行頂點。Merkle樹的每個後續頂點仍用雜湊表示,頂點的雜湊值可透過將父頂點的雜湊值相加並對相加的結果進行雜湊計算所得。
這些雜湊最終可計算得到一個公共的頂點,稱為Merkle根或者根雜湊。Merkle根節點可以被認為是樹中資料唯一且加密的指紋。儲存值的任意改變都將使得所連線的節點的雜湊值發生變化,從而產生不同的指紋。
Neo網路上的所有節點都會計算一個本地的狀態,並在每個新塊後確定一個state root。透過將該state root與由共識節點簽名的state root進行比較,節點即可驗證狀態與網路其他部分的一致性。
Merkle證明是這些樹的一個有趣特性,它提供了一種可用於驗證特定鍵值在樹中存在性的機制。當輕客戶端從RPC節點請求資料時,資料將附帶可說明特定值(如使用者的資產餘額)在樹中存在的Merkle證明。
這意味著輕客戶端可以以一種去信任的方式驗證來自RPC節點的資訊,其中只需要Merkle證明以及從P2P網路接收到的共識節點的最新狀態確認。
簡單支付驗證
以上面的Merkle證明圖為例。假設一個輕錢包使用者想要傳送一筆交易,但是在此之前需要驗證RPC節點是否提供了準確的資產餘額資訊。該餘額資訊儲存在資料塊c中。
由於輕錢包不會儲存區塊鏈資料,因此它會請求RPC節點提供Merkle證明。RPC節點會提供c中的餘額值以及“路徑證明”,即從c向上移動到state root所需的雜湊列表。在這種情況下,RPC節點將提供c中的餘額值以及hash(d) 與h(h(a) + h(b)))的值。
有了這些值,輕錢包就可以開始驗證了。首先,對c的餘額值進行雜湊處理得到h(c)。該雜湊值與hash(d)相加後,再次對結果進行雜湊處理從而獲得h(h(c) + h(d)))的值。
重複此過程,將計算所得的h(h(c) + h(d)))與RPC節點提供的h(h(a) + h(b)))相加,最後再進行一次雜湊計算得到Merkle根。此時就可以開始進行驗證了。
如果RPC節點提供的c塊中的資產餘額以及路徑證明是正確的,則此過程將獲得與共識節點在P2P網路上簽名和廣播的相同的Merkle根。如果餘額或者路徑證明不正確將產生一個不同的state root,即可證明RPC節點提供了與共識節點不一致的錯誤資訊。
輕錢包現在就可以在不儲存區塊鏈副本的情況下驗證餘額資料,確保RPC伺服器提供的資訊與共識節點一致。