盤點京東金融區塊鏈儲存擴充套件的三個方案詳情內容

買賣虛擬貨幣

傳統的中心化“雲端儲存”存在很多問題,運用“分散式儲存網路IPFS+區塊鏈” 或許可以解決區塊鏈天然不易儲存大檔案的問題。本文源於京東金融區塊鏈實驗室技術專家李冠男分享的《基於Fabric的儲存擴充套件實踐》的主題演講,在實踐的過程中,他提出了三個設計方案,希望能給大家一點啟發。

以下是李冠男的分享,由整理。

大家都知道,區塊鏈的故事開始於2008年中本聰發表《一種點對點的電子現金系統》,之後比特幣橫空出世。後來又出現了以太坊,隨著市場熱度的高漲,人們發現了區塊鏈技術本身的應用價值,各種專案層出不窮,但是這其中的很多場景需要區塊鏈具備檔案儲存能力。

一般來講,大家的第一反應是,我能不能把資料都儲存在鏈上?但是現有的主流區塊鏈,比特幣就不用說了,以太坊上面存資料是非常昂貴的,按照Gas資料是5Gwei計算,儲存1MB資料需要花費3.76ETH。HyperLedger Fabric因為是聯盟鏈,把資料硬要存在上面也是可以的,但現在有個寫死的限制,預設資料小於99M,如果大於的話,需要重新編譯它的程式碼。

所以可以看到,資料全部上鍊並不明智,也沒有必要像儲存交易資料一樣,讓千百兆的資料檔案儲存在每一個節點上。所以通常的做法是: 將檔案儲存在鏈外,在鏈上儲存檔案的hash ,這樣檔案其實依然是中心化儲存,比如傳統的“雲端儲存“。

當前多采用的中心化“雲端儲存”

什麼是“雲端儲存”?

傳統雲端儲存是讓使用者上傳自己的資料到雲端,使用者上傳完畢後,由服務提供商將資料儲存在他們的資料中心。這樣使用者無論何時何地想要訪問這些資訊的時候,只需要向資料中心傳送一條請求,資料中心將資料發給使用者。

中心化的“雲端儲存”存在以下問題:

典型的問題是資料中心都是大型伺服器,它需要溫控,並且嚴格維護,成本高昂,而且會有延遲,因為通常資料中心與使用者不會距離很近。有人說,可以使用CDN,但問題是它的隱私策略是由服務提供商設計的,他們依然有辦法訪問和分享使用者的個人資料,畢竟是不透明的。而且除了作惡的可能,只要有人工牽扯進去,就很可能會有意外的錯誤。比如員工誤刪資料庫的事件並不罕見,GitLab事件讓人記憶猶新…

採用“分散式儲存網路”優點眾多

所以我們需要採用分散式儲存網路。這個技術並不新鮮,它有很多優點,儲存的檔案大小不受限制,可以無限擴充套件儲存容量,而且成本低,不受地域限制,還是去中心化的,如果應用特點的技術,也可以保證它的內容不被篡改。

如果將“分散式儲存網路”和“區塊鏈”技術結合起來,是不是就可以解決區塊鏈天然不易儲存大檔案的這種問題?

我選用的就是IPFS技術,中文叫做星際檔案系統。

分散式儲存IPFS——What?How?

IPFS是什麼?

 IPFS是分散式儲存網路;

 IPFS是一個點對點的超媒體協議,目的是讓現有的網路更快、更安全、更開放;

 IPFS有一個很瘋狂的目標:致力於替代HTTP協議,為所有人建造一 個更好的網路 ;

那麼它有什麼特點呢?

首先,儲存在IPFS上的檔案,是被打散儲存的。就是說每個檔案以及所有的檔案塊都有獨一無二的指紋,這個指紋就是一個加密雜湊值。其次,IPFS網路可以自動去除重複檔案,也可以跟蹤每個檔案的版本歷史 。而且每個網路節點只需要儲存自己感興趣的內容以及一些索引資訊,這些索引資訊的作用就是用來找到誰儲存了什麼 。當查詢檔案的時候,你可以使用Hash詢問IPFS網路哪些節點儲存了什麼內容。最後,每個檔案可以透過去中心化的命名系統IPNS獲得對人友好的名字 而不是一串看花眼的hash。

IPFS技術棧分為這麼幾層:

最底層當然是網路、然後是路由、交換層、特定的結構層、Merkledag、命名系統,最上面是應用。IPFS和區塊鏈一樣,是技術集大成者,它借鑑了很多相關的技術。最下面三層的作用是轉移資料,往上的兩層是定義資料,最上面當然就是使用資料了。

在介紹完基礎工具後,正式講解我的嘗試。

基於Fabric的儲存擴充套件實踐

首先,我明確了三個目標:

1.我希望Fabric能夠暴露出 一組介面,使得外部可以透過Fabric使用IPFS;

2.我希望接下來Chaincode可以在有需要時也可以直接使用IPFS這個功能;

3.我希望這個過程中儘量少的修改現有Fabric程式碼。換句話說,我希望這是一種系統的能力,而不是一種特定的應用層手段。

目標擺在這兒了,最直接的方式是以現有的go-sdk作為粘合劑,將Fabric和IPFS聯合起來。

最開始的想法是:對go-sdk進行二次開發,把與IPFS互動的邏輯封裝其中,實際上在使用過程中,由sdk先請求 IPFS得到返回,再將返回結果作為交易內容寫入Fabric ,和大部分現在的用法是一樣的。

另外IPFS有的幾個特點需要注意:一是它有自己的垃圾回收機制,當你寫入某個節點的資料,只有經過稱為“pin”的操作才能保證不被回收掉。二是不同節點之間不會自動備份同步資料,除非主動發起請求 。

基於這些想法,就誕生了第一個方案:

方案一

很簡單,透過sdk改造一下,用sdk去操作IPFS網路。把這個檔案新增pin之後得到雜湊返回,然後把雜湊值封裝到一般的交易裡面,再提交給FabriC網路。

這個方案有幾個明顯特點: 首先,IPFS與Fabric是相互獨立的,沒有直接的互動。IPFS作為外部系統由sdk呼叫 ,這樣做的優點是完全不用修改Fabric程式碼和內部流程。但缺點是,今後辦法直接使用IPFS的。

我們來看看Fabric 的Chaincode 的是怎麼工作的?大家都知道Chaincode是執行在docker容器中的,它和peer是透過GRPC通訊的。

通常,Chaincode首先需要註冊,註冊之後初始化,然後才能執行儲存資訊這樣的操作,再往後就是一些判活操作了。但是這種互動它其實有一箇中間層,是透過Shim元件去互動的,Shim中的 chaincodeStubInterface 定義了在chaincode中可以使用的功能。 所以我就誕生了第二個想法,若是想 chaincode使用IPFS,對shim進行擴充套件來實現。

方案二

這個方案的想法就是先去擴充套件shim.ChaincodeStubInterface,新增實現相應的功能函式,光新增函式肯定不行,還需要在Fabric內開闢一個模組,專門用來處理IPFS相關的請求,這樣就可以像呼叫GetState/PutState一樣呼叫類似GetFile/PutFile的函式來獲取/儲存檔案了。

這個方案裡,peer是Chaincode 的代理,可以與IPFS網路直接去互動。整個想法其實很簡單,但真正實現過程中,我發現並不容易,因為需要修改Fabric的很多程式碼,另外這個方案仍然是需要應用去主動維護檔案的狀態。IPFS網路節點是不會主動去備份這些檔案的。跟第一個方案相比,它已經實現了讓Chaincode直接使用IPFS,雖然缺點很多,但看上去方向應該沒錯。

這個時候我剛好注意到,Fabric1.2中有一個不錯的特性,這也得益於它的架構設計,一切設計都是可插拔的。Fabric1.2中系統鏈碼會在每個新建立的channel自動部署一套 ,並且不同的channel之間實現了隔離。所以我們跳出來看,讓chaincode使用IPFS,即讓chaincode呼叫外部的途徑都有什麼呢? 可不可以藉助Fabric系統可插拔的特性去實現這個功能呢?我看到ChaincodeStubInterface中有一個功能函式叫InvokeChaincode,這個功能很好,它可以讓一個Chaincode去呼叫另一個Chaincode,這讓我想到了第三個方案。

方案三

我完全可以把與IPFS互動的邏輯包裝成一個系統程式碼,然後應用可插拔特性把它整合進去。然後就可以用InvokeChaincode的功能,獲得相應的能力。而且好處還不少。首先它可以單獨維護,修改和升級都很方便。User Chaincode可以透過我剛說的這個功能,呼叫IPFScc來使用IPFS,也不用修改程式碼,並且可以把檔案索引儲存在IPFScc namespace中,這樣由系統實現檔案狀態監控也可行了 。

而且我可以其實靈活一些,把方案一里的辦法整合進來,讓sdk去開發一組介面,讓它可以和IPFS網路進行互動,得到的hash上傳到賬本里也是可以的。

還有最後一個問題就是剛才提到的,把檔案上傳進去之後,如果你不去操作的話,它不會主動備份。這個問題怎麼解決?最後我是透過IPFS-cluster,它有自己提供的共識機制,而且能自動備份IPFS網路中的檔案,還可以靈活配置備份數量。

這樣的話流程就比較清楚了。我可以透過Sdk/CLI上傳檔案/由chaincode 根據需要在peer端臨時生成檔案並上載IPFS網路,得到返回hash,透過IPFS- cluster pin 檔案,成功後將檔案資訊及相關IPFS 索引資訊寫入IPFScc的ledger 。這樣的話其實應用的空間也就被開啟了。

以上就是我做的實踐嘗試,這個方案也不完美,但是希望整個過程能給大家帶來一些啟發。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;