天天看點

IPFS(DRAFT 3) 中文版白皮書IPFS - Content Addressed, Versioned, P2P File System(DRAFT 3)

借助google翻譯加自己了解做了調整,個人在有道筆記上做記錄,現分享出來,有翻譯或了解不準确的,可以一起交流

個人有道筆記連結

IPFS - Content Addressed, Versioned, P2P File System(DRAFT 3)

Juan Benet

[email protected]

摘要 ABSTRACT

IPFS(星際檔案系統,星際檔案系統)是點對點分布式系統,追求連接配接所有相同檔案系統的計算裝置。在某些方面,IPFS類似于Web,但是IPFS可以被認為是一個單一的BitTorrent Swarm,使用Git倉庫進行交換對象。換句話說,IPFS使用内容尋址超連結,提供了高效的基于内容的位址區塊存儲模型。這形成了一個通用的MerkleDAG,它可以建構版本檔案系統,區塊鍊,甚至一個永恒的網站的資料結構.IPFS由一個分布式哈希表(分布式散清單,DHT),一個去中心化的區塊交換,一個自證明命名空間(一個自我認證的命名空間).IPFS沒有單點故障,其中的節點也不需要互相信任。

1.介紹 INTRODUCTION

在建構全球分布式檔案系統上已經進行過一些嘗試。一些系統相當成功,而另外一些則完全失敗了。在這些學術理論嘗試中,AFS獲得了廣泛的成功,直到目前還在使用。另外的一些,則沒有獲得一樣的成功。在理論研究之外,大多數成功的系統是适用于大媒體資料(音頻和視訊)的P2P檔案共享系統的應用。最著名的有,Napster,KaZaA和BitTorrent,其中BitTorrent部署了大量檔案分布式系統,有超過1億的并發使用者。即使今天,BitTorrent維持了大量的部署,每天有超過1000萬的節點數。這些應用比理論檔案系統有更多的使用者和檔案釋出。盡管如此,這些應用并沒有設計成一個基礎設施,以此為基礎建立擴充。然而,也有一些成功的改變,非通用的檔案系統已經出現,提供了全球化、低延時、去中心釋出。

可能對于大多數已存在的使用者場景Http已經是一個足夠好的系統。到目前為止,HTTP是有史以來最成功的“檔案的分布式系統”。與浏覽器相結合,HTTP産生了巨大的技術和社會影響。它已成為通過網際網路傳輸檔案的事實上的方式。然而,它未能利用過去十五年發明的數十種出色的檔案分發技術。從某個視角,演進Web基礎設施幾乎是不可能的,因為涉及大量向後相容性限制和大量團體在現有模型上的投入。但從另一個角度來看,自HTTP出現以來,新的協定已經出現并得到了廣泛的應用。缺少的是更新設計:增強目前的HTTP Web,并在不降低使用者體驗的情況下引入新功能。

業界已經開始使用HTTP了很長時間,因為移動小檔案相對便宜,即使對于擁有大量流量的小型組織也是如此。但我們正在進入一個新的資料分發時代,面臨着新的挑戰:(a)托管和分發PB級資料集,(b)跨組織計算大資料,(c)高容量高清晰度按需或實時媒體流,(d)大規模資料集的版本化和連結,(e)防止重要檔案的意外消失等。其中許多可歸結為大量資料,可随處通路。“受關鍵功能和帶寬問題的壓力,我們已經使用不同的資料分發協定放棄了HTTP。下一步是将它們作為Web本身的一部分。

正交于高效的資料分發,版本控制系統已設法開發重要的資料協作工作流程。Git是分布式源代碼版本控制系統,它開發了許多有用的方法來模組化和實作分布式資料操作。Git工具鍊提供了多種版本控制功能,大型檔案分發系統嚴重缺乏。受Git啟發的新解決方案正在出現,例如Camlistore[?],一個個人檔案存儲系統,以及Dat [?]一個資料協作工具鍊和資料集包管理器。Git已經影響了分布式檔案系統設計[9],因為其内容為Merkle DAG資料模型提供了強大的檔案分發政策。還有待探索的是,這種資料結構如何影響面向高吞吐量的檔案系統的設計,以及它如何更新Web本身。

本文介紹了IPFS,一種新穎的P2P版本控制檔案系統,旨在協調這些問題。IPFS綜合了許多過去成功系統的學習經驗。仔細的以界面為中心的內建産生的系統大于其各部分的總和。IPFS的核心原則是将所有資料模組化為同一Merkle DAG的一部分。

這篇文章介紹了IPFS,一個P2P版本控制檔案系統的新想法力圖解決這些問題。IPFS綜合學習了過去的一些成功的系統。基于接口緊密的內建産生的系統比各個部分的簡單相加更強大。IPFFS的中心原則是把所有資料改造成同一個Merkle DAG的一部分。

2. 背景 BACKGROUND

這章節回顧了構成IPFS的成功P2P系統的重要特性。

2.1 分布式哈希表 Distribution Hash Tables,DHT

DHTs廣泛适用于P2P系統的中繼資料的調整及維護。例如,BitTorrent MainlineDHT記錄了torrent swarm的節點集

2.1.1 Kademlia DHT

Kademlia是受歡迎的DHT,提供了:

1.在大網絡中高效查詢:查詢節點的平均效率log2(n).(例如,對于1000萬節點的網絡隻需要20跳)

2.低協調開銷:優化了發送給其他節點的控制資訊的數量

3.通過優選長期存在的節點來阻止大量攻擊

4.廣泛應用于P2P應用中,包括Guntella和BitTorrent,超過2000萬節點的組網。

2.1.2 Coral DSHT

雖然有些P2P檔案系統直接在DHTs中存儲資料塊,這個”浪費存儲和寬帶,因為原本并不需要的資料必須被存儲在節點上”。Coral DSHT通過三種特别重要的方式擴充了Kademlia:

1.Kademlia根據離key“最近”距離(使用XOR-distance)的節點ids中存儲資料,這沒有考慮應用資料的位置,忽略了擁有這些資料的“遠”節點,同時不管他們是否需要而強制“最近”節點來存儲。這浪費了有效存儲和寬帶。相反,Coral存儲能存儲這些資料塊的節點的位址。

2.Coral将DHT API從get_value(key)改成get_any_values(key)(DSHT中的“sloppy”)。Coral使用者僅需要一個正常運作的節點,而不需要整個清單。作為回報,Coral分發值的子集到“nearest”節點,避免熱點(當一個鍵值受歡迎時,使周邊所有nearest節點超負載)

3.還有,Coral依賴于區域和大小組成DSHTs的各個層級(稱為clusters)。這使節點優先在自己的區域内查詢節點,“查找臨近的資料,而不是查找距離節點”,這極大減少查找的延時。

2.1.3 S/Kademlia DHT

S/Kademlia為了阻止惡意攻擊擴充了Kademlia,在兩種特别重要的方面:

1.S/Kademlia提供了保護NodeID生成及阻止女巫攻擊的方案。要求節點産生PKI鍵值對,從中獲得辨別符,并且互相簽名。其中的一個方案POW提高了女巫攻擊的成本。

2.S/Kademlia節點通過獨立的路徑查詢值,就是為了確定誠實節點能夠在網絡中存在大量惡意節點時能夠互相連接配接。即使在一半惡意節點時,S/Kademlia也可以獲得85%的成功率。

2.2 塊交換Block Exchanges-BitTorrent

BitTorrent是一個相當成功的P2P檔案共享系統,成功的協調不信任節點(swarms)之間的網絡,互相合作分發檔案片段。從BitTorrent及其生态系統的關鍵特性中,ipfs得到的啟發包括:

1. BitTorrent的資料交換協定采用類似于tit-for-tat政策,獎勵互相貢獻的節點,懲罰那些隻擷取他人的節點的資源。

2. BitTorrent節點跟蹤檔案的可用性,優先發送最稀有的碎片。 這會減輕種子負擔,使非種子節點能夠互相交易。

3. BitTorrent的标準tit-for-tat相對容易受到一些強占帶寬共享政策的影響。PropShare是一種不同的對等帶寬配置設定政策,可以更好地抵制強占政策,并提高群體的性能。

2.3 版本控制系統 Version Control Systems-Git

版本控制系統提供了模型檔案的工具,可以随時間變化并有效地分發不同的版本。流行的版本控制系統Git提供了一個強大的Merkle DAG(Merkle Directed Acyclic Graph- 類似于但比MerkleTree更通用的結構。重複資料删除,不需要平衡,非葉節點包含資料。)對象模型,以分布式友好的方式捕獲檔案系統樹的變化。

1.不可變對象表示檔案(blob),目錄(tree)和更改(commit)。

2.對象通過其内容的hast加密方式進行内容尋址。

3.連結其他嵌入的對象,形成Merkle DAG。 這提供了許多有用的完整性和工作流屬性

4.大多數版本控制中繼資料(branches,tags等)隻是指針引用,是以建立和更新成本低廉。

5.版本更改僅更新引用或添加對象。

6.将版本更改分發給其他使用者隻是傳輸對象和更新遠端引用。

2.4 自證明檔案系統 Self-Certified Filesystems-SFS

SFS提出了兩個的引人注目的實作:(a)分布式信任鍊和(b)平等共享全局命名空間。SFS引入了一種建構SelfCertified Filesystems的技術:使用以下方案尋址遠端檔案系統

這裡的Location是伺服器網絡位址,同時

HostID = hash(public_key || Location)
           

是以,SFS檔案系統的名稱證明了他的伺服器。使用者可以驗證伺服器提供的公鑰,協商共享密鑰并保護所有流量。所有SFS執行個體共享一個全局命名空間,其中名稱配置設定是加密的,而不是任何集中式主體的把控。

3. IPFS設計

IPFS是一個分布式檔案系統,它綜合了以前的對等系統的成功思想,包括DHT,BitTorrent,Git和SFS。IPFS的貢獻在于将經過驗證的技術簡化,發展和整合到一個整體的系統中,大于其各部分的總和。IPFS提供了一個用于編寫和部署應用程式的新平台,以及一個用于分發和版本化大資料的新系統。 IPFS甚至可以改進網絡本身。

IPFS是點對點的; 沒有節點是特權。 IPFS節點将IPFS對象存儲在本地存儲中。節點間互相連接配接和轉移對象。 這些對象可以表示為檔案和其他資料結構。 IPFS協定分為一堆不同功能的子協定:

1.身份 - 管理節點身份生成和驗證。見3.1節。

2.網絡 - 管理與其他節點的連接配接,使用各種底層網絡協定。可配置。見3.2節。

3.路由 - 維護資訊以定位特定的節點和對象。響應本地和遠端查詢。預設為DHT,可替換。見3.3節。

4.交換 - 一種新的塊交換協定(BitSwap),用于管理有效的塊分發。模仿市場,弱激勵資料複制。交易政策可替換。在3.4節中描述。

5.對象 - 帶有連結的内容尋址不可變對象的MerkleDAG。用于表示任意資料結構,例如檔案層次結構和通信系統。在3.5節中描述。

