什么是區(qū)塊鏈的全節(jié)點(diǎn)與輕節(jié)點(diǎn)?
大家都知道,隨著時(shí)間的不斷流逝,區(qū)塊鏈上的交易會越來越多,隨之也就造成了區(qū)塊鏈的數(shù)據(jù)容量不斷增大,由于區(qū)塊鏈的冗余備份,要求所有節(jié)點(diǎn)都需要保存全量的數(shù)據(jù)文件,這個(gè)時(shí)候,假如有一個(gè)用戶想用自己創(chuàng)建一個(gè)區(qū)塊鏈節(jié)點(diǎn)來進(jìn)行DApp的開發(fā),但是又不想?yún)⑴c共識,其實(shí)對于這個(gè)用戶來說,同步大量的數(shù)據(jù)是一件很耗時(shí)的事情,并且十分浪費(fèi)相關(guān)的硬盤資源。
因此,專員今天想來跟大家講一下區(qū)塊鏈中的全節(jié)點(diǎn)以及輕節(jié)點(diǎn)的概念,專員的思考角度其實(shí)主要也是從以太坊這種賬戶模型去思考,今天也以以太坊作為例子來說這個(gè)事情。
以以太坊作為例子
在說全節(jié)點(diǎn)與輕節(jié)點(diǎn)相關(guān)介紹之前
專員首先向來跟大家說一下以太坊的區(qū)塊頭相關(guān)的東西,以太坊區(qū)塊的存儲主要分為兩個(gè)部分,分別是Header和Body,Body其實(shí)比較簡單,就是一些的交易列表,還有Uncle Block的相關(guān)信息,但是其實(shí)更為復(fù)雜的其實(shí)是Block Header,如下圖所示Block Header里面會存比較多的數(shù)據(jù),比如說父區(qū)塊的區(qū)塊hash,時(shí)間戳,挖礦的難度值等等相關(guān)的參數(shù),
但是專員覺得,其中最重要的當(dāng)屬以太坊中的“三棵樹”,與此對應(yīng)在區(qū)塊頭中的就是,StateRoot,TransactionRoot和ReceiptRoot三個(gè)哈希值。
在以太坊中什么用來存儲區(qū)塊數(shù)據(jù)的核心數(shù)據(jù)結(jié)構(gòu)?
利用了一種叫做Merkle-Patricia Trie(MPT)是Ethereum用來存儲區(qū)塊數(shù)據(jù)的核心數(shù)據(jù)結(jié)構(gòu)。
最簡單理解是一個(gè)倒置的樹形結(jié)構(gòu),每個(gè)節(jié)點(diǎn)可能有若干個(gè)子節(jié)點(diǎn),在最底層,也就是葉子節(jié)點(diǎn),把數(shù)據(jù)分成若干個(gè)小的數(shù)據(jù)塊,計(jì)算出相應(yīng)的Hash與之對應(yīng)。
但是往上層看去,Merkle樹并不是直接去運(yùn)算根哈希,而是把相鄰的兩個(gè)節(jié)點(diǎn)的哈希合并成一個(gè)字符串,然后運(yùn)算這個(gè)字符串的哈希,這樣每兩個(gè)哈希就能夠得到了一個(gè)”子哈?!?,而這個(gè)自哈希就是他們的父節(jié)點(diǎn)的哈希值。
于是以此類推依然是一樣的方式計(jì)算哈希值,可以得到數(shù)目更高級節(jié)點(diǎn)的新一級哈希,最終必然形成一棵倒掛的樹,到了樹根的這個(gè)位置,這一代就剩下一個(gè)根哈希了,我們把它叫做 Merkle Root。而在以太坊中,還對Merkle樹做了相應(yīng)的優(yōu)化,在Merkle樹的基礎(chǔ)上進(jìn)行前綴樹的構(gòu)建,因此也就通過前綴樹能夠快速查詢相關(guān)的數(shù)據(jù)信息,但是這個(gè)專員今天不細(xì)講,有興趣的同學(xué)可以私下去研究一下。
因此通過Merkle樹,其實(shí)我們可以做到幾個(gè)事情:
1. 快速重哈希:其實(shí)就是說,能夠在樹節(jié)點(diǎn)變化的情況下,根據(jù)上次的計(jì)算機(jī)結(jié)果通過計(jì)算部分值就可以計(jì)算出一個(gè)新的Merkle Root。
2. 輕節(jié)點(diǎn)擴(kuò)展:采用Merkle樹,我們可以再公鏈的環(huán)境下,擴(kuò)展一個(gè)輕節(jié)點(diǎn)。輕節(jié)點(diǎn)的特點(diǎn)其實(shí)就是,只需要存儲Block Header,而不存儲全量的交易列表等信息。通過Merkle證明來判斷一筆交易是否在現(xiàn)在的區(qū)塊鏈交易列表中。這樣,其實(shí)造就了以太坊的輕節(jié)點(diǎn)能夠運(yùn)行在小容量的個(gè)人PC等終端設(shè)備上。
下面說回以太坊在StateRoot,TxHashRoot和ReceiptHashRoot,分別取自三個(gè)MPT的計(jì)算結(jié)果:stateTrie, txTrie, 和receiptTrie的根節(jié)點(diǎn)哈希值。這樣的話,比如說我們在進(jìn)行Block的同步過程中,通過比對收到的TxHash,可以確認(rèn)transacTIons列表是否同步完整,通過StateRoot來判斷節(jié)點(diǎn)間狀態(tài)是不是一致的。
因此在以太坊中,所謂全節(jié)點(diǎn),其實(shí)就是同步所有區(qū)塊鏈數(shù)據(jù)的節(jié)點(diǎn),包括各種區(qū)塊Body,交易列表等等相關(guān)信息。但也是因?yàn)楣?jié)點(diǎn)全量數(shù)據(jù)都保存的情況,我們不需要相依賴中介去進(jìn)行數(shù)據(jù)的驗(yàn)證。
而所謂的以太坊輕節(jié)點(diǎn)(輕客戶端)
每當(dāng)有區(qū)塊出現(xiàn)在網(wǎng)絡(luò)便下載區(qū)塊頭,而不是全量的情況狀態(tài),并發(fā)送客戶端需要的特定狀態(tài)的默克爾證明(Merkle proofs)的請求。同時(shí)在以太坊輕節(jié)點(diǎn)中使用分布式哈希表來追蹤前綴節(jié)點(diǎn),而不是直接采用LevelDB進(jìn)行直接的存儲。
文末綜上,其實(shí)不論是輕節(jié)點(diǎn)還是全節(jié)點(diǎn),都有存在的價(jià)值以及意義,我們可以根據(jù)自己的需求去選擇部署相應(yīng)的節(jié)點(diǎn),雖說必然全節(jié)點(diǎn)的優(yōu)勢會比輕節(jié)點(diǎn)大,但是由此造成的就是全節(jié)點(diǎn)的資源損耗也必然會大很多。