摘要:是以太坊存儲(chǔ)數(shù)據(jù)的核心數(shù)據(jù)結(jié)構(gòu),它是由和結(jié)合的一種樹(shù)形結(jié)構(gòu),理解有助于我們更好的理解以太坊的數(shù)據(jù)存儲(chǔ)。所以就有了樹(shù)壓縮前綴樹(shù),后面會(huì)介紹到,也被稱為,中文名稱默克爾樹(shù),主要用于數(shù)據(jù)集較大時(shí)的文件校驗(yàn)。
??MPT(Merkle Patricia Tries)是以太坊存儲(chǔ)數(shù)據(jù)的核心數(shù)據(jù)結(jié)構(gòu),它是由Merkle Tree和Patricia Tree結(jié)合的一種樹(shù)形結(jié)構(gòu),理解MPT有助于我們更好的理解以太坊的數(shù)據(jù)存儲(chǔ)。在了解MPT數(shù)據(jù)結(jié)構(gòu)之前,我們需要先來(lái)看看基本的Tree結(jié)構(gòu)和Merkle Tree、Patricia Tree。
Trie字典樹(shù)??Trie樹(shù),又稱前綴樹(shù)或字典樹(shù),是一種有序樹(shù),用于保存關(guān)聯(lián)數(shù)組,其中的鍵通常是字符串。一個(gè)節(jié)點(diǎn)的所有子孫都有相同的前綴,也就是這個(gè)節(jié)點(diǎn)對(duì)應(yīng)的字符串,而根節(jié)點(diǎn)對(duì)應(yīng)空字符串。
上圖是一棵Trie樹(shù),表示了字符串集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} ,從上圖中我們可以看出Trie樹(shù)的特點(diǎn):
根節(jié)點(diǎn)不包含字符,除根節(jié)點(diǎn)外的每一個(gè)子節(jié)點(diǎn)都包含一個(gè)字符。
從根節(jié)點(diǎn)到某一個(gè)節(jié)點(diǎn),路徑上經(jīng)過(guò)的字符連接起來(lái),為該節(jié)點(diǎn)對(duì)應(yīng)的字符串。
每個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn)包含的字符互不相同。
但是從上面的結(jié)構(gòu)也可以看出一個(gè)問(wèn)題:高度不可控,如下圖所示。所以就有了Patricia樹(shù)(壓縮前綴樹(shù)),后面會(huì)介紹到
Merkle Tree,也被稱為Hash Tree,中文名稱:默克爾樹(shù),主要用于數(shù)據(jù)集較大時(shí)的文件校驗(yàn)。其主要特點(diǎn)為:
葉節(jié)點(diǎn)存儲(chǔ)著數(shù)據(jù)塊的Hash(如:文件塊、一段數(shù)據(jù)集)
非葉子節(jié)點(diǎn)(包括中間節(jié)點(diǎn)和根節(jié)點(diǎn))存儲(chǔ)著對(duì)應(yīng)子節(jié)點(diǎn)Hash值串聯(lián)字符串之后的Hash值。
解釋:
1、在最底層,和哈希列表一樣,我們把數(shù)據(jù)分成小的數(shù)據(jù)塊,有相應(yīng)地哈希和它對(duì)應(yīng);
2、往上走,并不是直接去運(yùn)算根哈希,而是把相鄰的兩個(gè)哈希合并成一個(gè)字符串,然后運(yùn)算這個(gè)字符串的哈希,這樣每?jī)蓚€(gè)哈希就結(jié)婚生子,得到了一個(gè)”子哈?!?。如果最底層的哈希總數(shù)是單數(shù),那到最后必然出現(xiàn)一個(gè)單身哈希,這種情況就直接對(duì)它進(jìn)行哈希運(yùn)算,所以也能得到它的子哈希再往上推,依然是一樣的方式,可以得到數(shù)目更少的新一級(jí)哈希,
3、最終必然形成一棵倒掛的樹(shù),到了樹(shù)根的這個(gè)位置,這一代就剩下一個(gè)根哈希了,我們把它叫做 Merkle Root。
??對(duì)于這種數(shù)據(jù)結(jié)構(gòu),在實(shí)際應(yīng)用中會(huì)有哪些應(yīng)用場(chǎng)景了,舉個(gè)例子,我們知道現(xiàn)在從網(wǎng)上下載文件,很多都是P2P下載,文件會(huì)切分成很多小的數(shù)據(jù)塊,每個(gè)數(shù)據(jù)塊從不同的來(lái)源上下載,這些機(jī)器可以認(rèn)為是不穩(wěn)定或不可信的,文件下載完之后我們需要校驗(yàn)文件的完整性,這時(shí)我們總不能把文件再次切分然后分別計(jì)算它的Hash和下載前的Hash做對(duì)比吧,這時(shí)就需要用到Merkle Tree。
??在下載前,先從可靠的源獲得文件的Merkle Tree樹(shù)根,下載后,在合并文件之前先對(duì)比小文件的Hash是否一樣,如果一樣就認(rèn)為是可靠的,如果不一樣,就判定文件被損壞,從新的來(lái)源重新下載,文件合并之后,計(jì)算小數(shù)據(jù)塊的Hash并最終計(jì)算根Hash,也成為Merkle Root,然后對(duì)比根Hash是否一致。這樣就避免了對(duì)整個(gè)文件進(jìn)行Hash計(jì)算,因?yàn)楫?dāng)文件太大時(shí),這種計(jì)算是很耗時(shí)。
??Patricia樹(shù),或稱Patricia trie,或crit bit tree,壓縮前綴樹(shù),是一種更節(jié)省空間的Trie。對(duì)于基數(shù)樹(shù)的每個(gè)節(jié)點(diǎn),如果該節(jié)點(diǎn)是唯一的兒子的話,就和父節(jié)點(diǎn)合并。
??上面我們介紹了Merkle Tree和Patricia Tree,而MPT(Merkle Patricia Tree),顧名思義就是這兩者的結(jié)合。MTP樹(shù)種的節(jié)點(diǎn)包含空節(jié)點(diǎn)、葉子節(jié)點(diǎn)、擴(kuò)展節(jié)點(diǎn)和分支節(jié)點(diǎn)。
Nibble:它是key的基本單元,是一個(gè)四元組(四個(gè)bit位的組合例如二進(jìn)制表達(dá)的0010就是一個(gè)四元組)
空節(jié)點(diǎn)**:簡(jiǎn)單的表示空,在代碼中是一個(gè)空串。
葉子節(jié)點(diǎn)(leaf):只有兩個(gè)元素,分別為key和value,表示為[key,value]的一個(gè)鍵值對(duì),其中key是key的一種特殊十六進(jìn)制編碼,value是value的RLP編碼。
擴(kuò)展節(jié)點(diǎn)(extension):也是[key,value]的一個(gè)鍵值對(duì),但是這里的value是其他節(jié)點(diǎn)的hash值,這個(gè)hash可以被用來(lái)查詢數(shù)據(jù)庫(kù)中的節(jié)點(diǎn)。也就是說(shuō)通過(guò)hash鏈接到其他節(jié)點(diǎn)。
分支節(jié)點(diǎn)(branch):分支節(jié)點(diǎn)有17個(gè)元素,回到Nibble,四元組是key的基本單元,四元組最多有16個(gè)值。所以前16個(gè)必將落入到在其遍歷中的鍵的十六個(gè)可能的半字節(jié)值中的每一個(gè)。第17個(gè)是存儲(chǔ)那些在當(dāng)前結(jié)點(diǎn)結(jié)束了的節(jié)點(diǎn)(例如, 有三個(gè)key,分別是 (abc ,abd, ab) 第17個(gè)字段儲(chǔ)存了ab節(jié)點(diǎn)的值)
這里還有一些知識(shí)點(diǎn)需要了解的,為了將MPT樹(shù)存儲(chǔ)到數(shù)據(jù)庫(kù)中,同時(shí)還可以把MPT樹(shù)從數(shù)據(jù)庫(kù)中恢復(fù)出來(lái),對(duì)于Extension和Leaf的節(jié)點(diǎn)類型做了特殊的定義:如果是一個(gè)擴(kuò)展節(jié)點(diǎn),那么前綴為0,這個(gè)0加在key前面。如果是一個(gè)葉子節(jié)點(diǎn),那么前綴就是1。同時(shí)對(duì)key的長(zhǎng)度就奇偶類型也做了設(shè)定,如果是奇數(shù)長(zhǎng)度則標(biāo)示1,如果是偶數(shù)長(zhǎng)度則標(biāo)示0。
以太坊的每一個(gè)區(qū)塊頭,并非只包含一棵MPT樹(shù),而是包含了三棵MPT樹(shù),分別對(duì)應(yīng)了四種對(duì)象:
State Trie 區(qū)塊頭中的狀態(tài)樹(shù)
key => sha3(以太坊賬戶地址address)
value => rlp(賬號(hào)內(nèi)容信息account)
Transactions Trie 區(qū)塊頭中的交易樹(shù)
key => rlp(交易的偏移量 transaction index)
每個(gè)塊都有各自的交易樹(shù),且不可更改
Receipts Trie 區(qū)塊頭中的收據(jù)樹(shù)
key = rlp(交易的偏移量 transaction index)
每個(gè)塊都有各自的交易樹(shù),且不可更改
Storage Trie 存儲(chǔ)樹(shù)
存儲(chǔ)只能合約狀態(tài)
每個(gè)賬號(hào)有自己的Storage Trie
MPT樹(shù)種還有一個(gè)重要的概念:特殊的十六進(jìn)制前綴(hex-prefix, HP)編碼來(lái)對(duì)key編碼,我們先來(lái)了解一下編碼定義規(guī)則:
RAW 原始編碼,對(duì)輸入不做任何變更
HEX 十六進(jìn)制編碼
RAW編碼輸入的每個(gè)字符分解為高4位和低4位。比如key=>"bob",b的ASCII十六進(jìn)制編碼為0x62,o的ASCII十六進(jìn)制編碼為0x6f,分解成高四位和第四位,16表示終結(jié) 0x10,最終編碼結(jié)果為[6 2 6 15 6 2 16],
如果是葉子節(jié)點(diǎn),則在最后加上Hex值0x10表示結(jié)束
如果是分支節(jié)點(diǎn)不附加任何Hex值
HEX-Prefix 十六進(jìn)制前綴編碼
輸入key結(jié)尾為0x10,則去掉這個(gè)終止符
key之前補(bǔ)一個(gè)四元組這個(gè)Byte第0位區(qū)分奇偶信息,第1位區(qū)分節(jié)點(diǎn)類型
如果輸入key的長(zhǎng)度是偶數(shù),則再添加一個(gè)四元組0x0在flag四元組后
將原來(lái)的key內(nèi)容壓縮,將分離的兩個(gè)byte以高四位低四位進(jìn)行合并
十六進(jìn)制前綴編碼相當(dāng)于一個(gè)逆向的過(guò)程,比如輸入的是[6 2 6 15 6 2 16],根據(jù)第一個(gè)規(guī)則去掉終止符16。根據(jù)第二個(gè)規(guī)則key前補(bǔ)一個(gè)四元組,從右往左第一位為1表示葉子節(jié)點(diǎn),從右往左第0位如果后面key的長(zhǎng)度為偶數(shù)設(shè)置為0,奇數(shù)長(zhǎng)度設(shè)置為1,那么四元組0010就是2。根據(jù)第三個(gè)規(guī)則,添加一個(gè)全0的補(bǔ)在后面,那么就是20.根據(jù)第三個(gè)規(guī)則內(nèi)容壓縮合并,那么結(jié)果就是[0x20 0x62 0x6f 0x62]
官方有一個(gè)詳細(xì)的結(jié)構(gòu)的示例:
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/24478.html
摘要:是以太坊中存儲(chǔ)區(qū)塊數(shù)據(jù)的核心數(shù)據(jù)結(jié)構(gòu),它和融合一個(gè)樹(shù)形結(jié)構(gòu),理解結(jié)構(gòu)對(duì)之后學(xué)習(xí)以太坊區(qū)塊以及智能合約狀態(tài)存儲(chǔ)結(jié)構(gòu)的模塊源碼很有幫助。 MPT(Merkle Patricia Tries)是以太坊中存儲(chǔ)區(qū)塊數(shù)據(jù)的核心數(shù)據(jù)結(jié)構(gòu),它Merkle Tree和Patricia Tree融合一個(gè)樹(shù)形結(jié)構(gòu),理解MPT結(jié)構(gòu)對(duì)之后學(xué)習(xí)以太坊區(qū)塊header以及智能合約狀態(tài)存儲(chǔ)結(jié)構(gòu)的模塊源碼很有幫助。 首...
摘要:前言以太坊是一個(gè)巨大的狀態(tài)機(jī),在網(wǎng)絡(luò)中,每一個(gè)全節(jié)點(diǎn)都保存著以太坊狀態(tài)機(jī)的全部歷史,只要愿意,我們可以查詢到任何時(shí)刻的狀態(tài)黃皮書中,而賬戶狀態(tài)便是其中的狀態(tài),這部分功能由主要由代碼中的包提供基本概念賬戶地址在以太坊中,無(wú)論是外部賬戶還是合約 前言 以太坊是一個(gè)巨大的狀態(tài)機(jī),在網(wǎng)絡(luò)中,每一個(gè)全節(jié)點(diǎn)都保存著以太坊狀態(tài)機(jī)的全部歷史,只要愿意,我們可以查詢到任何時(shí)刻的狀態(tài)(黃皮書中World ...
摘要:加密經(jīng)濟(jì)網(wǎng)絡(luò)中的底層公鏈?zhǔn)潜缺忍貛鸥癖忍貛诺膬r(jià)值存儲(chǔ)平臺(tái)。這一點(diǎn)將會(huì)在經(jīng)濟(jì)模型設(shè)計(jì)中講到,敬請(qǐng)期待在技術(shù)實(shí)現(xiàn)上,我們也充分對(duì)比了比特幣模型和以太坊模型的優(yōu)劣,從中繼承了比特幣協(xié)議對(duì)狀態(tài)為核心的優(yōu)秀架構(gòu)。 Nervos 加密經(jīng)濟(jì)網(wǎng)絡(luò)中的底層公鏈 CKB 是比比特幣更像比特幣的價(jià)值存儲(chǔ)平臺(tái)。(這一點(diǎn)將會(huì)在經(jīng)濟(jì)模型設(shè)計(jì)中講到,敬請(qǐng)期待~)在技術(shù)實(shí)現(xiàn)上,我們也充分對(duì)比了比特幣 UTXO 模型...
摘要:以太坊發(fā)布加密貨幣網(wǎng)絡(luò)年月初文章在上宣布以太坊首次向比特幣社群宣布以太坊。銷售所得首先用于償還日益增加的法律債務(wù),回報(bào)開(kāi)發(fā)者們數(shù)月以來(lái)的努力,以及資助以太坊的持續(xù)開(kāi)發(fā)。以太坊安全審查開(kāi)始于年末,持續(xù)到年上半年。 以太坊歷史最近歷史記錄,請(qǐng)查看Taylor Gerring博客發(fā)帖。 誕生2013年末Vitalik Buterin第一次描述了以太坊,作為他研究比特幣社群的成果,不久后,Vi...
摘要:基于以太坊項(xiàng)目,以太坊團(tuán)隊(duì)目前運(yùn)營(yíng)了一個(gè)公開(kāi)的區(qū)塊鏈平臺(tái)以太坊網(wǎng)絡(luò)。主要特點(diǎn)以太坊區(qū)塊鏈底層也是一個(gè)類似比特幣網(wǎng)絡(luò)的網(wǎng)絡(luò)平臺(tái),智能合約運(yùn)行在網(wǎng)絡(luò)中的以太坊虛擬機(jī)里。以太坊采用交易作為執(zhí)行操作的最小單位。 以太坊將比特幣針對(duì)數(shù)字交易的功能進(jìn)一步進(jìn)行了拓展,面向更為復(fù)雜和靈活的應(yīng)用場(chǎng)景,支持了智能合約這一重要特性。 以太坊項(xiàng)目簡(jiǎn)介 以太坊:項(xiàng)目最初的目標(biāo)是打造以個(gè)智能合約的平臺(tái),該平臺(tái)支持...
閱讀 3610·2023-04-26 02:24
閱讀 943·2023-04-25 14:47
閱讀 2516·2021-11-24 11:16
閱讀 1733·2021-11-24 09:38
閱讀 1585·2021-11-18 10:07
閱讀 2076·2021-09-22 15:49
閱讀 1603·2019-08-30 15:55
閱讀 893·2019-08-26 13:38