各區(qū)塊鏈底層數(shù)據(jù)存儲分析,幫你了解它們的不同之處
互聯(lián)網(wǎng)的中心化發(fā)展模式是傳統(tǒng)網(wǎng)絡(luò)安全的的軟肋,區(qū)塊鏈作為一種去中心化、集體維護、不可篡改的新興技術(shù),是對互聯(lián)網(wǎng)底層架構(gòu)的革新,是對當(dāng)今生產(chǎn)力和生產(chǎn)關(guān)系的變革。區(qū)塊鏈也被譽為是繼蒸汽機、電力、信息和互聯(lián)網(wǎng)科技之后,目前最有潛力觸發(fā)第五輪顛覆性革命浪潮的核心技術(shù)。
目前市場上主流的區(qū)塊鏈系統(tǒng)有比特幣,Ripple,以太坊和 Hyperledger Fabric 。本文的主要目的就是分析當(dāng)前主要流行的區(qū)塊鏈的存儲技術(shù)以及他們之間的不同。
區(qū)塊鏈簡介
區(qū)塊鏈(英語:blockchain 或 block chain)是用分布式數(shù)據(jù)庫識別、傳播和記載信息的智能化對等網(wǎng)絡(luò), 也稱為價值互聯(lián)網(wǎng)。中本聰于2008年在《比特幣白皮書》中提出“區(qū)塊鏈”概念,并在2009年創(chuàng)立了比特幣社會網(wǎng)絡(luò),開發(fā)出***個區(qū)塊,即“創(chuàng)世區(qū)塊”。區(qū)塊鏈包含一張被稱為區(qū)塊的列表,有著持續(xù)增長并且排列整齊的記錄。每個區(qū)塊都包含一個時間戳和一個與前一區(qū)塊的鏈接,這樣設(shè)計區(qū)塊鏈?zhǔn)沟脭?shù)據(jù)不可篡改,一旦記錄下來,在一個區(qū)塊中的數(shù)據(jù)將不可逆。
其數(shù)據(jù)結(jié)構(gòu)大致如下:
(區(qū)塊鏈結(jié)構(gòu))
數(shù)據(jù)存儲
1、比特幣
比特幣(英語:Bitcoin)是一種去中心化、全球通用、不需第三方機構(gòu)或個人,基于區(qū)塊鏈作為支付技術(shù)的電子加密貨幣。它由中本聰于2009年1月3日,基于無國界的對等網(wǎng)絡(luò),用共識主動性開源軟件發(fā)明創(chuàng)立,是加密貨幣及區(qū)塊鏈的始祖,也是目前知名度與市場總值***的加密貨幣。
比特幣存儲系統(tǒng)由普通文件和 kv 數(shù)據(jù)庫(levelDB)組成。普通文件用于存儲區(qū)塊鏈數(shù)據(jù),kv 數(shù)據(jù)庫用于存儲區(qū)塊鏈元數(shù)據(jù)。
用于存儲區(qū)塊鏈數(shù)據(jù)的普通文件以 blk00000.dat , blk00001.dat 文件名格式組成,如圖2所示,其中 index 目錄存儲用于存儲區(qū)塊元數(shù)據(jù)。
(圖2)
為了快速檢索區(qū)塊數(shù)據(jù)每個文件的大小是128 M Bytes。每個區(qū)塊的數(shù)據(jù)(區(qū)塊頭和區(qū)塊里的所有交易)都會序列成字節(jié)碼的形式寫入 dat 文件中。
在序列化的過程中,如果檢測到當(dāng)前寫入文件尺寸加上區(qū)塊尺寸大于 128 M Bytes,則會重新生成一個 dat 文件。具體的序列化過程如下所述:
- 獲取當(dāng)前 dat 文件大小 npos,并將區(qū)塊大小追加寫入至 dat 文件中
- 序列化區(qū)塊數(shù)據(jù)和區(qū)塊中的交易數(shù)據(jù),并將序列化的數(shù)據(jù)追加至 dat 文件中。
- ?在寫入數(shù)據(jù)的過程中,會生成區(qū)塊和交易相關(guān)的元數(shù)據(jù)。
區(qū)塊的元數(shù)據(jù)格式如 <blockHash,xxxxx+npos> 格式, 其中 xxxxx 為 dat 文件序號,npos 為區(qū)塊寫入 dat 文件的起始位置。
交易的元數(shù)據(jù)格式如 <txHash, xxxxx+npos+nTxOffset> 格式, 其中 xxxxx、npos 和上面的描述一致,nTxOffset 為寫入 dat 文件的起始位置(基于npos 位置)。
上述所有元數(shù)據(jù)都將寫入 kv 數(shù)據(jù)庫中,其中 blockhash/txHash 將作為后續(xù)查詢具體數(shù)據(jù)在 dat 文件中的索引使用。
綜上所述,在獲取鏈數(shù)據(jù)的時候只需傳入?yún)^(qū)哈希或是交易哈希,就能很容易的定位到區(qū)塊數(shù)據(jù)或是交易數(shù)據(jù)。
2、瑞波幣
Ripple 是世界上***個開放的支付網(wǎng)絡(luò),通過這個支付網(wǎng)絡(luò)可以轉(zhuǎn)賬任意一種貨幣,包括美元、歐元、人民幣、日元或者比特幣,簡便易行快捷,交易確認(rèn)在幾秒以內(nèi)完成,交易費用幾乎是零,沒有所謂的跨行異地以及跨國支付費用。
Ripple 的區(qū)塊鏈數(shù)據(jù)存儲系統(tǒng)是由關(guān)系型數(shù)據(jù)庫(sqlite)和 kv 數(shù)據(jù)庫組成,其中關(guān)系型數(shù)據(jù)庫用來存儲區(qū)塊頭信息和每筆交易的具體信息, kv 數(shù)據(jù)庫主要存儲區(qū)塊頭、交易和狀態(tài)表序列化后的數(shù)據(jù)。 Ripple 這樣處理的主要目的是單純在查詢區(qū)塊頭信息和具體每筆交易的時候,可以直接從關(guān)系型數(shù)據(jù)庫中查找;而要構(gòu)造整個區(qū)塊數(shù)據(jù)的時候,除了從關(guān)系型數(shù)據(jù)庫構(gòu)造區(qū)塊頭信息外,還要依據(jù)區(qū)塊頭里的交易根哈希和狀態(tài)表根哈希從 kv 數(shù)據(jù)庫中獲取具體的交易和狀態(tài)表信息。這是 Ripple 和其他三種類型區(qū)塊鏈系統(tǒng)唯一***的不同。
區(qū)塊頭信息的序列化具體步驟:
- 用區(qū)塊的哈希作為 Key;
- 序列化區(qū)塊高度、區(qū)塊哈希、前一個區(qū)塊哈希、交易根哈希、狀態(tài)表根哈希等生成的數(shù)據(jù)作為 value;
- 將 <key, value> 存儲至 kv 數(shù)據(jù)庫中。
交易的序列化具體步驟:
- 用區(qū)塊頭中的交易根哈希作為 Key;
- 序列化交易哈希、交易類型、交易數(shù)據(jù)和 MetaData 等生成的數(shù)據(jù)作為 value;
- 將 <Key, value> 存儲至 kv 數(shù)據(jù)庫中。
下表分別是 Ledgers 和 Transactions 表結(jié)構(gòu)。
數(shù)據(jù)存儲(二)
1、以太坊
以太坊是一個開源的有智能合約功能的公共區(qū)塊鏈平臺。通過其專用加密貨幣以太幣(Ether,又稱為「以太幣」)提供去中心化的虛擬機(稱為「以太虛擬機」Ethereum Virtual Machine)來處理點對點合約。
以太坊的區(qū)塊主要由區(qū)塊頭和交易組成,區(qū)塊在存儲的過程中分別將區(qū)塊頭和交易體經(jīng)過 RLP 編碼后存入至 KV 數(shù)據(jù)當(dāng)中。以太坊在數(shù)據(jù)存儲的過程中,每個 value 對應(yīng)的key 都有相對應(yīng)的前綴,不同類型的 value 對應(yīng)不同的前綴。
區(qū)塊交易體的存儲過程如下:
1. 將區(qū)塊中的交易數(shù)據(jù)和叔塊頭信息進行 RLP 編碼從而生成存儲值value;
2. 將數(shù)據(jù)類型前綴,編碼后的區(qū)塊高度和區(qū)塊哈希拼接生成 key;
3.將存儲至db數(shù)據(jù)庫中。
區(qū)塊的信息可以通過區(qū)塊哈希和區(qū)塊高度進行檢索,其存儲過程如下:
1.將區(qū)塊頭信息進行 RLP 編碼從而生成存儲值 value
2.將區(qū)塊高度進行編碼(轉(zhuǎn)發(fā)成大端格式數(shù)據(jù))生成encNum
3. 將數(shù)據(jù)類型前綴 (headerPrefix) 和 encNum 生成以區(qū)塊高度為檢索信息的 key
4.將存儲至db數(shù)據(jù)庫中,從而生成以區(qū)塊高度為檢索的信息
5.將數(shù)據(jù)類型前綴(blockHashPrefix)和區(qū)塊哈希生成以區(qū)塊哈希為檢索信息的key
6.將存儲至db數(shù)據(jù)庫中,從生成區(qū)塊哈希為檢索的信息
在數(shù)據(jù)查詢的時候,應(yīng)用層只需要提供交易 hash、區(qū)塊高度和區(qū)塊哈希就能得到交易 key,從而查詢到相關(guān)的交易信息。
2、Hyperledger Fabric
Hyperledger fabric (HLF)是由Linux基金會主導(dǎo)推廣的區(qū)塊鏈開源項目。在Hyperledger Fabric的基礎(chǔ)上又衍生出了其他一些相關(guān)的項目。HyperLedger項目匯集了金融、銀行、物聯(lián)網(wǎng)、供應(yīng)鏈、制造等各界開發(fā)人員的心血。目的是為了打造一個跨領(lǐng)域的區(qū)塊鏈應(yīng)用。
HLF 的存儲系統(tǒng)和比特幣一樣,也是由普通的文件和 kv 的數(shù)據(jù)庫(levelDB/couchDB)組成。在 HLF 中,每個 channel 對應(yīng)一個賬本目錄,在賬本目錄中由 blockfile_000000、blockfile_000001 命名格式的文件名組成。為了快速檢索區(qū)塊數(shù)據(jù)每個文件的大小是64 M Bytes。每個區(qū)塊的數(shù)據(jù)(區(qū)塊頭和區(qū)塊里的所有交易)都會序列成字節(jié)碼的形式寫入 blockfile 文件中。
HLF存儲區(qū)塊數(shù)據(jù)的文件名格式如圖所示:
HLF檢索信息文件如圖所示:
在序列化的過程中,程序以 append 方式打開 blockfile 文件,然后將區(qū)塊大小和和區(qū)塊數(shù)據(jù)寫入至 blockfile 文件中。
以下是區(qū)塊數(shù)據(jù)寫入的具體描述:
1.寫入?yún)^(qū)塊頭數(shù)據(jù),依次寫入的數(shù)據(jù)為區(qū)塊高度、交易哈希和前一個區(qū)塊哈希;
2. 寫入交易數(shù)據(jù),依次寫入的數(shù)據(jù)為區(qū)塊包含交易總量和每筆交易詳細(xì)數(shù)據(jù);
3. 寫入?yún)^(qū)塊的Metadata 數(shù)據(jù),依次寫入的數(shù)據(jù)為 Metadata 數(shù)據(jù)總量和每個 Metadata 項的數(shù)據(jù)詳細(xì)信息。
在寫入數(shù)據(jù)的過程中會以 kv 的形式保存區(qū)塊和交易在 blockfile 文件中的索引信息,以方便 HLF 的快速查詢。
HLF 區(qū)塊索引信息格式在 kv 數(shù)據(jù)庫中存儲的最終的 LevelKey 值有前綴標(biāo)志和區(qū)塊 hash 組成,而 LevelValue 的值由區(qū)塊高度,區(qū)塊 hash,本地文件信息(文件名,文件偏移等信息),每個交易在文件中的偏移列表和區(qū)塊的 MetaData 組成, HLF 按照特定的編碼方式將上述的信息拼接成 db 數(shù)據(jù)庫中的 value 。
HLF交易索引信息格式在kv數(shù)據(jù)庫中存儲最終的LevelKey值由channel_name,chaincode_name和chaincode中的key值組合而成:
LevelKey = channel_name + []byte + chaincode_name + []byte + key
而 LevelValue 的值由BlockNum 區(qū)塊號,TxNum 交易在區(qū)塊中的編號組成, HLF 通過將區(qū)塊號和交易編號按照特定的方式編碼,然后與 chaincode 中的 value 相互拼接最終生成 db 數(shù)據(jù)庫中的 value 。
總結(jié)
綜上所述,本文介紹的主要區(qū)塊鏈除了 Ripple 使用的關(guān)系型數(shù)據(jù)庫存儲、檢索區(qū)塊數(shù)據(jù)外,其他三種類型的區(qū)塊鏈都使用 kv 數(shù)據(jù)庫存儲區(qū)塊鏈的檢索信息。在存儲、檢索數(shù)據(jù)上,比特幣和 Hyperledger Fabric 高度一致,即使用普通文件存儲區(qū)塊數(shù)據(jù),使用 kv 數(shù)據(jù)庫存儲檢索信息;以太坊的區(qū)塊數(shù)據(jù)和檢索信息都存儲至 kv 數(shù)據(jù)庫中,而 Ripple 的區(qū)塊數(shù)據(jù)也會存儲至 kv 數(shù)據(jù)庫中。