區塊鏈比特幣關系(比特幣的區塊鏈空間回收)
中本聰在《A Peer-to-Peer Electronic Cash System》原文指出:
一旦某個貨幣的最新交易已經被足夠多的區塊覆蓋,這之前的支付交易就可以被丟棄以節省磁盤空間。為便于此而又不破壞區塊的哈希值,交易將被哈希進默克爾樹 [7][2][5],只有根節點被納入到區塊的哈希值。老的區塊可通過剪除樹枝的方式被壓縮。樹枝內部的哈 希不需要被保存。
到底占用了多少空間?
下面我們看看比特幣從2009年到2022年區塊占用空間的規模變化趨勢圖,統計數據來源于:https://www.statista.com/statistics/647523/worldwide-bitcoin-blockchain-size/。
由上圖可以看出2009年剛發行時,存儲空間占用可以忽略不計。截止到2022年7月,磁盤空間占用規模高達400G。這意味著比特幣網絡的全節點數據規模已經達到了400G,也就是說如果一個新的節點要想同步比特幣網絡區塊數據,至少要同步400G數據。雖然網絡上的節點不一定都是全節點,其實中本聰早已在論文中簡單地提出了解決方案來解決日益增長的數據空間需求。
什么時候回收和誰來回收?
論文指出:一旦某個貨幣的最新交易已經被足夠多的區塊覆蓋,這之前的支付交易就可以被丟棄以節省磁盤空間。其實空間回收的話可以有兩個方向,一個是刪除老數據來騰挪空間,一個是裁剪底層的數據結構。但是為了保留全網賬本的數據,需要有特定需求的全節點,普通節點是可以通過空間回收的算法來騰出硬盤空間的。
怎么回收?
區塊由區塊頭和交易信息構成,為了確保不損壞區塊的hash值(非常重要),交易信息通過hash被構建成了一種Merke樹的形態,只有根被納入了區塊的hash值。
重點有以下:
每一筆交易都產生一個hash值
每一筆交易都是一個葉子節點
父節點的hash值由左右子節點的hash相加后再hash生成
如果父節點只有一個左孩子節點,則拷貝一份左孩子節點為右孩子節點來計算父節點的hash值
分支拔出后,只保留最右最下的交易,即最后一筆交易
只有會影響根節點hash計算的子節點hash值會被留下來
空間評估
每個不含交易的區塊頭大約是80 bytes。按照設計的出塊速度大約是10分鐘,實際情況下會更慢一些,每年生成的區塊占用空間約為 80 bytes * 6 * 24 * 265 = 4.2 MB。按照摩爾定律,內存和硬盤價格會越來越低,設備的內存空間也會逐步越來約大,就算過了120年到2140左右比特幣區塊挖盡之后,把所有的區塊頭都存在內存里,存儲也不是問題。
數據結構為什么要用Merkle Tree?
MerkleTree是區塊鏈的基本組成部分,如果沒有Merkle Tree,區塊鏈也可以基于其他的數據結構實現。如果不空間回收的話,最后全網可能只剩下那些最強大的計算機才可以運行在區塊鏈網絡里。
Merkle Tree,本質上是用hash構建起來的樹,二叉樹結構。樹的每個父節點,都是由左右孩子節點的值相加后哈希計算生成,樹的最頂層節點叫做默克爾樹根。如果樹的某一層存在奇數個hash,則復制該層最后一個hash補充到右孩子節點位置。
試想,如果我們篡改了交易數據,那么就會從下到上傳遞修改父節點的hash,一直到根節點,這樣區塊的hash就被篡改了,篡改后大家都不承認,所以這一特點天然地適合在區塊鏈中防治篡改交易數據。
空間回收到,會遇到什么問題?
通過Merkle tree的分支裁剪缺少降低了一個區塊的空間占用,但是也減少了區塊中的交易記錄。注意中本聰說的是當區塊被足夠多的節點收納后才開始空間回收的。如果一個節點執行了回收邏輯后,賬本是不全的,它只能驗證鏈路是合理的、接收新的區塊或者基于最長的鏈挖掘新的區塊。但是如果這個節點需要查詢一個區塊的數據但是賬本又不全時怎么呢?
其實,這個時候該節點是無法做交易溯源的,好在網絡上還有其他的節點保存該區塊的交易信息,因此這個時候丟失交易信息的節點需要求助包含該區塊的其他節點(包含全節點)。
備注:比特幣網絡指的是運行了比特幣P2P協議的所有節點的集合,每個節點地位上是平等的,但是由于偏向的功能點不同,包含不同角色的節點。節點的功能主要有錢包、挖礦、保存全部賬本和路由,對應的就是錢包節點、礦工節點、全鏈節點和路由節點。錢包節點只關心和自己錢包中的地址相關部分交易,不會下載完整的區塊鏈,也稱為輕節點。礦工節點主要工作是挖礦,獨立的,不加入礦池的節點要挖礦的話是需要下載全部區塊鏈的,也是全節點,但是不驗證交易。全節點是功能最全的節點,包含了全部的賬本,也可以擁有錢包和挖礦的能力,全節點具備路由功能,只有全節點才可以真正地去驗證交易。
后續會逐步發文章一一探索Web3.0的奧秘,包括但不限于:各種形態和底層原理。