6.檔案 - 受Git啟發的版本化檔案系統層次結構。見3.6節。

7.命名 - 自我認證的可變名稱系統。在3.7節中描述。

這些子系統不是獨立的;它們是內建的并融合的。盡管如此,從下到上建構協定棧,分别描述它們是有益的。

注意:下面的資料結構和函數在Go文法中指定。

3.1身份 Identities

節點通過NodeId來辨別,NodeId是公鑰的加密哈希,使用S/Kademlia的靜态加密拼圖建立。 節點存儲其公鑰和私鑰(使用密碼加密)。使用者可以在每次釋出時自由地設定“新”節點辨別,但是會丢失累積的網絡收益。 被激勵節點保持不變。
type NodeId Multihash
type Multihash []byte
// self-describing cryptographic hash digest
type PublicKey []byte
type PrivateKey []byte
// self-describing keys
type Node struct {
NodeId NodeID
PubKey PublicKey
PriKey PrivateKey
}
           

基于S/Kademlia方式産生的IPFS身份

difficulty = <integer parameter>
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)
           

第一次連接配接時,節點互相交換公鑰,并且校驗:hash(other.PublicKey)==other.NodeId.如果不是,連接配接終止。

關于加密函數的注意事項:

IPFS不是将系統鎖定到一組特定的函數選擇,而是支援自描述值。散列摘要值以multihash格式存儲,其中包括指定所使用的散列函數的短标頭和以位元組為機關的摘要長度。 例如:

這允許系統(a)為用例選擇最佳功能(例如,更強的安全性和更快的性能),以及(b)随着功能選擇的改變而發展。 自描述值允許相容地使用不同的參數選擇。

3.2 Network

IPFS節點與網絡中的數百個其他節點定期通信,可能跨越廣泛的網際網路。 IPFS網絡堆棧功能:

•傳輸:IPFS可以使用任何傳輸協定,最适合WebRTC資料通道[?](用于浏覽器連接配接)或uTP(LEDBAT [14])。

•可靠性:如果底層網絡不提供IPFS,IPFS可以使用uTP(LEDBAT [14])或SCTP [15]提供可靠性。

•連接配接性:IPFS還使用ICE NAT周遊技術[13]。

•完整性:可選擇使用哈希校驗和檢查消息的完整性。

•真實性:可選擇使用帶有發件人公鑰的HMAC檢查郵件的真實性。

3.2.1 節點尋址注意事項

IPFS可以使用任何網絡; 它不依賴或假設通路IP。這允許IPFS用于覆寫網絡。IPFS将位址存儲為multiaddr的位元組字元串,供底層網絡使用。 multiaddr提供了一種表達位址及其協定的方法,包括對封裝的支援。 例如:
# an SCTP/IPv4 connection
/ip4//sctp//
# an SCTP/IPv4 connection proxied over TCP/IPv4
/ip4//tcp//ip4//sctp//
           

3.3 Routing

IPFS節點需要路由系統,該路由系統可以找到(a)其他Peer的網絡位址,以及(b)可以為特定對象提供服務的Peer。 IPFS使用基于S/Kademlia和Coral的DSHT,2.1中讨論了這個。對象的大小和IPFS的使用模式類似于Coral和Mainline 是以IPFS DHT根據它們的大小對存儲的值進行區分。對于值小(等于或小于1KB)的情況直接存儲在DHT上。對于更大的值,DHT存儲引用,它們是可以提供塊服務的對等體的NodeId。

此DSHT的接口如下:

type IPFSRouting interface {
FindPeer(node NodeId)
// gets a particular peer’s network address
SetValue(key []bytes, value []bytes)
// stores a small metadata value in DHT
GetValue(key []bytes)
// retrieves small metadata value from DHT
ProvideValue(key Multihash)
// announces this node can serve a large value
FindValuePeers(key Multihash, min int)
// gets a number of peers serving a large value
}
           
注意:不同的用例将要求實質上不同的路由系統(例如,寬網絡中的DHT,本地網絡中的靜态HT)。 是以,可以交換IPFS路由系統以滿足使用者的需求。 隻要滿足上面的接口,系統的其餘部分将繼續運作。

3.4 區塊交換-BitSwap Protocol

在IPFS中,通過使用BitTorrent啟發的協定:BitSwap,與peers交換塊來進行資料分發。與BitTorrent一樣,BitSwap節點正在尋求獲得一組塊(want_list),并在交換中提供另一組塊(have_list)。與BitTorrent不同,BitSwap不僅限于一個torrent中的塊。BitSwap作為一個持久的市場運作,節點可以擷取所需的塊,無論這些塊是哪些檔案的一部分。 這些塊可能來自檔案系統中完全不相關的檔案。 節點聚集在一起交易市場。

雖然交易系統的概念意味着可以建立虛拟貨币,但這需要全球分類賬來跟蹤貨币的所有權和轉移。這可以作為BitSwap政策實作,并将在未來的論文中進行探讨。

在基本情況下,BitSwap節點必須以塊的形式互相提供直接值。當跨節點的塊分布是互補的時,也就是說它們具有對方想要的内容,這非常有效。通常情況并非如此。在某些情況下,節點必須适用于其塊。如果一個節點沒有其peer想要的東西(或根本沒有),它會尋找其peer想要的部分,其優先級低于節點自己想要的優先級。這激勵節點緩存和傳播稀有部分,即使他們不直接對它們感興趣。

3.4.1 BitSwap Credit

