區塊鏈新C位:IPFS 與 FileCoin

說起“區塊鏈”你是不是一臉的問號

“區塊鏈”對大部分人來說都是陌生的

但是它的作用

未來可能是顛覆性的

到底有多顛覆

專家說了

它的顛覆性堪比是互聯網技術

在這篇文章中,我想聊一聊最近比較熱門的 IPFS(InterPlanetary File System),一個點對點的分佈式文件系統;從 HTTP 協議出現到今天已經過去了半個多世紀,很少有一些設計能夠增強整個 HTTP 網絡或者為它帶來新的功能。


區塊鏈新C位:IPFS 與 FileCoin

使用 HTTP 協議傳遞相對小的文件其實是非常廉價和方便的,但是隨著計算資源和存儲空間的指數增長,我們面臨了需要隨時獲取大量數據的問題,而 IPFS 就是為了解決這一問題出現的。

架構設計

作為一個分佈式的文件系統,IPFS 提供了一個支持部署和寫入的平臺,同時能夠支持大文件的分發和版本管理;為了達到上述的目的,IPFS 協議被分成如下的幾個子協議:


區塊鏈新C位:IPFS 與 FileCoin

上述的七個子協議分別負責 IPFS 中的不同功能,我們將在接下來的章節中分別介紹各個協議分別做了哪些工作以及 IPFS 是如何實現的。

身份

在 IPFS 網絡中,所有的節點都通過唯一的 NodeId 進行標識,與 Bitcoin 的地址有一些相似, 它其實是一個公鑰的哈希,然而為了增加攻擊者的成本,IPFS 使用 S/Kademlia 中提到的算法增加創建新身份的成本:

 difficulty = <integer>n = Node{}do {
n.PubKey, n.PrivKey = PKI.genKeyPair()
n.NodeId = hash(n.PubKey)
p = count_preceding_zero_bits(hash(n.NodeId))} while (p < difficulty)
/<integer>


每一個節點在 IPFS 代碼中都由Node 結構體來表示,其中只包含 NodeId 以及一個公私鑰對:

 type NodeId Multihashtype Multihash []bytetype PublicKey []bytetype PrivateKey []bytetype Node struct {
NodeId NodeId
PubKey PublicKey
PriKey PrivateKey}


總之,身份系統的主要作用就是表示 IPFS 網絡中的每一個節點,代表每一個使用 IPFS 的『用戶』。

網絡

作為一個分佈式的存儲系統,節點之間的通信和信息傳遞都需要通過網絡進行,同時能夠使用多種傳輸層協議並保證可靠性、連通性、信息的完整性以及真實性。


區塊鏈新C位:IPFS 與 FileCoin

IPFS 可以使用任意的網絡進行通信,它並沒有假設自己一定運行在 IP 協議上,而是通過 multiaddr 的格式來表示目標地址和使用的協議,以此來兼容和擴展未來可能出現的其他網絡協議:

/ip4/10.20.30/40/sctp/1234/
/ip4/5.6.7.8/tcp/5678/ip4/1.2.3.4/sctp/1234/


路由

在一個分佈式系統中,檢索或者訪問其他節點中存儲的資源就需要通過一個路由系統,IPFS 使用了基於 S/Kademlia 和 Coral 中的 DSHT 實現了路由系統,我們能夠在 libp2p/go-libp2p-routing/routing.go 中找到 IPFS 路由系統的接口:

type IpfsRouting interface {
ContentRouting
PeerRouting
ValueStore Bootstrap(context.Context) error}type ContentRouting interface {
Provide(context.Context, *cid.Cid, bool) error
FindProvidersAsync(context.Context, *cid.Cid, int) FindPeer(context.Context, peer.ID) (pstore.PeerInfo, error)}type ValueStore interface {
PutValue(context.Context, string, []byte) error
GetValue(context.Context, string) ([]byte, error)
GetValues(c context.Context, k string, count int) ([]RecvdVal, error)}


從這裡我們可以看到 IPFS 中的路由需要實現三種基本的功能,內容路由、節點路由以及數據存儲。實現了這幾些接口的『路由器』就可以在底層進行替換,不會影響系統其他部分的工作。目前 IPFS 使用全局 DHT 和 DNS 來解析路由記錄,而 Kademlia DHT 有以下的優點:

