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