協定還必須激勵節點在不需要任何特定内容時做種子,因為它們可能有其他節點所需的塊。是以,BitSwap節點積極地向其Peer發送塊,期望償還債務。 但必須防範水蛭(永不共享的免費加載節點)。 一個簡單的信用類系統解決了這個問題:

1.Peers跟蹤其他節點的收支(以位元組驗證)。

2.根據債務增加而下降的函數,peer在機率上向債務peer發送區塊。

請注意,如果節點決定不發送給對等方,則該節點随後會忽略該Peer以擷取ignore_cooldown逾時。這可以防止發件人通過引起更多的骰子來嘗試遊戲機率。 (預設BitSwap為10秒)。

3.4.2 BitSwap Strategy

BitSwap Peers可能采用的不同政策會對整個交易所的表現産生了截然不同的影響。在BitTorrent中,雖然指定了标準政策(tit-for-tat),但也已經實施了各種其他政策,從BitTyrant(共享最不可能),到BitThief(利用漏洞,永不分享),到PropShare(按比例分享)。 BitSwap Peers可以類似地實施一系列政策(良好和惡意)。 那麼,功能的選擇應該旨在:

1.最大化節點和整個交易所的交易表現

2.阻止貪圖者利用和降低交換

3.對其他未知政策有效并具有抵抗力

4.對受信任的peers寬容

對這些戰略空間的探索是未來的工作。 在實踐中起作用的一個功能選擇是一個sigmoid,由債務比例縮放:

讓節點與其對等體之間的負債比率為:

r = bytes_sent/(bytes_recv + )

//給定r,讓發送給債務人的機率為:
P(send|r) =  − /( + exp1( − r))
           

正如您在圖1中所看到的,當節點的負債率超過既定信用額度的兩倍時,此功能會迅速下降。

debt ratio是衡量信任度的名額:對先前已成功交換大量資料的節點之間的債務寬容,對未知的不可信節點無情。 這(a)提供了對建立大量新節點(sybill攻擊)的攻擊者的抵抗,(b)保護以前成功的交換關系,即使其中一個節點暫時無法提供價值,以及(c)最終關閉已經惡化關系,直到他們改善。

3.4.3 BitSwap Ledger

BitSwap節點使分類賬記錄與其他節點的轉賬。這允許節點跟蹤曆史記錄并避免篡改。激活連接配接時,BitSwap節點會交換其分類帳資訊。 如果它不完全比對,則從破壞或丢失的信用或債務開始重新初始化分類帳。惡意節點有可能故意丢失分類賬本,進而達到消除債務的目的。節點不太可能産生足夠的債務以保證也會失去應計信任;但是合作夥伴節點可以自由地将其視為不當行為,并且拒絕交易。
type Ledger struct {
owner NodeId
partner NodeId
bytes_sent int
bytes_recv int
timestamp Timestamp
}
           

節點可以自由保留分類帳曆史記錄,但不是必須的正确操作。隻有目前分類帳條目才有用。節點也可以根據需要随意收集分類賬,從較不實用的分類賬開始:舊的(peers可能不再存在)和小。

3.4.4 BitSwap Specification

BitSwap節點遵循一個簡單協定
// Additional state kept
type BitSwap struct {
ledgers map[NodeId]Ledger
// Ledgers known to this node, inc inactive
active map[NodeId]Peer
// currently open connections to other nodes
need_list []Multihash
// checksums of blocks this node needs
have_list []Multihash
// checksums of blocks this node has
}
type Peer struct {
nodeid NodeId
ledger Ledger
// Ledger between the node and this peer
last_seen Timestamp
// timestamp of last received message
want_list []Multihash
// checksums of all blocks wanted by peer
// includes blocks wanted by peer’s peers
}
// Protocol interface:
interface Peer {
open (nodeid :NodeId, ledger :Ledger);
send_want_list (want_list :WantList);
send_block (block :Block) -> (complete :Bool);
close (final :Bool);
}
           

節點連接配接的全生命周期架構:

1.Open: 達成一緻後,Peers發送Ledgers

2.Sending:peers 交換want_lists 和Blocks

3.Close:Peers關閉連接配接

4.Ignored:(特别的)如果一個節點的政策是避免發送,該Peer被忽略(在逾時周期内)

Peer.open(NodeId, Ledger)
           

當連接配接時,節點使用Ledger初始化連接配接,該Ledger可以是從過去的連接配接存儲的,也可以是新的連接配接。 然後,将帶有Ledger的Open消息發送給Peer。

收到Open消息後,Peer選擇是否激活連接配接。如果根據接收方的Ledger,發送方不是可信代理(傳輸低于零,或大量未償還債務),接收方可以選擇忽略該請求。這應該通過ignore_cooldown逾時以機率方式完成,以便糾正錯誤并阻止攻擊者。 如果激活連接配接,接收器将使用本地版本的Ledger初始化Peer對象并設定last_seen時間戳。然後,它将收到的Ledger與自己的Ledger進行比較。如果它們完全比對,則連接配接已打開。如果它們不比對,則對等方建立一個新的歸零分類帳并發送它。

Peer.send_want_list(WantList)
           

當連接配接打開時,節點廣播他們的want_list到所有連接配接的peers。完成這部分工作必須滿足(a)打開連接配接,(b)在一個随機周期逾時後,(c)在want_list發生改變,以及(d)在接收到一個新區塊後。

在接收到want_list後,節點做好存儲。然後校驗是否存在想要的區塊。如果有,依據BitSwap Strategy發送出去。

Peer.send_block(Block)
           