1. 在批量節點中快速找到目標地址,時間複雜度是 $log_2(n)$,也就是說,在 10,000,000 節點中只需要 20 次查詢;

2. 優化了節點之間的控制消息長度,降低了信息協調的開銷;

3. 通過優先選擇長期節點抵禦多種網絡攻擊;

4. 在點對點的應用中被廣泛應用,例如 BitTorrent 和 Gnutella,技術也比較成熟;

數據交換

在 IPFS 中,數據的分發和交換使用 BitSwap 協議,BitSwap 負責兩件事情:向其他節點請求需要的 Block 以及為其他節點提供 Block。


區塊鏈新C位:IPFS 與 FileCoin

當我們需要向其他節點請求 Block 或者為其他節點提供 Block 時,都會發送 BitSwap 消息,其中主要包含了兩部分內容:發送者的 wantlist以及數據塊,整個消息都是使用 Protobuf 進行編碼的:

message Message {
message Wantlist {
message Entry {
optional string block = 1; // the block key
optional int32 priority = 2; // the priority (normalized). default to 1
optional bool cancel = 3; // whether this revokes an entry
}
repeated Entry entries = 1; // a list of wantlist entries
optional bool full = 2; // whether this is the full wantlist. default to false
}
optional Wantlist wantlist = 1;
repeated bytes blocks = 2;
}


在 BitSwap 系統中,有兩個非常重要的模塊需求管理器(Want-Manager)和決定引擎(Decision-Engine);前者會在節點請求 Block 時在本地返回相應的 Block 或者發出合適的請求,而後者決定如何為其他節點分配資源,當節點接收到包含 wantlist 的消息時,消息會被轉發至決定引擎,引擎會根據該節點的Ledger 決定如何處理請求。

想要了解跟多 BitSwap 的實現細節以及 Spec 的讀者可以閱讀 BitSwap Spec 其他內容。


IPFS 除了定義節點之間互相發送的消息之外,還引入了激勵和懲罰來保證整個網絡中不會有『惡意』的節點,通過 Ledger 來存儲兩個節點之間的數據來往:

type Ledger struct {
owner NodeId
partner NodeId
bytes_sent int
bytes_recv int
timestamp Timestamp
}


決定引擎會通過兩個節點之間的 Ledger 計算出一個負債比率(debt ratio):


區塊鏈新C位:IPFS 與 FileCoin


負債比率是用來衡量節點之間信任的,它不僅能夠阻止攻擊者創建大量的節點、還能在節點短時間不可用時保護已有的交易關係並且在節點關係惡化之前終止交易。

IPFS 使用 Ledger 創建了一個具有激勵和懲罰的網絡,保證了網絡中的大部分節點能夠交換數據並且正常運行。

文件系統

DHT 和 BitSwap 允許 IPFS 構建一個用於存儲和分發數據塊的大型點對點系統;在這之上,IPFS 構建了一個 Merkle DAG,每一個 IPFS 對象都可能包含一組鏈接和當前節點中的數據:

type IPFSLink struct {
Name string
Hash Multihash
Size int
}
type IPFSObject struct {
links []IPFSLink
data []byte
}


我們可以使用如下的命令列出該對象下的全部鏈接:

$ ipfs ls QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG
QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1688 about
QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y 200 contact
QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 322 help
QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha 1728 quick-start
QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB 1102 readme
QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ 1027 security-notes


原始數據加上通用的鏈接是在 IPFS 上構造任意數據結構的基礎,鍵值存儲、傳統的關係型數據庫、加密區塊鏈都可以在 IPFS 的 Merkle DAG 上進行存儲和分發。

在這之上,IPFS 定義了一系列的對象構建了支持版本控制的文件系統,它與 Git 的對象模型非常類似,並且所有文件對象其實都通過 Protobuf 進行了二進制編碼:


區塊鏈新C位:IPFS 與 FileCoin

IPFS 文件可以通過 list和blob 進行表示:

  • 其中 blob不包含任何的鏈接,只包含數據;
  • 但是 list卻包含了一個 blob 和 list的有序隊列;
  • 而 tree文件對象與 Git 中的tree 非常相似,它表示一個從名字到哈希的文件目錄;
  • 最後的 commit 表示任意對象的快照;


