➡ 简

IPFS(星際文件系統)中文白皮書

IPFS - 可快速索引的版本化的點對點文件系統(草案3)

作者: Juan Benet ([email protected])
譯者: 郭光華([email protected])

摘要

星際文件系統是一種點對點的分佈式文件系統, 旨在連接所有有相同的文件系統的計算機設備。在某些方面, IPFS類似於web, 但web 是中心化的,而IPFS是一個單一的Bittorrent 群集, 用git 倉庫分佈式存儲。換句話說, IPFS 提供了高吞吐量的內容尋址塊存儲模型, 具有內容尋址的超鏈接。這形成了一個廣義的Merkle DAG 數據結構,可以用這個數據結構構建版本文件系統,區塊鏈,甚至是永久性網站。。IPFS 結合了分佈式哈希表, 帶有激勵機制的塊交換和自我認證命名空間。IPFS 沒有單故障點, 節點不需要相互信任。

1. 介紹

在全球分佈式文件系統這領域, 已經有許多人的嘗試。一些系統已經取得了重大的成功, 而很多卻完全失敗了。在學術嘗試中, AFS【6】就是成功的例子,如今已經得到廣泛的應用, 然而,其他的【7, ?】卻沒有得到相同的結果。在學術界之外,應用最廣泛的是面向音視頻媒體的點對點文件共享系統。 最值得注意的是, Napster, KaZaA 和BitTorrent[2]部署的文件分發系統支持1億用戶的同時在線。即使在今天, BitTorrent 也維持著每天千萬節點的活躍數。 基於這些學術文件系統理論而實現的應用程序有很多的用戶量, 然而,這些系統理論是在應用層,而沒有放在基礎層。以致沒有出現通用的文件系統基礎框架, 給全球提供低延遲的分發。
也許是因為HTTP這樣“足夠好“的系統已經存在。到目前為止,HTTP已經作為“分佈式文件系統“的協議,並且已經大量部署,再與瀏覽器相結合,具有巨大的技術和社會影響力。在現在, 它已經成為互聯網傳輸文件的事實標準。然而,他沒有采用最近15年的發明的數十種先進的文件分發技術。 從一方面講, 由於向後兼容的限制 和 當前新模式的投入, 不斷髮展http web 的基礎設施幾乎是不可能的。但從一個角度看, 從http 出現以來, 已經有許多新協議出現並被廣泛使用。升級http協議雖然能引入新功能和加強當前http協議,但會降低用戶的體驗。
有些行業已經擺脫使用HTTP 這麼久, 因為移動小文件相對便宜,即使對擁有大流量的小組織也是如此。但是,隨著新的挑戰,我們正在進入數據分發的新紀元。

2. 背景

本節回顧了IPFS所採用成功的點對點系統技術的重要屬性。

### [](#2-1-分佈式哈希表-DHT "2.1 分佈式哈希表(DHT)")2.1 分佈式哈希表(DHT)

分佈式散列表(DHT)被廣泛用於協調和維護關於對等系統的元數據。比如,MainlineDHT 是一個去中心化哈希表,他可追蹤查找所有的對等節點。

#### [](#2-1-1-Kademlia-DHT "2.1.1 Kademlia DHT")2.1.1 Kademlia DHT

Kademlia\[10\] 是受歡迎的DHT, 它提供:

2.1.2 Coral DSHT

雖然一些對等文件系統直接在DHT中存儲數據塊,這種“數據存儲在不需要的節點會亂費存儲和帶寬”[5]。Coral DSHT擴展了Kademlia三個特別重要的方式:

2.1.3 S/Kademlia DHT

S/Kademlia[1] 擴展了Kademlia, 用於防止惡意的攻擊。有如下兩方面的方法:

2.2 塊交換 - BitTorrent

BitTorrent[3] 是一個廣泛成功應用的點對點共享文件系統,它可以在存在不信任的對等節點(群集)的協作網絡中分發各自的文件數據片。從BitTorrent和它的生態系統的關鍵特徵, IPFS得到啟示如下:

2.3 版本控制系統- Git

版本控制系統提供了對隨時間變化的文件進行建模的設施,並有效地分發不同的版本。流行版本控制系統Git提供了強大的Merkle DAG對象模型,以分佈式友好的方式捕獲對文件系統樹的更改。

2.4 自我認證認文件系統-SFS

SFS [ 12,11 ]提出了兩個引人注目的實現(a)分佈式信任鏈,和(b)平等共享的全局命名空間。SFS引入了一種自我建構技術—註冊文件:尋址遠程文件系統使用以下格式:

    /sfs/
:

    
    Location:代表的是服務網絡地方
    
    HostID = hash(public_key || Location)

因此SFS文件系統的名字認證了它的服務,用戶可以通過服務提供的公鑰來驗證,協商一個共享的私鑰,保證所有的通信。所有的SFS實例都共享了一個全局的命名空間,這個命名空間的名稱分配是加密的,不被任何中心化的body控制。

3. IPFS設計

IPFS是一個分佈式文件系統,它綜合了以前的對等系統的成功想法,包括DHT,BitTorrent,Git和SFS。 IPFS的貢獻是簡化,發展和將成熟的技術連接成一個單一的內聚系統,大於其部分的總和。 IPFS提供了編寫和部署應用程序的新平臺,以及一個新的分發系統版本化大數據。 IPFS甚至可以演進網絡本身。
IPFS是點對點的;沒有節點是特權的。 IPFS節點將IPFS對象存儲在本地存儲中。節點彼此連接並傳輸對象。這些對象表示文件和其他數據結構。 IPFS協議分為一組負責不同功能的子協議:
1. 身份 - 管理節點身份生成和驗證。描述在3.1節。
2.網絡 - 管理與其他對等體的連接,使用各種底層網絡協議。可配置的。詳見3.2節。
3.路由 - 維護信息以定位特定的對等體和對象。響應本地和遠程查詢。默認為DH​​T,但可更換。在3.3節描述。
4.交換 - 一種支持有效塊分配的新型塊交換協議(BitSwap)。模擬市場,弱化數據複製。貿易策略可替換。描述在3.4節。
5.對象 - 具有鏈接的內容尋址不可更改對象的Merkle DAG。用於表示任意數據結構,例如文件層次和通信系統。詳見第3.5節。
6.文件 - 由Git啟發的版本化文件系統層次結構。詳見3.6節。
7.命名 - 自我認證的可變名稱系統。詳見3.7節。
這些子系統不是獨立的;它們是集成在一起,互相利用各自的屬性。但是,分開描述它們是有用的,從下到上構建協議棧。符號:Go語言中指定了以下數據結構和功能

3.1 身份

節點由NodeId標識,這是使用S / Kademlia的靜態加密難題[1]創建的公鑰的密碼散列。節點存儲其公私鑰(用密碼加密)。用戶可以在每次啟動時自由地設置一個“新”節點身份,儘管這會損失積累的網絡利益。激勵節點保持不變。

 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 = 

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不是將系統鎖定到一組特定的功能選擇,而是支持自我描述的值。哈希摘要值以多重哈希格式存儲,其包括指定使用的哈希函數的頭和以字節為單位的摘要長度。例如:





這允許系統

3.2 網絡

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

    \# 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/

3.3 路由

IPFS節點需要一個路由系統, 這個路由系統可用於查找:

IPFS使用基於S / Kademlia和Coral的DSHT,在2.1節中具體介紹過。在對象大小和使用模式方面, IPFS 類似於Coral[5] 和Mainline[16], 因此,IPFS DHT根據其大小對存儲的值進行區分。小的值(等於或小於1KB)直接存儲在DHT上。對於更大的值,DHT只存儲值索引,這個索引就是一個對等節點的NodeId, 該對等節點可以提供對該類型的值的具體服務。

DSHT的接口如下:

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路由系統可以根據用戶的需求替換的。只要使用上面的接口就可以了,系統都能繼續正常運行。

3.4 塊交換 - BitSwap協議

IPFS 中的BitSwap協議受到BitTorrent 的啟發,通過對等節點間交換數據塊來分發數據的。像BT一樣, 每個對等節點在下載的同時不斷向其他對等節點上傳已下載的數據。和BT協議不同的是, BitSwap 不侷限於一個torrent文件中的數據塊。BitSwap 協議中存在一個永久的市場。 這個市場包括各個節點想要獲取的所有塊數據。而不管這些塊是哪些如.torrent文件中的一部分。這些快數據可能來自文件系統中完全不相關的文件。 這個市場是由所有的節點組成的。
雖然易貨系統的概念意味著可以創建虛擬貨幣,但這將需要一個全局分類賬本來跟蹤貨幣的所有權和轉移。這可以實施為BitSwap策略,並將在未來的論文中探討。
在基本情況下,BitSwap節點必須以塊的形式彼此提供直接的值。只有當跨節點的塊的分佈是互補的時候,各取所需的時候,這才會工作的很好。 通常情況並非如此,在某些情況下,節點必須為自己的塊而工作。 在節點沒有其對等節點所需的(或根本沒有的)情況下,它會更低的優先級去尋找對等節點想要的塊。這會激勵節點去緩存和傳播稀有片段, 即使節點對這些片段不感興趣。

3.4.1 BitSwap 信用

這個協議必須帶有激勵機制, 去激勵節點去seed 其他節點所需要的塊,而它們本身是不需要這些塊的。 因此, BitSwap的節點很積極去給對端節點發送塊,期待獲得報酬。但必須防止水蛭攻擊(空負載節點從不共享塊),一個簡單的類似信用的系統解決了這些問題:

3.4.2 BitSwap的策略

BitSwap 對等節點採用很多不同的策略,這些策略對整個數據塊的交換執行力產生了不同的巨大影響。在BT 中, 標準策略是明確規定的(tit-for-tat),其他不同的策略也已經被實施,從BitTyrant \[8\](儘可能分享)到BitThief \[8\](利用一個漏洞,從不共享),到PropShare \[8\](按比例分享)。BitSwap 對等體可以類似地實現一系列的策略(良好和惡意)。對於功能的選擇,應該瞄準:
    r =  bytes\_sent  / bytes\_recv + 1

根據r,發送到負債節點的概率為:

P(send | r ) = 1 − ( 1/  ( 1 + exp(6 − 3r) ) )

正如你看到的圖片1,當節點負債比例超過節點已建立信貸的兩倍,發送到負債節點的概率就會急速下降。

當r增加時發送的概率

圖1 當r增加時發送的概率

負債比是信任的衡量標準:對於之前成功的互換過很多數據的節點會寬容債務,而對不信任不瞭解的節點會嚴格很多。這個(a)給與那些創造很多節點的攻擊者(sybill 攻擊)一個障礙。(b)保護了之前成功交易節點之間的關係,即使這個節點暫時無法提供數據。(c)最終阻塞那些關係已經惡化的節點之間的通信,直到他們被再次證明。

3.4.3 BitSwap 賬本

BitSwap節點保存了一個記錄與所有其他節點之間交易的賬本。這個可以讓節點追蹤歷史記錄以及避免被篡改。當激活了一個鏈接,BitSwap節點就會互換它們賬本信息。如果這些賬本信息並不完全相同,分類賬本將會重新初始化, 那些應計信貸和債務會丟失。 惡意節點會有意去失去“這些“賬本, 從而期望清除自己的債務。節點是不太可能在失去了應計信託的情況下還能累積足夠的債務去授權認證。夥伴節點可以自由的將其視為不當行為, 拒絕交易。