發送塊很簡單。 節點隻是傳輸資料塊。在接收到所有資料後,接收器計算Multihash校驗和以驗證它是否與預期資料比對,并傳回确認。在完成正确傳輸塊之後,接收器将塊從need_list移動到have_list,并且接收方和發送方都更新其分類賬以反映傳輸的附加位元組。 如果傳輸驗證失敗,則發送方發生故障或攻擊接收方。接收方可以自由拒絕進一步的交易。請注意, BitSwap期望在可靠的傳輸通道上運作,是以傳輸錯誤–這可能會導緻對誠實發件人的錯誤處罰–預計會在将資料提供給BitSwap之前被捕獲.
Peer.close(Bool)
           

close的最後參數表明拆除連接配接的意圖是否是發送者。如果為false,接收方可以選擇立即重新打開連接配接。這避免了過早關閉。應在兩種情況下關閉對等連接配接:

•silence_wait逾時已過期,但未收到來自對等方的任何消息(預設BitSwap使用30秒)。該節點發出Peer.close(false)。

•節點正在退出,BitSwap正在關閉。在這種情況下,節點發出Peer.close(true)。

收到消息後,收件人和發件人都會拆除連接配接,清除存儲的任何狀态。如果有用的話,可以存儲Ledger以供将來使用。

注意事項:

•應忽略非活動連接配接上的Non-open消息。在send_block消息的情況下,接收器可以檢查塊以檢視是否所需并且正确,如果是這樣,請使用它。無論如何,所有這些無序消息都會觸發來自接收器的close(flase)消息以強制重新初始化連接配接。

Object Merkle DAG

DHT和BitSwap允許IPFS形成一個龐大的P2P系統,用于快速、穩健地存儲和分發區塊。 除此之外,IPFS還建構了一個MerkleDAG,一個有向無環圖,其中對象之間的連結是嵌入源中的目标的加密哈希。這是Git資料結構的概括。 MerkleDAGs為IPFS提供了許多有用的屬性,包括:

1.内容尋址:所有内容由其多哈校驗的唯一辨別,包括連結。

2.防篡改:所有内容都通過校驗和進行驗證。 如果資料被篡改或損壞,IPFS會檢測到它。

3.重複資料删除:包含完全相同内容的所有對象都相同,并且隻存儲一次。這對于索引對象(例如gittrees和commits)或資料的公共部分特别有用。

IPFS對象格式是:

type IPFSLink struct {
Name string
// name or alias of this link
Hash Multihash
// cryptographic hash of target
Size int
// total size of target
}
type IPFSObject struct {
links []IPFSLink
// array of links
data []byte
// opaque content data
}
           

IPFS Merkle DAG是一種非常靈活的資料存儲方式。唯一的要求是對象引用是(a)内容尋址,(b)以上述格式編碼。 IPFS授予應用程式對資料字段的完全控制權;應用程式可以使用他們選擇的任何自定義資料格式,IPFS可能無法了解。單獨的對象内連結表允許IPFS:

·在對象中列出所有對象引用,例如:

> ipfs ls /XLZ1625Jjn7SubMDgEyeaynFuR84ginqvzb
XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x 189458 less
XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5 19441 script
XLF4hwVHsVuZ78FZK6fozf8Jj9WEURMbCX4 5286 template

<object multihash> <object size> <link name>
           

·解析查找字元串路徑,例如foo/bar/baz。給定一個對象,IPFS将第一個路徑元件解析為對象連結表中的哈希,擷取第二個對象,并使用下一個元件重複上述操作。是以,無論資料格式是什麼,字元串路徑都可以周遊Merkle DAG。

·解析遞歸引用的所有對象:

> ipfs refs --recursive \
/XLZ1625Jjn7SubMDgEyeaynFuR84ginqvzb
XLLxhdgJcXzLbtsLRL1twCHA2NrURp4H38s
XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x
XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5
XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z
...
           
原始資料字段和公共連結結構是在IPFS之上構造任意資料結構的必要元件。雖然很容易看出Git對象模型如何适合這個DAG,但請考慮以下其他潛在的資料結構:(a)鍵值存儲(b)傳統關系資料庫(c)Linked Data triple storesLinked Data triple stores(d)連結文檔釋出系統linked document publishing systems(e)連結通信平台(f)加密貨币區塊鍊。 這些都可以在IPFS Merkle DAG之上模組化,它允許任何這些系統使用IPFS作為更複雜應用程式的傳輸協定。

3.5.1 Paths

可以使用字元串路徑API周遊IPFS對象。路徑可以像在傳統UNIX檔案系統和Web中一樣工作。 Merkle DAG連結使其易于周遊。 請注意,IPFS中的完整路徑具有以下形式:
# format
/ipfs/<hash-of-object>/<name-path-to-object>
# example
/ipfs/XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x/foo.txt
           
/ipfs字首允許在标準安裝點安裝到現有系統而不會發生沖突(安裝點名稱當然是可配置的)。 第二個路徑元件(首先在IPFS中)是對象的哈希。情況總是如此,因為沒有全局根。根對象有個不可能的任務:将處理分布式(并且可能是斷開連接配接的)環境中的數百萬個對象的一緻性的。相反,我們使用内容尋址來模拟根。 所有對象始終可以通過哈希通路。 注意這意味着在路徑/bar/baz中給出三個對象,所有人都可以通路最後一個對象:
/ipfs/<hash-of-foo>/bar/baz
/ipfs/<hash-of-bar>/baz
/ipfs/<hash-of-baz>
           

3.5.2 本地對象Local Objects

IPFS用戶端需要一些本地存儲和一個外部系統,用于存儲和檢索IPFS管理的對象的本地原始資料。存儲類型取決于節點的用例。在大多數情況下,這隻是磁盤空間的一部分(由本機檔案系統管理,由kv存儲系統,如leveldb,或直接由IPFS用戶端管理)。在其他情況下,例如非持久性緩存,此存儲隻是RAM的一部分。

最終,IPFS中可用的所有塊都在某個節點的本地存儲中。當使用者請求對象時,至少可以臨時找到,下載下傳和存儲它們。 這為此後的一些可配置時間提供了快速查找。

3.5.3 對象固定 Object Pinning

希望確定特定對象生存的節點可以通過固定對象來實作。 這可確定對象保留在節點的本地存儲中。 固定可以遞歸完成,也可以固定所有連結的後代對象。 然後指向的所有對象都存儲在本地。 這對于儲存檔案(包括引用)特别有用。這也使IPFS成為一個永久連結的Web,而對象可以確定他們指向的其他對象是存在的。

3.5.4 釋出對象 Publishing Objects

IPFS是全球分布的。 它旨在允許數百萬使用者的檔案一起共存。具有内容哈希尋址的DHT允許以公平,安全和完全分布的方式釋出對象。 任何人都可以通過簡單地将其鍵添加到DHT,把自己加入到Peers,并向其他使用者提供對象的路徑來釋出對象。 請注意,對象本質上是不可變的,就像在Git中一樣。新版本的哈希值不同,是以是新對象。 跟蹤版本是其他版本控制對象的工作。

3.5.5 Object-level Cryptography

IPFS可以處理對象級加密操作。加密或簽名的對象包裝在一個特殊的幀中,允許加密或驗證原始位元組。
type EncryptedObject struct {
Object []bytes
// raw object data encrypted
Tag []bytes
// optional tag for encryption groups
}
type SignedObject struct {
Object []bytes
// raw object data signed
Signature []bytes
// hmac signature
PublicKey []multihash
// multihash identifying key
}
           
加密操作會更改對象的哈希值,進而定義不同的對象。IPFS自動驗證簽名,并可以使用使用者指定的密鑰鍊解密資料。 加密對象的連結也受到保護,沒有解密密鑰就無法進行周遊。可以在一個密鑰下加密父對象,子對象在另一個密鑰下加密或不加密。這可以確定連結共享對象的安全。

3.6 Files

IPFS還定義了一組對象,用于在MerkleDAG之上對版本化檔案系統進行模組化。這個對象模型類似于Git:

1. block:可變大小的資料塊。

2. list:塊或其他清單的集合。

3. tree:區塊,清單或其他樹的集合。

4. commit:某棵樹的版本曆史中的快照。

我希望完全使用Git對象格式,但不得不離開以介紹在分布式檔案系統中有用的某些功能,即(a)快速查找大小(對象中添加了聚合位元組大小),(b)大檔案重複資料删除(添加清單對象),以及(c)将commits嵌入到樹中。盡管如此,IPFS檔案對象與Git足夠相似,可以實作兩者之間的轉換。此外,可以引入轉換一組Git對象而不會丢失任何資訊(unix檔案權限等)。

注意:下面的檔案對象格式使用JSON。請注意,雖然ipfs包含導入/導出到JSON,但此結構實際上是使用protobufs進行二進制編碼,

3.6.1 File Object: blob

blob對象包含可尋址的資料單元,并使用檔案表示。 IPFS塊類似于Git blob或檔案系統資料塊。它們存儲使用者的資料。 請注意,IPFS檔案可以由lists和blobs表示。 Blob沒有連結。
{
"data": "some data here",
// blobs have no links
}
           

3.6.2 File Object: list

list對象表示由多個IPFS blob組成的大型或去重檔案。 清單包含有序的blob或清單對象序列。

從某種意義上說,IPFS清單的功能類似于帶有間接塊的檔案系統檔案。由于清單可以包含其他清單,是以可以使用包括連結清單和平衡樹的拓撲。同一節點出現在多個位置的定向圖允許檔案内部去重。 當然,循環是不可能的,因為哈希尋址強制執行。

{
"data": ["blob", "list", "blob"],
// lists have an array of object types as data
"links": [
{ "hash": "XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x",
"size":  },
{ "hash": "XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5",
"size":  },
{ "hash": "XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z",
"size":  }
// lists have no names in links
]
}
           

3.6.3 File Object: tree

IPFS中的tree對象類似于Git中的tree對象:它表示一個目錄,一個哈希名稱的映射。哈希引用blobs,lists,其他trees或commits。 請注意,Merkle DAG已經實作了傳統路徑命名。
{
"data": ["blob", "list", "blob"],
// trees have an array of object types as data
"links": [
{ "hash": "XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x",
"name": "less", "size":  },
{ "hash": "XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5",
"name": "script", "size":  },
{ "hash": "XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z",
"name": "template", "size":  }
// trees do have names
]
}
           

3.6.4 File Object: commit

IPFS中的commit對象表示任何對象的版本曆史的快照。 它類似于Git,但可以指向任何類型的對象。 它還連結到作者對象。
{
"data": {
"type": "tree",
"date": "2014-09-20 12:44:06Z",
"message": "This is a commit message."
},
"links": [
{ "hash": "XLa1qMBKiSEEDhojb9FFZ4tEvLf7FEQdhdU",
"name": "parent", "size":  },
{ "hash": "XLGw74KAy9junbh28x7ccWov9inu1Vo7pnX",
"name": "object", "size":  },
{ "hash": "XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm",
"name": "author", "size":  }
]
}
           

3.6.5 Version control

commit對象表示一個對象的版本曆史的特定快照。兩個不同commit的對象(和子對象)的對比,透露了檔案系統的兩個版本之間的差異。隻要單個commit和它引用的所有子對象可以通路,就可以檢索所有先前版本,并且可以浏覽檔案系統變更的完整曆史記錄。這不屬于MerkleDAG對象模型。IPFS使用者可以使用Git版本控制工具的全部功能。 對象模型相容,但不相同。可以(a)建構一個修改過的Git工具版本以适用于IPFS對象圖,(b)建構一個挂載的FUSE檔案系統,将IPFS樹挂載為Git倉庫,将Git檔案系統讀/寫轉換為IPFS格式。

3.6.6 Filesystem Paths

正如我們在Merkle DAG部分中看到的那樣,可以使用字元串路徑API周遊IPFS對象。IPFS檔案對象的設計使IPFS挂載在UNIX檔案系統上更簡單。為了将tree表示為目錄,tree下沒有資料。并且commits可以表示為目錄,也可以完全隐藏在檔案系統中。

3.6.7 Splitting Files into Lists and Blob

版本控制和分發大型檔案的主要挑戰之一是找到将它們拆分為獨立塊的正确方法。IPFS提供以下備選方案,而不是假設它可以适用每一種類型的檔案:

(a)在LBFS中使用Rabin指紋來選擇合适的塊邊界。

(b)使用rsync滾動校驗和算法來檢測版本之間已更改的塊。

(c)允許使用者針對特定檔案自定義塊分割函數。

3.6.8 Path Lookup Performance

基于路徑通路來周遊對象圖。檢索某個對象需要先在DHT中查找key,連接配接到peer及诶單并檢索其塊。 這是相當大的開銷,特别是在查找包含許多元件的路徑時。 這可以通過以下方式減輕:

•tree caching:由于所有對象都是散列尋址的,是以可以無限期地緩存它們。此外,tree往往很小,是以IPFS優先考慮将它們緩存在blob上。

•flattened tree:對于任何給定的tree,可以構造一個特殊的flattenedTree來列出從樹可到達的所有對象。 flattened tree中的命名實際上是從原始樹分開的帶有斜杠的。

Figure 2-Sample Object Graph

IPFS(DRAFT 3) 中文版白皮書IPFS - Content Addressed, Versioned, P2P File System(DRAFT 3)
Figure : Sample Objects

> ipfs file-cat <ccc111-hash> --json
{
"data": {
"type": "tree",
"date": "2014-09-20 12:44:06Z",
"message": "This is a commit message."
},
"links": [
{ "hash": "<ccc000-hash>",
"name": "parent", "size":  },
{ "hash": "<ttt111-hash>",
"name": "object", "size":  },
{ "hash": "<aaa111-hash>",
"name": "author", "size":  }
]
}
> ipfs file-cat <ttt111-hash> --json
{
"data": ["tree", "tree", "blob"],
"links": [
{ "hash": "<ttt222-hash>",
"name": "ttt222-name", "size":  },
{ "hash": "<ttt333-hash>",
"name": "ttt333-name", "size":  },
{ "hash": "<bbb222-hash>",
"name": "bbb222-name", "size":  }
]
}
> ipfs file-cat <bbb222-hash> --json
{
"data": "blob222 data",
"links": []
}
           
例如,上面的ttt111用flattened tree可以表示為:
{
"data":
["tree", "blob", "tree", "list", "blob" "blob"],
"links": [
{ "hash": "<ttt222-hash>", "size": 
"name": "ttt222-name" },
{ "hash": "<bbb111-hash>", "size": ,
"name": "ttt222-name/bbb111-name" },
{ "hash": "<ttt333-hash>", "size": ,
"name": "ttt333-name" },
{ "hash": "<lll111-hash>", "size": ,
"name": "ttt333-name/lll111-name"},
{ "hash": "<bbb222-hash>", "size": ,
"name": "ttt333-name/lll111-name/bbb222-name" },
{ "hash": "<bbb222-hash>", "size": 
"name": "bbb222-name" }
] }
           

3.7 IPNS: Naming and Mutable State

到目前為止,IPFS堆棧形成了p2p塊交換,建構了内容尋址的對象DAG。它用于釋出和檢索不可變對象。 它甚至可以跟蹤這些對象的版本曆史記錄。但是,缺少一個關鍵元件:可變命名。沒有它,新内容的所有通信必須在外帶發送IPFS連結。 需要的是在同一路徑上檢索可變狀态的某種方法。 值得說明的原因(如果最終需要可變資料),我們努力建立一個不可變的Merkle DAG。 考慮從Merkle DAG中放棄IPFS的屬性:對象可以(a)通過其哈希檢索,(b)檢查完整性,(c)連結到其他人,以及(d)無限緩存。

在某種意義上:Objects are permanent

這些是高性能分布式系統的關鍵屬性,其中資料在網絡鍊路上移動的成本很高。對象内容尋址通過以下方式建構Web:(a)顯着的帶寬優化,(b)不可信内容服務,(c)永久連結,以及(d)對任何對象及其引用進行完全永久備份的能力。

Merkle DAG,不可變的内容尋址對象,以及Naming,指向MerkleDAG的可變指針,采用了在許多成功的分布式系統中使用的二分法。 這些包括Git版本控制系統,其不可變對象和可變引用; 和Plan9[?],UNIX的分布式繼承者,具有可變的Fossil [?]和不可變的Venti [?]檔案系統。 LBFS [?]也使用可變索引和不可變塊。

3.7.1 Self-Certified Names

使用SFS的命名方案[12,11]為我們提供了一種在密碼學全局命名空間中構造可自變的自認證名稱的方法。 IPFS的方案如下:

1.回想一下IPFS中:NodeId = hash(node.PubKey)

2.我們配置設定每一個使用者一個可變命名空間:/ipns/

3.使用者可以将對象釋出到此路徑,并用私鑰簽名,比如說:

/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/

4.當其他使用者檢索對象時,他們可以檢查簽名是否與公鑰和NodeId比對。這驗證了使用者釋出的Object的真實性,實作了可變的狀态回溯。

請注意以下細節:

•ipns(InterPlanetary NameSpace)單獨的字首是為程式和人類讀者建立一個易于識别的可變和不可變路徑之間的差別。

•因為這不是内容尋址對象,是以釋出它依賴于IPFS中唯一可變的狀态分發系統,即路由系統。 該過程是(1)将對象釋出為正常不可變IPFS對象,(2)在路由系統上将其散列作為中繼資料值釋出:

routing.setValue(NodeId, )

•釋出的Object中的任何連結都充當命名空間中的子名稱:

/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/

/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs

/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs/ipfs

•建議釋出commit對象或具有版本曆史記錄的其他對象,以便用戶端可以找到舊名稱。這留給了使用者選項(并不強制)。

請注意,當使用者釋出此Object時,無法以相同的方式再釋出它

3.7.2 Human Friendly Names

雖然IPNS确實是一種配置設定和重新配置設定名稱的方式,但它不是非常使用者友好,因為它将長哈希值暴露為名稱,這是衆所周知難以記住的。 這些适用于URL,但不适用于多種離線傳輸。 是以,IPFS通過以下技術提高了IPNS的使用者友好性。

Peer Links

在SFS的鼓勵下,使用者可以将其他使用者的對象直接連結到他們自己的對象(命名空間,首頁等)。這樣做的好處是還可以建立信任網(并支援舊的證書頒發機構模型):

# Alice links to bob Bob
ipfs link /<alice-pk-hash>/friends/bob /<bob-pk-hash>
# Eve links to Alice
ipfs link /<eve-pk-hash/friends/alice /<alice-pk-hash>
# Eve also has access to Bob
/<eve-pk-hash/friends/alice/friends/bob
# access Verisign certified domains
/<verisign-pk-hash>/foo.com
           

DNS TXT IPNS Records.

如果/ipns/是一個有效的域名,IPFS在DNS TXT記錄表中查找Key的ipns。IPFS将該值解釋為對象哈希或另一個IPNS路徑:

# this DNS TXT record
ipfs.benet.ai. TXT "ipfs=XLF2ipQ4jD3U ..."
# behaves as symlink
ln -s /ipns/XLF2ipQ4jD3U /ipns/fs.benet.ai
           

Proquint可發音辨別符 Proquint Pronounceable Identifiers

一直有将二進制編碼成可發音單詞的方案。 IPNS支援Proquint [?]。 進而:

# this proquint phrase
/ipns/dahih-dolij-sozuk-vosah-luvar-fuluh
# will resolve to corresponding
/ipns/KhAwNprxYVxKqpDZ
           

名稱縮短服務。Name Shortening Services.

必然會出現提供名稱縮短服務,為使用者提供名稱空間。 這類似于我們今天看到的DNS和Web URL:

# User can get a link from
/ipns/shorten.er/foobar
# To her own namespace
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm
           

3.8 Using IPFS

IPFS旨在以多種不同方式使用。 以下是我将要介紹的一些用例:

1.作為已挂載的全局檔案系統,在/ipfs和/ipns下。

2.作為已安裝的個人同步檔案夾,可自動釋出,釋出和備份任何寫入。

3.作為加密檔案或資料共享系統。

4.作為所有軟體的版本化軟體包管理器。

5.作為虛拟機的根檔案系統。

6.作為VM的引導檔案系統(在管理程式下)。

7.作為資料庫:應用程式可以直接寫入MerkleDAG資料模型,并獲得IPFS提供的所有版本控制,緩存和分發。

8.作為連結(和加密)通信平台。

9.作為完整性檢查CDN的大檔案(沒有SSL)。

10.作為加密的CDN。

11.在網頁上,作為網絡CDN。

12.作為一個新的永久網絡,連結不會消失。

IPFS實作目标:

(a)在您自己的應用程式中導入的IPFS庫。

(b)直接操縱對象的指令行工具。

(c)使用FUSE [?]或作為核心子產品安裝的檔案系統。

4. 将來 THE FUTURE

IPFS背後的思想是學術界和開源領域數十年成功的分布式系統研究的産物。IPFS綜合了迄今為止最成功系統中的許多最佳創意。 除了BitSwap這是一種新穎的協定之外,IPFS的主要貢獻在于系統的耦合和設計的綜合。

IPFS是對新的分散式網際網路基礎設施的雄心勃勃的願景,可以在其上建構許多不同類型的應用程式。 至少,它可以用作全局,已安裝,版本化的檔案系統和命名空間,或者用作下一代檔案共享系統。 在最好的情況下,它可以将網絡推向新的視野,在那裡釋出有價值的資訊并不會将其托管在釋出者身上,而是在那些感興趣的人身上,使用者可以信任他們收到的内容而不信任他們從中收到的Peers,以及舊的 但重要的檔案不會丢失。 期待IPFS将我們帶入永恒網絡。

借助google翻譯加自己了解做了調整,個人在有道筆記上做記錄,現分享出來,有翻譯或了解不準确的,可以一起交流

http://note.youdao.com/noteshare?id=c21f3c58a286fa1d8429a6cb6ee09821&sub=EE1C5448B7DC4622B2B93E98D19EB1B3

繼續閱讀