1. 程式人生 > >區塊鏈學習筆記:聽說你要講一下Merkle Tree

區塊鏈學習筆記:聽說你要講一下Merkle Tree

一、小段子

客官(小姐姐):哎,小二,我看之前有篇文講到Merkle Tree,聽說你要講Merkle Tree,這Merkle Tree究竟是什麼?

小二(我): 嗯,是的,小姐姐今天真幸運,我現在就給你細細講解。

客官(小姐姐):等等,我先搬好小凳子,好了,你說吧。

小二(我):........

二、這Merkle Tree究竟是什麼

在我說Merkle Tree 之前,我想講講另外一個與merkle tree 息息相關的Hash。

1.hash

hash(雜湊), 我們通常把雜湊函式簡稱雜湊(hash),所以這個hash事實上是一個函式,它也叫做雜湊函式,在百度百科的定義就是:

把任意長度的輸入(又叫做預對映pre-image)通過雜湊演算法變換成固定長度的輸出,該輸出就是雜湊值。這種轉換是一種壓縮對映,也就是,雜湊值的空間通常遠小於輸入的空間,不同的輸入可能會雜湊成相同的輸出,所以不可能從雜湊值來確定唯一的輸入值。簡單的說就是一種將任意長度的訊息壓縮到某一固定長度的訊息摘要的函式。

使用hash比較突出的特徵就是如果輸入稍微有不同,那麼產生的hash值就有巨大的變化,因為有這個特徵,所以可以用來對檔案進行完整性校驗;由於不同的輸入可能會產生相同的輸出,所以也很難通過產生的hash值來唯一確定輸入,也就是我們很難逆向推算出原來的輸入資訊,提高了安全性。

我們說驗證檔案資料的完整性可以通過驗證其hash值,那麼如果我們驗證的這個檔案過於龐大呢?按照之前的思路,我們可能就會想著把整個檔案生成一個hash來驗證不就行了嗎?是的,這是可行的,但是我們可以再往更加便利的方向思考,如果經過對比自己所下載的檔案與原來檔案的hash值不一樣,我們就得重新下載一個完整的檔案,但問題來了,我們的前提條件已經說了這個檔案是大檔案下載是需要更多的時間的,然後我們對比過hash值不同後再重新下載檔案,等同再花費同樣更多的時間,這樣的效率十分的低,我們都不想這樣浪費時間。

所以,我們都很聰明,想到了把檔案分塊,分別為這些資料塊做hash運算,然後把這一個個hash值串在一起再做hash運算得到一個總hash值來代表這個檔案,我們把這些生成的一個個hash值作為這個檔案的hash列表(hash list),把總的hash值稱為該檔案的根hash(root hash),然後當我們下載檔案,發現根hash不同,就會往下逐個逐個比較是哪一個hash不同,找到不同的hash就可以只是重新下載不同hash的那個檔案小分塊,而不用花大時間重新下載大檔案了。

客官您可以看看下面的圖會更容易理解:

 2.merkle tree

有了上面hash的基礎,我們就可以進入merkle tree的環節。

為什麼提到merkle tree 要提及hash的知識呢,事實上merkle tree(默克爾樹) 又叫 hash tree(雜湊樹)。顧名思義,hash tree 就是由hash值組成的 。我們在上段提到的hash list 其實就是 merkle tree 的特殊形式。而我們說的merkle tree 跟hash list相比起來就是:1、merkle tree一般是二叉樹的形式;2、Merkle Tree的葉子節點的value是資料集合的單元資料或者單元資料hash;3、Merke Tree非葉子節點value是其所有子節點value的hash值。

同樣的,小二我用一張圖來個客官您認識下merkle tree:

根據上面這張圖,我們來說說一個檔案生成的默爾克根是怎麼實現的。

首先還是一個檔案把它分塊,我們祈禱著這分塊的數目最好是偶數,那就可以生成偶數個雜湊值,再每相鄰兩個雜湊值串在一起再次做雜湊運算,因為上文提到默爾克樹一般為二叉樹,所以一個節點最大分支數就是2,所以每兩個雜湊值串起來做雜湊執行算就能得到這兩個雜湊值結合生成的‘子雜湊’。

那麼如果檔案分塊出來是奇數的話,對於最後多出來的那一個小資料塊的處理就是一直對它進行雜湊運算,儘管沒有其它雜湊跟它匹配(可憐的單身汪),它自身可以自己產生子雜湊。不斷生成子雜湊直到最後只生成兩個子雜湊節點的時候,當他們再串起來結合生成一個唯一的雜湊值,這個值就叫做根雜湊,也是默爾克根。

不單單除了檔案分塊數目是奇數時用上文的規則,只要每一層的子雜湊數目是奇數,那多出來的那個子雜湊也要自己做雜湊運算。

merkle tree 和 hash list 的區別是什麼呢?小二我引用某段話來說。

Merkle Tree和Hash List的主要區別是,可以直接下載並立即驗證Merkle Tree的一個分支。因為可以將檔案切分成小的資料塊,這樣如果有一塊資料損壞,僅僅重新下載這個資料塊就行了。如果檔案非常大,那麼Merkle tree和Hash list都很到,但是Merkle tree可以一次下載一個分支,然後立即驗證這個分支,如果分支驗證通過,就可以下載資料了。而Hash list只有下載整個hash list才能驗證。

 簡單的說就是merkle tree 比 hash list 更加有效率,並能節省時間。

3.區塊鏈中的merkle tree

剛剛客官您對merkle tree有了一定的概念之後,小二我就可以說說這個merkle tree在區塊鏈上是怎麼回事。

我們已經知道了merkle tree 的出現就是為了校驗,那麼我們可以想到了,merkle tree 可以校驗檔案是否一致,即一致性校驗。那麼在區塊鏈中也是一樣道理。merkle tree 是校驗交易資料的一致性,即可以知道交易資料有沒有損壞,或是被攥改。這樣就可以保證我們在每一個區塊上的交易記錄的不可更改性,或是不可重複交易。

客官是否還記得那張區塊鏈merkle tree的 圖?若忘記了的話,小二我這下面再放上去給您看看。

 從這幅圖中我們可以知道一個區塊中記錄了數筆的交易,而至於這具體的數目是多少,是說不準的,因為一個區塊的容量為1M,每一筆的交易大小都不同,平均可能是250位元組,那麼一個區塊算下來就可容納2500筆交易左右。然後把這麼多的交易資料不斷進行雜湊運算,形成merkle tree,最終生成一個默爾克根放在每一個的區塊頭上。可以進行校驗。

merkle tree 能進行一致性校驗,同時也可以進行資料校驗,驗證某一條資料是否存在,檢驗到與默爾克根值不同,那就證明某一條資料並不存在。至於具體的的內容小二我給客官您一張推薦劵——理解區塊鏈背後的Merkle Tree

文章寫得很詳細,小二我強烈推薦。

客官(小姐姐):小二,可以了,我現在腦脹了,我得好好消化才繼續聽你講吧

小二(我):好的,歡迎再來,我在這裡再給您一張推薦劵——MerkleTree概念,相信客官擁有了這兩張推薦劵,能夠對merkle tree豁然開朗(微笑)。