type Ledger struct {

    owner NodeId

    partner NodeId

    bytes_sent int

    bytes_recv int

    timestamp Timestamp

}

節點可以自由的保留分佈式賬本歷史,這不需要正確的操作,因為只有當前的分類賬本條目是有用的。節點也可以根據需要自由收集分佈式帳本,從不太有用的分佈式帳開始:老(其他對等節點可能不存在)和小。

3.4.4 BitSwap 詳解

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);
}

對等連接的生命週期草圖:

IPFS對象的格式是:

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做:

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

 
 

\> ipfs refs --recursive \
    
/XLZ1625Jjn7SubMDgEyeaynFuR84ginqvzb
XLLxhdgJcXzLbtsLRL1twCHA2NrURp4H38s
XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x
XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5
XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z

原始數據結構公共link結構是IPFS構建任意數據結構的必要組成部分。可以很容易看出Git的對象模型是如何套用DAG的。一些其他潛在的數據結構:

這些系統都可以套用IPFS Merkle DAG,這使這些系統更復雜的應用可以使用IPFS作為傳輸協議。

3.5.1 路經

IPFS對象可以遍歷一個字符串路經。路經格式與傳統UNIX文件系統以及Web一致。Merkle DAG的links使遍歷變得很容易。全稱路經在IPFS中的格式是:

*# 格式
/ipfs/
/


*# 例子
/ipfs/XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x/foo.txt

/ipfs前綴允許只要在掛載點不衝突(掛載點名稱當然是可配置的)的情況下掛載到一個已存在的系統上。第二個路經組成部分(第一個是IPFS)是一個對象的hash。通常都是這種情況,因為沒有全局的根。一個根對象可能會有一個不可能完成的任務,就是在分佈式環境(可能還斷開鏈接)中處理百萬對象的一致性。因此,我們用地址可尋址來模擬根。通過的hash所有的對象都是可訪問的。這意思是說,給一個路經對象/bar/baz,最後一個對象可以可以被所有的訪問的:

/ipfs/
/bar/baz
/ipfs/
/baz
/ipfs/

3.5.2 本地對象

IPFS客戶端需要一個本地存儲器,一個外部系統可以為IPFS管理的對象存儲以及檢索本地原始數據。存儲器的類型根據節點使用案例不同而不同。在大多數情況下,這個存儲器只是硬盤空間的一部分(不是被本地的文件系統使用鍵值存儲如leveldb來管理,就是直接被IPFS客戶端管理),在其他的情況下,例如非持久性緩存,存儲器就是RAM的一部分。
最終,所有的塊在IPFS中都是能夠獲取的到的,塊都存儲在了一些節點的本地存儲器中。當用戶請求一個對象時,這個對象會被查找到並下載下來存儲到本地,至少也是暫時的存儲在本地。這為一些可配置時間量提供了快速的查找。

3.5.3對象鎖定

希望確保特定對象生存的節點可以鎖定此對象。這保證此特定對象被保存在了節點的本地存儲器上。也可以遞歸的進行鎖定所有相關的派生對象。這使所有被指定的對象都保存在本地存儲器上。這對長久保存文件特別有用,包括引用。這也同樣讓IPFS成為一個links是永久的Web,且對象可以確保其他被指定對象的生存。

3.5.4 發佈對象

IPFS是全球分佈的。它設計為允許成千上萬的用戶文件可以共同的存在的。DHT使用內容哈希尋址技術,使發佈對象是公平的,安全的,完全分佈式的。任何人都可以發佈對象,只需要將對象的key加入到DHT中,並且以對象是對等節點的方式加入進去,然後把路徑給其他的用戶。要注意的是,對象本質上是不可改變的,就像在Git中一樣。新版本的哈希值不同,因此是新對象。跟蹤版本則是額外版本對象的工作。

3.5.5 對象級別的加密

IPFS是具備可以處理對象級別加密操作的。一個已加密的或者已簽名的對象包裝在一個特殊的框架裡,此框架允許加密和驗證原始字節。

type EncryptedObject struct {
	Object \[\]bytes // 已加密的原始對象數據
	Tag \[\]bytes    // 可選擇的加密標識
	type SignedObject struct {
	Object \[\]bytes  // 已簽名的原始對象數據
	Signature \[\]bytes // HMAC簽名
	PublicKey \[\]multihash // 多重哈希身份鍵值
}

加密操作改變了對象的哈希值,定義一個不同的新的對象。IPFS自動的驗證簽名以及使用用戶指定的鑰匙鏈解密數據。加密數據的links也同樣的被保護著,沒有解密祕鑰就無法遍歷對象。也存在著一種現象,可能父對象使用了一個祕鑰進行了加密,而子對象使用了另一個祕鑰進行加密或者根本沒有加密。這可以保證links共享對象安全。

3.6 文件

IPFS在Merkle DAG上還為模型化版本文件系統定義了一組對象。這個對象模型與Git比較相似:
Block:一個可變大小的數據塊
List:塊或者其他鏈表的集合
Tree:塊,鏈表,或者其他樹的集合
Commit:樹在版本歷史記錄中的一個快照
我原本希望使用與Git對象格式一致的模型,但那就必須要分開來引進在分佈式文件系統中有用的某些特徵,如

標記:下面的文件對象格式使用JSON。注意,雖然IPFS包含了JSON的互相轉換,但是文件對象的結構體還是使用protobufs的二進制編碼。

3.6.1 文件對象:blob

blob對象代表一個文件且包含一個可尋址的數據單元,IPFS的blobs就像Git的blobs或者文件系統數據塊。它們存儲用戶的數據。需要留意的是IPFS文件可以使用lists或者blobs來表示。Blobs沒有links。
{
    "data": "some data here",  // blobs無links   
}

3.6.2 文件對象: list

List對象代表著由幾個IPFS的blobs連接成的大文件或者重複數據刪除文件。Lists包含著有序的blob序列或list對象。從某種程度上而言,IPFS的list函數就像一個間接塊的文件系統。由於lists可以包含其他的lists,那麼包含linked的鏈表和平衡樹的拓撲結構是有可能的。有向圖中相同的節點出現在多個不同地方允許在文件中重複數據刪除。當然,循環是不可以能的,因為是被哈希尋址強制實行的。

{
	"data": ["blob", "list", "blob"], //lists有一個對象類型的數組作為數據
	"links": [
		{ "hash": "XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x",
		"size": 189458 },
		{ "hash": "XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5",
		"size": 19441 },
		{ "hash": "XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z",
		"size": 5286 } //在links中lists是沒有名字的
	]
}

3.6.3 文件對象:tree

IPFS中的tree對象與Git中相似,它代表著一個目錄,一個名字到哈希值的映射。哈希值則表示著blobs,lists,其他的trees,或者commits。注意,傳統路徑的命名早已經被Merkle DAG實現了。

{
	"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是有名字的
	]
}

3.6.4 文件對象:commit

IPFS中的commit對象代表任何對象在版本歷史記錄中的一個快照。與Git中類似,但是它能夠表示任何類型的對象。它同樣link著發起對象。

3.6.5 版本控制

Commit對象代表著一個對象在歷史版本中的一個特定快照。在兩個不同的commit中比較對象(和子對象)可以揭露出兩個不同版本文件系統的區別。只要commit和它所有子對象的引用是能夠被訪問的,所有前版本是可獲取的,所有文件系統改變的全部歷史是可訪問的,這就與Merkle DAG對象模型脫離開來了。

Git版本控制工具的所有功能對於IPFS的用戶是可用的。對象模型不完全一致,但也是可兼容的。這可能

3.6.6 文件系統路徑

如我們在Merkle DAG中看到的一樣,IPFS對象可以使用字符串路徑API來遍歷。IPFS文件對象是特意設計的,為了讓掛載IPFS到UNIX文件系統更加簡單。文件對象限制trees沒有數據,為了使它們可以表示目錄。Commits可以以代表目錄的形式出現,也可以完全的隱藏在文件系統中。

3.6.7 將文件分隔成Lists和Blobs

版本控制和分發大文件其中一個最主要的挑戰是:找到一個正確的方法來將它們分隔成獨立的塊。與其認為IPFS可以為每個不同類型的文件提供正確的分隔方法,不如說IPFS提供了以下的幾個可選選擇:
就像在LIBFS[?]中一樣使用Rabin Fingerprints [?]來選擇一個比較合適的塊邊界。
使用rsync[?] rolling-checksum算法,來檢測塊在版本之間的改變。
允許用戶指定專為特定文件而調整的’快分隔’函數。

3.6.8 路徑查找性能

基於路徑的訪問需要遍歷對象圖。獲取每個對象要求在DHT中查找它們的key,連接到對等節點,然後獲取它的塊。這造成相當大的開銷,特別是查找的路徑由很多子路徑組成時。下面的方法可以減緩開銷:

{
	"data": ["tree", "blob", "tree", "list", "blob" "blob"],
	"links": [
		{ "hash": "
", "size": 1234
		"name": "ttt222-name" },
		{ "hash": "
", "size": 123,
		"name": "ttt222-name/bbb111-name" },
		{ "hash": "
", "size": 3456,
		"name": "ttt333-name" },
		{ "hash": "
", "size": 587,
		"name": "ttt333-name/lll111-name"},
		{ "hash": "
", "size": 22,
		"name": "ttt333-name/lll111-name/bbb222-name" },
		{ "hash": "
", "size": 22
		"name": "bbb222-name" }
	]
}

3.7 IPNS:命名以及易變狀態

目前為止,IPFS桟形成了一個對等塊交換組成一個內容可尋址的DAG對象。這提供了發佈和獲取不可改變的對象。這甚至可以跟蹤這些對象的版本歷史記錄。但是,這裡有一個關鍵成分遺漏了:易變的命名。沒有這個,發送IPFS的links,所有新內容的通信肯定都會有所偏差。現在所需就是能有某些方法可以獲取相同路徑的的易變狀態。
這值得詳述原因—如果最終易變數據是必須的—我們費了很大的力氣構建了一個不可改變的Merkle DAG。就當做IPFS脫離了Merkle DAG的特徵:對象可以

不可變的內容可尋址對象和命名的Merkle DAG, 可變指針指向Merkle DAG,實例化了一個出現在很多成功分佈式系統中的二分法。這些系統包括Git的版本控制系統,使用不可變的對象和可變的引用;還有UNIX分佈式的繼承者Plan9[?]文件系統,使用可變的Fossil和不可變的Venti[?]。LBFS[?]同樣使用可變的索引以及不可變的塊。

3.7.1 自我認證名稱

使用SFS[12,11]中的命名方案,給我們提供了一個種可以構建自我認證名稱的方法,在一個加密指定的全局命名空間中,這是可變的。

IPFS的方案如下:

注意下面的細節:

routing.setValue(NodeId, 
)
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs/ipfs

3.7.2人類友好名稱

IPNS的確是一個分配和在分配名稱的好方法,但是對用戶卻不是十分友好的,因為它使用很長的哈希值作為名稱,眾所周知這樣的名稱很難被記住。IPNS足夠應付URLs,但對於很多線下的傳輸工作就沒有這麼好用了。因此,IPFS使用下面的技術來增加IPNS的用戶友好度。
對等節點Links
被SFS所鼓舞,用戶可以直接將其他用戶的對象link到自己的對象上(命令空間,家目錄等等)。這有一個好處就是創建了一個可信任的Web(也支持老的真實性認證模型):

# Alice links 到Bob上
ipfs link /
/friends/bob /

# Eve links 到Alice上
ipfs link /