區塊鏈新C位:IPFS 與 FileCoin

在上述文件對象圖中,最頂層的 commit 就表示歷史的某一次快照,對比兩次 commit以及子節點構成的樹就能得到兩次快照之間的差別,我們可以認為 Merkle DAG 和文件對象構成了整個 IPFS 中的文件系統。

命名系統

到目前為止,IPFS 技術棧已經提供了一個點對點的數據交換系統,能夠在節點之間發送 DAG 對象,並且可以推送和取回不可變的對象,但是可變的命名系統也是網絡不可缺少的一部分,我們終究需要使用同一個地址獲取不同的狀態,因為不能因為網站的更新而改變域名,所以 IPFS 需要提供一種『域名服務』解決這一問題。

在 IPFS 中可以使用如下的可變命名空間來解決這些問題,用戶可以發佈一個對象,其他節點就可以通過 ipns 加上該用戶的節點地址訪問到這些發佈到網絡中的對象:

/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhetaAmU8Vm/


當然,我們也可以在現有的 DNS 系統中添加 TXT 記錄,這樣就能通過域名訪問 IPFS 網絡中發佈的文件對象了:

ipfs.benet.ai. TXT "ipfs=XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm"
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm
/ipns/ipfs.benet.ai


在 IPFS 不僅能夠使用哈希訪問可變對象,也能嵌入現有的 DNS 服務中很好的運行,解決了底層服務無縫切換的問題。

激勵

在今天,當我們討論 IPFS 這種底層的區塊鏈技術時,就不得不提構建在 IPFS 上的 FileCoin,它提供了一個給宿主和上傳者交易的市場,通過市場可以調節存儲的成本,上傳者能夠根據價格選擇速度、冗餘和成本。

節點

大多數的區塊鏈網絡中都只具有單一類型的標準節點,但是 FileCoin 中卻有兩種不同的節點:存儲節點和檢索節點。


區塊鏈新C位:IPFS 與 FileCoin

所有人都可以成為存儲節點,將自己磁盤上額外的存儲空間租賃出去,FileCoin 會使用這些磁盤存儲一些較小的加密文件的一部分;而檢索節點則需要儘可能靠近更多的存儲節點,也需要更高的帶寬和更低的延遲,用戶會支付最快返回文件的檢索節點。

當我們想要上傳文件時,需要支付一定的存儲費用,存儲節點會為存儲文件的權利給出報價,FileCoin 會選擇價格最低的存儲節點保存文件;存儲的文件會被加密並分割成多個部分併發送給多個節點,文件的位置會存儲在全局的表中,在這之後只有擁有私鑰的節點才能查詢、組裝並且解密上傳的文件。

共識算法

我們可以說所有的區塊鏈應用都需要 共識算法 保證多個節點對某一結果達成共識,並在發生衝突時進行解決,Bitcoin 和 Ethereum 目前都使用了 Proof-of-Work 作為共識算法,而 FileCoin 使用 Proof-of-Replication(PoRep) 解決其網絡內部存在的問題。

We introduce Proof-of-Replication (PoRep) schemes, which allow a prover P to (a) commit to store n distinct replicas (physically independent copies) of D, and then (b) convince a verifier V that P is indeed storing each of the replicas.

PoRep 允許證明者 P 提交存儲 n 個 D 的不同副本,然後說服驗證人 V,P 確實保存了這些副本。


在 Proof of Replication 一文中能夠找到更多與 PoRep、PoS(Proof-of-Storage) 等用於驗證磁盤空間提供方確實存儲資源的共識算法,在這裡就不展開介紹了。

總結

IPFS 是一個非常有意思的區塊鏈底層技術,它在兼容現有互聯網協議的基礎上,實現了點對點的文件存儲系統並且為大數據存儲提出了方案,作者嘗試了一下 IPFS 的官方客戶端 go-ipfs 也確實比較好用,但是目前也是在項目的早期階段,很多模塊和功能還沒有定型,而基於 IPFS 發佈的 FileCoin 也沒有要發佈的確切日誌 Proof of Replication 這篇白皮書還被標記為 WIP(Work In Process),有一些部分也沒有完成,所以等待這門技術的成熟也確實需要比較長的一段時間。



分享到:


相關文章: