2017-05-28node
做者: Juan Benet (juan@benet.ai)
譯者: 郭光華(gavin@8btc.com),https://gguoss.github.io/2017/05/28/ipfs/git
星際文件系統是一種點對點的分佈式文件系統, 旨在鏈接全部有相同的文件系統的計算機設備。在某些方面, IPFS相似於web, 但web 是中心化的,而IPFS是一個單一的Bittorrent 羣集, 用git 倉庫分佈式存儲。換句話說, IPFS 提供了高吞吐量的內容尋址塊存儲模型, 具備內容尋址的超連接。這造成了一個廣義的Merkle DAG 數據結構,能夠用這個數據結構構建版本文件系統,區塊鏈,甚至是永久性網站。。IPFS 結合了分佈式哈希表, 帶有激勵機制的塊交換和自我認證命名空間。IPFS 沒有單故障點, 節點不須要相互信任。github
在全球分佈式文件系統這領域, 已經有許多人的嘗試。一些系統已經取得了重大的成功, 而不少卻徹底失敗了。在學術嘗試中, AFS【6】就是成功的例子,現在已經獲得普遍的應用, 然而,其餘的【7, ?】卻沒有獲得相同的結果。在學術界以外,應用最普遍的是面向音視頻媒體的點對點文件共享系統。 最值得注意的是, Napster, KaZaA 和BitTorrent[2]部署的文件分發系統支持1億用戶的同時在線。即便在今天, BitTorrent 也維持着天天千萬節點的活躍數。 基於這些學術文件系統理論而實現的應用程序有不少的用戶量, 然而,這些系統理論是在應用層,而沒有放在基礎層。以至沒有出現通用的文件系統基礎框架, 給全球提供低延遲的分發。
也許是由於HTTP這樣「足夠好「的系統已經存在。到目前爲止,HTTP已經做爲「分佈式文件系統「的協議,而且已經大量部署,再與瀏覽器相結合,具備巨大的技術和社會影響力。在如今, 它已經成爲互聯網傳輸文件的事實標準。然而,他沒有采用最近15年的發明的數十種先進的文件分發技術。 從一方面講, 因爲向後兼容的限制 和 當前新模式的投入, 不斷髮展http web 的基礎設施幾乎是不可能的。但從一個角度看, 從http 出現以來, 已經有許多新協議出現並被普遍使用。升級http協議雖然能引入新功能和增強當前http協議,但會下降用戶的體驗。
有些行業已經擺脫使用HTTP 這麼久, 由於移動小文件相對便宜,即便對擁有大流量的小組織也是如此。可是,隨着新的挑戰,咱們正在進入數據分發的新紀元。web
因爲關鍵功能和帶寬問題,咱們已經爲不一樣的數據放棄了HTTP 分銷協議。下一步是使它們成爲web本身的一部分。正交於有效的數據分發,版本控制系統,已經設法開發重要的數據協做工做流程。算法
Git是分佈式源代碼版本控制系統,開發了許多有用的方法來建模和實現分佈式數據操做。Git工具鏈提供了靈活的版本控制功能,這正是大量的文件分發系統所嚴重缺少的。由Git啓發的新解決方案正在出現,如Camlistore [?],我的文件存儲系統,Dat [?]數據協做工具鏈和數據集包管理器。Git已經影響了分佈式文件系統設計[9],由於其內容涉及到Merkle DAG數據模型,可以實現強大的文件分發策略。還有待探討的是,這種數據結構如何影響面向高吞吐量的文件系統的設計,以及如何升級Web自己。
本文介紹了IPFS,一種新穎的對等版本控制的文件系統,旨在調和這些問題。 IPFS綜合了許多之前成功的系統的優勢。 IPFS產生了突出的效果, 甚至比參考的這些系統的總和還要好。IPFS的核心原則是將全部數據建模爲同一Merkle DAG的一部分。數據庫
本節回顧了IPFS所採用成功的點對點系統技術的重要屬性。數組
分佈式散列表(DHT)被普遍用於協調和維護關於對等系統的元數據。好比,MainlineDHT 是一個去中心化哈希表,他可追蹤查找全部的對等節點。瀏覽器
Kademlia[10] 是受歡迎的DHT, 它提供:緩存
雖然一些對等文件系統直接在DHT中存儲數據塊,這種「數據存儲在不須要的節點會亂費存儲和帶寬」[5]。Coral DSHT擴展了Kademlia三個特別重要的方式:安全
6.分佈式版本改變對其餘用戶而言只是轉移對象和更新遠程引用。
SFS [ 12,11 ]提出了兩個引人注目的實現(a)分佈式信任鏈,和(b)平等共享的全局命名空間。SFS引入了一種自我建構技術—註冊文件:尋址遠程文件系統使用如下格式:
1 2 3 |
/sfs/<Location>:<HostID> Location:表明的是服務網絡地方 HostID = hash(public_key || Location) |
所以SFS文件系統的名字認證了它的服務,用戶能夠經過服務提供的公鑰來驗證,協商一個共享的私鑰,保證全部的通訊。全部的SFS實例都共享了一個全局的命名空間,這個命名空間的名稱分配是加密的,不被任何中心化的body控制。
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.對象 - 具備連接的內容尋址不可更改對象的Merkle DAG。用於表示任意數據結構,例如文件層次和通訊系統。詳見第3.5節。
6.文件 - 由Git啓發的版本化文件系統層次結構。詳見3.6節。
7.命名 - 自我認證的可變名稱系統。詳見3.7節。
這些子系統不是獨立的;它們是集成在一塊兒,互相利用各自的屬性。可是,分開描述它們是有用的,從下到上構建協議棧。符號:Go語言中指定了如下數據結構和功能
節點由NodeId標識,這是使用S / Kademlia的靜態加密難題[1]建立的公鑰的密碼散列。節點存儲其公私鑰(用密碼加密)。用戶能夠在每次啓動時自由地設置一個「新」節點身份,儘管這會損失積累的網絡利益。激勵節點保持不變。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
type NodeId Multihash type Multihash []byte // 自描述加密哈希摘要 type PublicKey []byte type PrivateKey []byte // 自描述的私鑰 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不是將系統鎖定到一組特定的功能選擇,而是支持自我描述的值。哈希摘要值以多重哈希格式存儲,其包括指定使用的哈希函數的頭和以字節爲單位的摘要長度。例如:
1 |
<function code><digest length><digest bytes> |
這容許系統
1 2 3 4 |
# an SCTP/IPv4 connection /ip4/10.20.30.40/sctp/1234/ # an SCTP/IPv4 connection proxied over TCP/IPv4 /ip4/5.6.7.8/tcp/5678/ip4/1.2.3.4/sctp/1234/ |
IPFS節點須要一個路由系統, 這個路由系統可用於查找:
1 2 3 4 5 6 7 |
type IPFSRouting interface { FindPeer(node NodeId) // 獲取特定NodeId的網絡地址。 SetValue(key []bytes, value []bytes) // 往DHT存儲一個小的元數據。 GetValue(key []bytes) // 從DHT獲取元數據。 ProvideValue(key Multihash) // 聲明這個節點可一個提供一個大的數據。 FindValuePeers(key Multihash, min int) // 獲取服務於該大數據的節點。 } |
注意:不一樣的用例將要求基本不一樣的路由系統(例如廣域網中使用DHT,局域網中使用靜態HT)。所以,IPFS路由系統能夠根據用戶的需求替換的。只要使用上面的接口就能夠了,系統都能繼續正常運行。
IPFS 中的BitSwap協議受到BitTorrent 的啓發,經過對等節點間交換數據塊來分發數據的。像BT同樣, 每一個對等節點在下載的同時不斷向其餘對等節點上傳已下載的數據。和BT協議不一樣的是, BitSwap 不侷限於一個torrent文件中的數據塊。BitSwap 協議中存在一個永久的市場。 這個市場包括各個節點想要獲取的全部塊數據。而無論這些塊是哪些如.torrent文件中的一部分。這些快數據可能來自文件系統中徹底不相關的文件。 這個市場是由全部的節點組成的。
雖然易貨系統的概念意味着能夠建立虛擬貨幣,但這將須要一個全局分類帳原本跟蹤貨幣的全部權和轉移。這能夠實施爲BitSwap策略,並將在將來的論文中探討。
在基本狀況下,BitSwap節點必須以塊的形式彼此提供直接的值。只有當跨節點的塊的分佈是互補的時候,各取所需的時候,這纔會工做的很好。 一般狀況並不是如此,在某些狀況下,節點必須爲本身的塊而工做。 在節點沒有其對等節點所需的(或根本沒有的)狀況下,它會更低的優先級去尋找對等節點想要的塊。這會激勵節點去緩存和傳播稀有片斷, 即便節點對這些片斷不感興趣。
這個協議必須帶有激勵機制, 去激勵節點去seed 其餘節點所須要的塊,而它們自己是不須要這些塊的。 所以, BitSwap的節點很積極去給對端節點發送塊,期待得到報酬。但必須防止水蛭攻擊(空負載節點從不共享塊),一個簡單的相似信用的系統解決了這些問題:
1 |
r = bytes_sent / bytes_recv + 1 |
根據r,發送到負債節點的機率爲:
1 |
P(send | r ) = 1 − ( 1/ ( 1 + exp(6 − 3r) ) ) |
正如你看到的圖片1,當節點負債比例超過節點已創建信貸的兩倍,發送到負債節點的機率就會急速降低。
圖片1 當r增長時發送的機率
負債比是信任的衡量標準:對於以前成功的互換過不少數據的節點會寬容債務,而對不信任不瞭解的節點會嚴格不少。這個(a)給與那些創造不少節點的攻擊者(sybill 攻擊)一個障礙。(b)保護了以前成功交易節點之間的關係,即便這個節點暫時沒法提供數據。(c)最終阻塞那些關係已經惡化的節點之間的通訊,直到他們被再次證實。
BitSwap節點保存了一個記錄與全部其餘節點之間交易的帳本。這個可讓節點追蹤歷史記錄以及避免被篡改。當激活了一個連接,BitSwap節點就會互換它們帳本信息。若是這些帳本信息並不徹底相同,分類帳本將會從新初始化, 那些應計信貸和債務會丟失。 惡意節點會有意去失去「這些「帳本, 從而指望清除本身的債務。節點是不太可能在失去了應計信託的狀況下還能累積足夠的債務去受權認證。夥伴節點能夠自由的將其視爲不當行爲, 拒絕交易。
1 2 3 4 5 6 7 |
type Ledger struct { owner NodeId partner NodeId bytes_sent int bytes_recv int timestamp Timestamp } |
節點能夠自由的保留分佈式帳本歷史,這不須要正確的操做,由於只有當前的分類帳本條目是有用的。節點也能夠根據須要自由收集分佈式賬本,從不太有用的分佈式賬開始:老(其餘對等節點可能不存在)和小。
BitSwap 節點有如下簡單的協議。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// 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); } |
對等鏈接的生命週期草圖:
IPFS對象的格式是:
1 2 3 4 5 6 7 8 9 10 |
type IPFSLink struct { Name string // 此link的別名 Hash Multihash // 目標的加密hash Size int // 目標總大小 } type IPFSObject struct { links []IPFSLink //links數組 data []byte //不透明內容數據 } |
IPFS Merkle DAG是存儲數據很是靈活的一種方式。只要求對象引用是(a)內容可尋址的,(b)用上面的格式編碼。IPFS容許應用徹底的掌控數據域;應用可使用任何自定義格式的數據,即便數據IPFS都沒法理解。單獨的內部對象link表容許IPFS作:
1 2 3 4 5 6 |
> ipfs ls /XLZ1625Jjn7SubMDgEyeaynFuR84ginqvzb XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x 189458 less XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5 19441 script XLF4hwVHsVuZ78FZK6fozf8Jj9WEURMbCX4 5286 template <object multihash> <object size> <link name> |
1 2 3 4 5 6 |
> ipfs refs --recursive \ /XLZ1625Jjn7SubMDgEyeaynFuR84ginqvzb XLLxhdgJcXzLbtsLRL1twCHA2NrURp4H38s XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5 XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z |
原始數據結構公共link結構是IPFS構建任意數據結構的必要組成部分。能夠很容易看出Git的對象模型是如何套用DAG的。一些其餘潛在的數據結構:
IPFS對象能夠遍歷一個字符串路經。路經格式與傳統UNIX文件系統以及Web一致。Merkle DAG的links使遍歷變得很容易。全稱路經在IPFS中的格式是:
1 2 3 4 |
*# 格式 /ipfs/<hash-of-object>/<name-path-to-object> *# 例子 /ipfs/XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x/foo.txt |
/ipfs前綴容許只要在掛載點不衝突(掛載點名稱固然是可配置的)的狀況下掛載到一個已存在的系統上。第二個路經組成部分(第一個是IPFS)是一個對象的hash。一般都是這種狀況,由於沒有全局的根。一個根對象可能會有一個不可能完成的任務,就是在分佈式環境(可能還斷開連接)中處理百萬對象的一致性。所以,咱們用地址可尋址來模擬根。經過的hash全部的對象都是可訪問的。這意思是說,給一個路經對象/bar/baz,最後一個對象能夠能夠被全部的訪問的:
1 2 3 |
/ipfs/<hash-of-foo>/bar/baz /ipfs/<hash-of-bar>/baz /ipfs/<hash-of-baz> |
IPFS客戶端須要一個本地存儲器,一個外部系統能夠爲IPFS管理的對象存儲以及檢索本地原始數據。存儲器的類型根據節點使用案例不一樣而不一樣。在大多數狀況下,這個存儲器只是硬盤空間的一部分(不是被本地的文件系統使用鍵值存儲如leveldb來管理,就是直接被IPFS客戶端管理),在其餘的狀況下,例如非持久性緩存,存儲器就是RAM的一部分。
最終,全部的塊在IPFS中都是可以獲取的到的,塊都存儲在了一些節點的本地存儲器中。當用戶請求一個對象時,這個對象會被查找到並下載下來存儲到本地,至少也是暫時的存儲在本地。這爲一些可配置時間量提供了快速的查找。
但願確保特定對象生存的節點能夠鎖定此對象。這保證此特定對象被保存在了節點的本地存儲器上。也能夠遞歸的進行鎖定全部相關的派生對象。這使全部被指定的對象都保存在本地存儲器上。這對長久保存文件特別有用,包括引用。這也一樣讓IPFS成爲一個links是永久的Web,且對象能夠確保其餘被指定對象的生存。
IPFS是全球分佈的。它設計爲容許成千上萬的用戶文件能夠共同的存在的。DHT使用內容哈希尋址技術,使發佈對象是公平的,安全的,徹底分佈式的。任何人均可以發佈對象,只須要將對象的key加入到DHT中,而且以對象是對等節點的方式加入進去,而後把路徑給其餘的用戶。要注意的是,對象本質上是不可改變的,就像在Git中同樣。新版本的哈希值不一樣,所以是新對象。跟蹤版本則是額外版本對象的工做。
IPFS是具有能夠處理對象級別加密操做的。一個已加密的或者已簽名的對象包裝在一個特殊的框架裏,此框架容許加密和驗證原始字節。
1 2 3 4 5 6 7 8 |
type EncryptedObject struct { Object []bytes // 已加密的原始對象數據 Tag []bytes // 可選擇的加密標識 type SignedObject struct { Object []bytes // 已簽名的原始對象數據 Signature []bytes // HMAC簽名 PublicKey []multihash // 多重哈希身份鍵值 } |
加密操做改變了對象的哈希值,定義一個不一樣的新的對象。IPFS自動的驗證簽名以及使用用戶指定的鑰匙鏈解密數據。加密數據的links也一樣的被保護着,沒有解密祕鑰就沒法遍歷對象。也存在着一種現象,可能父對象使用了一個祕鑰進行了加密,而子對象使用了另外一個祕鑰進行加密或者根本沒有加密。這能夠保證links共享對象安全。
IPFS在Merkle DAG上還爲模型化版本文件系統定義了一組對象。這個對象模型與Git比較類似:
Block:一個可變大小的數據塊
List:塊或者其餘鏈表的集合
Tree:塊,鏈表,或者其餘樹的集合
Commit:樹在版本歷史記錄中的一個快照
我本來但願使用與Git對象格式一致的模型,但那就必需要分開來引進在分佈式文件系統中有用的某些特徵,如
1 2 3 |
{ "data": "some data here", // blobs無links } |
List對象表明着由幾個IPFS的blobs鏈接成的大文件或者重複數據刪除文件。Lists包含着有序的blob序列或list對象。從某種程度上而言,IPFS的list函數就像一個間接塊的文件系統。因爲lists能夠包含其餘的lists,那麼包含linked的鏈表和平衡樹的拓撲結構是有可能的。有向圖中相同的節點出如今多個不一樣地方容許在文件中重複數據刪除。固然,循環是不能夠能的,由於是被哈希尋址強制實行的。
1 2 3 4 5 6 7 8 9 10 11 |
{ "data": ["blob", "list", "blob"], //lists有一個對象類型的數組做爲數據 "links": [ { "hash": "XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x", "size": 189458 }, { "hash": "XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5", "size": 19441 }, { "hash": "XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z", "size": 5286 } //在links中lists是沒有名字的 ] } |
IPFS中的tree對象與Git中類似,它表明着一個目錄,一個名字到哈希值的映射。哈希值則表示着blobs,lists,其餘的trees,或者commits。注意,傳統路徑的命名早已經被Merkle DAG實現了。
1 2 3 4 5 6 7 8 9 10 11 |
{ "data": ["blob", "list", "blob"],//trees有一個對象類型的數組做爲數據 "links": [ { "hash": "XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x", "name": "less", "size": 189458 }, { "hash": "XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5", "name": "script", "size": 19441 }, { "hash": "XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z", "name": "template", "size": 5286 }//trees是有名字的 ] } |
IPFS中的commit對象表明任何對象在版本歷史記錄中的一個快照。與Git中相似,可是它可以表示任何類型的對象。它一樣link着發起對象。
Commit對象表明着一個對象在歷史版本中的一個特定快照。在兩個不一樣的commit中比較對象(和子對象)能夠揭露出兩個不一樣版本文件系統的區別。只要commit和它全部子對象的引用是可以被訪問的,全部前版本是可獲取的,全部文件系統改變的所有歷史是可訪問的,這就與Merkle DAG對象模型脫離開來了。
Git版本控制工具的全部功能對於IPFS的用戶是可用的。對象模型不徹底一致,但也是可兼容的。這可能
版本控制和分發大文件其中一個最主要的挑戰是:找到一個正確的方法來將它們分隔成獨立的塊。與其認爲IPFS能夠爲每一個不一樣類型的文件提供正確的分隔方法,不如說IPFS提供瞭如下的幾個可選選擇:
就像在LIBFS[?]中同樣使用Rabin Fingerprints [?]來選擇一個比較合適的塊邊界。
使用rsync[?] rolling-checksum算法,來檢測塊在版本之間的改變。
容許用戶指定專爲特定文件而調整的’快分隔’函數。
基於路徑的訪問須要遍歷對象圖。獲取每一個對象要求在DHT中查找它們的key,鏈接到對等節點,而後獲取它的塊。這形成至關大的開銷,特別是查找的路徑由不少子路徑組成時。下面的方法能夠減緩開銷:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "data": ["tree", "blob", "tree", "list", "blob" "blob"], "links": [ { "hash": "<ttt222-hash>", "size": 1234 "name": "ttt222-name" }, { "hash": "<bbb111-hash>", "size": 123, "name": "ttt222-name/bbb111-name" }, { "hash": "<ttt333-hash>", "size": 3456, "name": "ttt333-name" }, { "hash": "<lll111-hash>", "size": 587, "name": "ttt333-name/lll111-name"}, { "hash": "<bbb222-hash>", "size": 22, "name": "ttt333-name/lll111-name/bbb222-name" }, { "hash": "<bbb222-hash>", "size": 22 "name": "bbb222-name" } ] } |
目前爲止,IPFS桟造成了一個對等塊交換組成一個內容可尋址的DAG對象。這提供了發佈和獲取不可改變的對象。這甚至能夠跟蹤這些對象的版本歷史記錄。可是,這裏有一個關鍵成分遺漏了:易變的命名。沒有這個,發送IPFS的links,全部新內容的通訊確定都會有所誤差。如今所需就是能有某些方法能夠獲取相同路徑的的易變狀態。
這值得詳述緣由—若是最終易變數據是必須的—咱們費了很大的力氣構建了一個不可改變的Merkle DAG。就當作IPFS脫離了Merkle DAG的特徵:對象能夠
不可變的內容可尋址對象和命名的Merkle DAG, 可變指針指向Merkle DAG,實例化了一個出如今不少成功分佈式系統中的二分法。這些系統包括Git的版本控制系統,使用不可變的對象和可變的引用;還有UNIX分佈式的繼承者Plan9[?]文件系統,使用可變的Fossil和不可變的Venti[?]。LBFS[?]一樣使用可變的索引以及不可變的塊。
使用SFS[12,11]中的命名方案,給咱們提供了一個種能夠構建自我認證名稱的方法,
在一個加密指定的全局命名空間中,這是可變的。IPFS的方案以下:
注意下面的細節:
由於這不是一個內容可尋址的對象,因此發佈它就要依靠IPFS中的惟一的可變狀態分配製度,路由系統。過程是(a)首先把此對象作一個常規的不可變IPFS的對象來發布(b)將此對象的哈希值做爲元數據的值發佈到路由系統上:
1 |
routing.setValue(NodeId, <ns-object-hash>) |
發佈的對象中任何links在命令空間中充當子名稱:
1 2 3 |
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/ /ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs /ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs/ipfs |
通常建議發佈一個commit對象或者其餘對象的時候,要使用歷史版本記錄,由於這樣就用戶就能夠找到以前使用過的名字。不過因爲這並不老是須要的,因此留個用戶本身選擇。
注意當用戶發佈一個對象的時候,他不能使用相同的方式來發布對象。
IPNS的確是一個分配和在分配名稱的好方法,可是對用戶卻不是十分友好的,由於它使用很長的哈希值做爲名稱,衆所周知這樣的名稱很難被記住。IPNS足夠應付URLs,但對於不少線下的傳輸工做就沒有這麼好用了。所以,IPFS使用下面的技術來增長IPNS的用戶友好度。
對等節點Links
被SFS所鼓舞,用戶能夠直接將其餘用戶的對象link到本身的對象上(命令空間,家目錄等等)。這有一個好處就是建立了一個可信任的Web(也支持老的真實性認證模型):
1 2 3 4 5 6 7 8 |
# Alice links 到Bob上 ipfs link /<alice-pk-hash>/friends/bob /<bob-pk-hash> # Eve links 到Alice上 ipfs link /<eve-pk-hash/friends/alice /<alice-pk-hash> # Eve 也能夠訪問Bob /<eve-pk-hash/friends/alice/friends/bob # 訪問Verisign 認證域 /<verisign-pk-hash>/foo.com |
DNS TXT IPNS 記錄
若是/ipns/是一個有效的域名稱,IPFS會在DNS TXT記錄中查找關鍵的ipns。IPFS會將查找到的值翻譯爲一個對象的哈希值或者另外一個ipns的路徑:
1 2 3 4 |
# DNS TXT 記錄 ipfs.benet.ai. TXT "ipfs=XLF2ipQ4jD3U ..." # 表現爲符號連接 ln -s /ipns/XLF2ipQ4jD3U /ipns/fs.benet.ai |
Proquint 可讀的標識符
老是會有將二進制編碼翻譯成可讀文件的方法。IPNS則支持Proquint[?].。以下:
1 2 3 4 |
# proquint語句 /ipns/dahih-dolij-sozuk-vosah-luvar-fuluh # 分解爲相應的下面形式 /ipns/KhAwNprxYVxKqpDZ |
縮短名稱服務
會涌現出不少服務器提供縮短名稱的服務,向用戶提供他們的命名空間。就像咱們如今看到的DNS和Web的URLs:
1 2 3 4 |
# 用戶能夠從下面獲取一個link /ipns/shorten.er/foobar # 而後放到本身的命名空間 /ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm |
IPFS設計爲可使用多種不一樣的方法來使用的,下面就是一些我將會繼續追求的使用方式: