NO IMAGE

IPFS學習筆記

版本:

  • 本文件持續更新……
  • 即將補充Bittorrent和Merkle DAG詳細內容

參考:

PPT以及github
PPT
github

IPFS簡介

Protocol Labs協議實驗室成立於2014年5月,由IPFS和Filecoin的發明者Juan Benet創立。在2014年夏天,加入了美國頂級孵化器Y-Combinator。協議實驗室於2015年1月向世界釋出了IPFS,從此,IPFS在各行業的組織中獲得了巨大的發展。在2016年,IPFS一度成為區塊鏈行業中最受青睞的技術之一,數千名開發人員稱之為“WEB的未來”。同年,協議實驗室還建立了libp2p、IPLD、multiformats、Orbit以及其他專案。而我們最期待的專案是Filecoin,目前正在開發中,預計在今年的晚些時候上線。

IPFSIPFS的中文名是星際檔案系統(InterPlanetary File System),它本質上是一種內容可定址、版本化、點對點超媒體的分散式儲存、傳輸協議 ,目標是補充甚至取代過去20年裡使用的超文字媒體傳輸協議(HTTP) ,希望構建更快、更安全、更自由的網際網路時代.

為什麼要取代HTTP?
1. HTTP效率低下,伺服器成本昂貴:
使用HTTP協議從一臺計算機伺服器上一次只能下載一個檔案,而不是同時從多臺計算機中獲取檔案。通過P2P方式的視訊傳輸可以節省頻寬成本的60%。

  1. 歷史檔案被刪除:
    網頁的平均使用壽命為100天,大量的網站檔案不能得以長期儲存。有些重要的檔案因操作不當,也有可能永遠在網際網路消失。

  2. 中心化的網路限制了機會
    網際網路一直是人類進步的催化器,但中心化的網路容易被控制,是對網際網路良性發展的的威脅。

  3. 網路應用太依賴骨幹網
    為保證資料的可靠性,我們開發的應用程式太依賴大型的中心伺服器,並通過大量的備份來保證資料的安全。

HTTP協議已經用了20年的歷史,從HTTP 1.0 到現在的HTTP 5,網頁的展示越來越美觀豐富,但它背後的Browser/Server 模式是從來沒變的。

對比HTTP,IPFS具有這樣的一些特性:

  1. 基於內容定址,而非基於域名定址。檔案(內容)具有存在的唯一性,一個檔案加入了IPFS的網路,將基於計算對內容賦予一個唯一加密的雜湊值。這將改變我們使用域名訪問網路的習慣。

  2. 提供檔案的歷史版本控制器(如git),並且讓多節點使用儲存不同版本的檔案。

  3. IPFS的網路上執行著一條區塊鏈,即用來儲存網際網路檔案的雜湊值表,每次有網路訪問,即要在鏈上查詢該內容(檔案)的地址。

  4. 通過使用代幣(FileCoin)的激勵作用,讓各節點有動力去儲存資料。 Filecoin 是一個由加密貨幣驅動的儲存網路。礦工通過為網路提供開放的硬碟空間獲得Filecoin,而使用者則用 Filecoin 來支付在去中心化網路中儲存加密檔案的費用。

IPFS協議棧

IPFS至少有七層協議棧,從下至上分別為身份、網路、路由、交換、物件、檔案、命名、應用(有些認為八層協議棧的存在應用層),每層協議棧各司其職,寫成獨立於上層,但上層依賴於下層。

各層解釋:

  • 身份層和路由層可以一起解釋。對等節點身份資訊的生成以及路由規則是通過Kademlia協議生成制定,KAD協議實質是構建了一個分散式鬆散Hash表,簡稱DHT,每個加入這個DHT網路的人都要生成自己的身份資訊(通過雜湊生成的ID),然後才能通過這個身份資訊去負責儲存這個網路裡的資源資訊和其他成員的聯絡資訊。

  • 網路層比較核心,使用的LibP2P可以支援任意傳輸層協議。NAT技術能讓內網中的裝置共用同一個外網IP,我們都體驗過的家庭路由器就是這個原理。

  • 交換層,是類似迅雷這樣的BT工具。

    1. 迅雷其實是模擬了P2P網路,並建立中心伺服器,當伺服器登記使用者請求資源時,讓請求同樣資源的使用者形成一個小叢集swarm,在這裡分享資料。這種方式有弊端,一位伺服器是由迅雷統一維護,如果出現了故障、宕機時,下載操作無法進行。
    1. 中心化服務還可以限制一些下載請求,人們發明了一種更聰明的方式就是Bittorrent,讓每一個種子節點所要儲存的資料,通過雜湊表儲存在裡面,BT工具相對不太受監管,服務更加穩定。
    1. IPFS團隊把BitTorrent進行了創新,叫作Bitswap,它增加了信用和帳單體系來激勵節點去分享,我推斷FileCoin有很大概率是基於Bitswap,使用者在Bitswap裡增加資料會增加信用分,分享得越多信用分越高。如果使用者只去檢索資料而不存資料,信用分會越來越低,其它節點會在嵌入連線時優先選擇信用分高的。這一設計可以解決女巫攻擊,信用分不可能靠機器刷去提高,一直刷檢索請求,信用分越刷越低。請求次數和儲存量的變數之間有一個比較精妙的演算法,類似一個拋物線,前期可以容忍很多東西,達到一定次數後不再信任。
  • 物件層和檔案層適合結合來談,它們管理的是IPFS上80%的資料結構,大部分資料物件都是以Merkle DAG的結構存在,這為內容定址和去重提供了便利。檔案層是一個新的資料結構,和DAG並列,採用Git一樣的資料結構來支援版本快照。

  • 命名層具有自我驗證的特性(當其他使用者獲取該物件時,使用指紋公鑰進行驗籤,即驗證所用的公鑰是否與NodeId匹配,這驗證了使用者釋出物件的真實性,同時也獲取到了可變狀態),並且加入了IPNS這個巧妙的設計來使得加密後的DAG物件名可定義,增強可閱讀性。

  • 最後是應用層,IPFS核心價值就在於上面執行的應用程式,我們可以利用它類似CDN的功能,在成本很低的頻寬下,去獲得想要的資料,從而提升整個應用程式的效率。

新的技術取代老的技術,無非就兩點:第一,能提高系統效率;第二,能夠降低系統成本。IPFS把這兩點都做到了。

技術拆解

本章將會將IPFS技術拆解,主要分成以下幾部分進行解釋:

  • Kademlia和DHT
  • Merkle Tree和Merkle DAG
  • Bittorrent和BitSwap
  • IPNS

1. Kademlia和DHT

DHT
DHT全稱叫分散式雜湊表(Distributed Hash Table),是一種分散式儲存方法,一類可由鍵值來唯一標示的資訊按照某種約定/協議被分散地儲存在多個節點上,這樣也可以有效地避免“中央集權式”的伺服器的單一故障而帶來的整個網路癱瘓。實現DHT的技術/演算法有很多種,常用的有:Chord, Pastry, Kademlia等。我們這裡要研究的是Kademlia演算法。

  • DHT分散式雜湊表:
    1.雜湊表被分割成不連續的塊,每個節點被分配給一個屬於自己的雜湊塊(稱為區間表),併成為這個雜湊塊的管理者。
    2.通過雜湊函式,一個物件的名字或關鍵詞被對映為128位或160位的雜湊值。

  • DHT網路的基本思想:
    1.每一份資源都由一組關鍵字進行標識。
    2.系統對其中的每一個關鍵字進行Hash,根據Hash的結果決定此關鍵字對應的那條資訊(即資源索引中的一項)由哪個使用者負責儲存。由此,生成雜湊表。
    3.使用者搜尋的時候,用同樣的演算法計算每個關鍵字的Hash,然後從雜湊表獲得該關鍵字對應的資訊儲存位置(具體檢視關鍵字定位),並迅速定位資源。

  • DHT關鍵字定位
    1.DHT通過分散式雜湊函式,將輸入的關鍵字唯一對映到某個節點上,然後通過某些路由演算法同該節點建立連線。
    2.每個節點並不需要儲存整個系統的節點檢視資訊,只在節點中儲存其鄰近的幾個後繼節點資訊。當一個節點收到一個查詢操作時,如果它發現所查詢的標識不在自己關聯的區間內,那麼該節點將會把該查詢傳送給其儲存節點資訊表中它認為最靠近目標的鄰居。
    3.每次轉發都能更進一步地接近資料來源。因此較少的路由資訊就可以有效地實現到達目標節點。

Kademlia
各種DHT的實現演算法,不論是Chord, Pastry,還是Kademlia,其最直接的目標就是以最快的速度來定位到期望的節點,在P2P檔案分享應用中則是以最快的速度來查詢到正在分享某一檔案/種子的peers列表資訊。因為每個節點都是分散式存在於地球的任何角落,如果用地理距離來衡量兩節點間的距離則可能給計算帶來極大複雜性甚至不可能進行衡量,因此基本所有的DHT演算法都是採用某種邏輯上的距離,在Kademlia則採用簡單的異或計算 來衡量兩節點間的距離,它和地理上的距離沒有任何關係,但卻具備幾何公式的絕大特徵:

  1. 節點和它本身之間的異或距離是0
  2. 異或距離是對稱的:即從A到B的異或距離與從B到A的異或距離是等同的
  3. 異或距離符合三角形不等式:給定三個頂點A B C,假如AC之間的異或距離最大,那麼AC之間的異或距離必小於或等於AB異或距離和BC異或距離之和.
  4. 對於給定的一個距離,距離A只存在有唯一的一個節點B,也即單向性,在查詢路徑上也是單向的,這個和地理距離不同。

Kademlia中規定所有的節點都具有一個節點ID,該節點ID的產生方法和種子檔案中的info hash採用相同演算法:即sha-1(安全hash演算法)。因此每個節點的id,以及每個共享檔案/種子的info-hash都是唯一的,並且都是20個字元160bits位組成。兩個節點間的距離就是兩個節點id的異或結果,節點離鍵值(種子)的距離為該節點的id和該種子檔案的info-hash的異或結果。

Kademlia在異或距離度量的基礎上又把整個DHT網路拓撲組織成一個二叉字首樹,所有的節點(所有的正在執行的,並且開取了DHT功能)作為該二叉字首樹的葉子節點,可以想象這棵二叉樹可以容納多達2128個葉子(節點),這足以組織任何規模的網路了。對於每個節點來說按照離自己的遠近區域又可以把這棵樹劃分為160棵子樹,每一個子樹和該節點都有一個共同的字首,共同字首越少離得越遠(異或結果亦是如此)。

例如:以下5個節點將會根據其ID組織成二叉樹(模擬)

為了快速到達這160棵子樹,處於DHT網路的每一個節點都記錄了每棵子樹上的K個節點的資訊(ip,port,id),在BT中K固定為8。這份記錄資訊稱為K桶,也叫路由表。這個路由表與通常IP路由的概念不一樣,它代表了到達處於自己某個距離範圍[2i—2i 1)的節點,可以通過該範圍所選取的K個節點來定位。下圖是路由表的結構:

實際上,路由表可能沒有160份,因為路由表是對半拆分的,最初只有一份,在插入過程中,該路由表的節點大於k(8)時,則拆分成兩半,一半包含自身節點,一半不包含自身節點,迴圈往復。(?路由表的節點大於k(8)?怎麼拆分?
每一個新加入DHT網路的節點,其路由表是空的,通過以下方式逐步形成自己的路由表:

  1. 非首次啟動,從曾經儲存過的路由表檔案中直接讀取;
  2. 首次啟動,從超級節點中讀取;
  3. 首次啟動,沒有超級節點,則在download檔案的郭晨各種逐步形成;
  4. 動態重新整理,每次上傳/下載都按照一定規則建立/重新整理路由表。

實際上,DHT是把Tracker集中維護的所有種子的peers-list資訊利用DHT的方法雜湊並儲存到所有的DHT網路中的節點上去,然後在此基礎上提供查詢的方法。在DHT中實現了兩種型別的查詢,一種是查詢node(find_node),另一種是查詢peers(get_peers)。
查詢node過程如下:

  1. 如果節點x需要查詢節點y,則x計算xor(x,y)並從本地K桶中得到k個比較closer的節點;
  2. 然後向這些比較close的k個節點繼續詢問它是否有離y更近的節點,這些k個節點當然也從自己的對應的K桶中返回k個更近的節點給x;
  3. x然後再從返回結果中選取k個more closer節點重複上面的動作,直到不能返回更近的節點為止,則最後找到的k個節點即為the most closest nodes;
  4. 在這個過程中返回的任何k個close的節點都會嘗試去插到自己的路由表中去。

查詢peers過程如下:而x查詢peers-list的方法則和上面查詢節點的方法類似,不同的是它是以info-hash作為引數進行查詢,並且如果在查詢過程中有任何一個節點返回了(info-hash, peers-list)對則提前結束查詢。

當一個節點通過上面方法得到了peers-list後,則會試圖對每個peers主動發起TCP的連線繼續後面真實的下載過程,同時會把自己的peer資訊傳送給先前的告訴者和自己K桶中的k個最近的節點儲存該peer-list資訊。該資訊在該k個節點上可以儲存24個小時,24小時後如果沒有收到x傳送的更新訊息則失效。因此,一個活動節點是儲存了兩部分資訊:一份是本地的路由表,另一份是

2.Merkle Tree和Merkle DAG

Merkle Tree
Merkle Tree,通常也被稱作Hash Tree,顧名思義,就是儲存hash值的一棵樹。Merkle樹的葉子是資料塊(例如,檔案或者檔案的集合)的hash值。非葉節點是其對應子節點串聯字串的hash。

  • 雜湊演算法(Hash)又稱雜湊函式、雜湊技術、摘要。
  • 雜湊演算法是可以將任意長度的資料對映成固定長度的資料的函式,對一份資料進行雜湊運算的結果一般都是唯一的
  • 只要原文發生改變,雜湊運算的結果就會完全不一樣。
  • 雜湊逆運算在數學上是不可能的。
  • 主要用於數字簽名、錯誤檢驗等場景。
  • 雜湊碰撞:對不同的資料進行雜湊運算產生相同的結果。概率極小
  • 常見的hash演算法有MD5以及SHA系列。

在穩定伺服器的場景中,從伺服器下載資料後,採用單一的雜湊進行檢驗。如果雜湊結果不正確,說明資料在傳輸過程中發生錯誤。此時,需要重新下載整份資料,這是方法的效率是很低的。
在在點對點網路的場景中,由於節點機器被認為是不穩定或不可信的,為了校驗資料的完整性,更好的辦法就是將大份資料分割成許多小的資料塊來儲存和傳輸。這樣做的好處就是,當資料出錯時,只需要對錯誤的資料進行重傳。
第一種方法就是Hash List:

點對點下載的時候,在真正地下載資料之前,會先下載一個Hash列表,該Hash列表就是各個資料塊的Hash值。然後從可信的伺服器獲取根hash(就是圖中的top hash),用根hash來校驗hash列表。校驗過程是:將Hash列表的所有hash按順序結成字串,再做一次Hash運算,結果與根Hash對比。
第二種方法就是Merkle Tree,
跟Hash List一樣,Merkle Tree先計算小資料塊的hash值,然後按順序將相鄰的hash合併成字串,再計算該字串的hash,逐級計算,最終得出樹根Merkle Root。

點對點下載的時候,從可信源獲取Merkle Root,從不可信源獲取Merkle Tree,這樣就這一檢驗資料是否有錯誤。與Hash List不同的是,Merkle Tree可以直接下載並立即檢驗樹的一個分支:如果資料塊錯誤,需要下載完整的Hash List來驗證,而Merkle tree只需要下載一個分支並立即驗證,不同在下載另一個分支,以此類推。

Merkle Tree的特點:

  1. MT是一種樹,大多數是二叉樹,它具有樹結構所有的特點;
  2. MT的葉子節點的值可以是小資料塊的hash或小資料塊;
  3. 非葉子節點的值都是其子節點值的hash結果。

詳細的Merkle Tree演算法解析請點選

Merkle DAG
Merkle DAG的全稱是 Merkle directed acyclic graph(默克有向無環圖),它是在Merkle tree基礎上構建的。Merkle DAG跟Merkle tree很相似,區別在於:Merkle DAG不需要進行樹的平衡操作,非葉子節點允許包含資料等。
IPFS的Merkle DAG是由Git改造而來的,定義了一組物件:

  • Blob-一個大小可變的資料塊(等於或小於256KB)。Blob物件代表一個檔案且包含一個可定址的資料單元,用來儲存使用者的資料。Blob沒有links。
  • List-塊或者其他連結串列的集合。List物件代表著由幾個blob物件連線而成的大檔案或者重複資料刪除檔案。List中包含有序的blob序列或者其他list 物件。
  • Tree-塊、連結串列或者而其他樹的集合。Tree代表一個目錄,一個名字到雜湊值的對映。雜湊值則代表了bolbs、lists和其他trees。
  • Commit-任何物件在版本歷史記錄中的一個快照。他同樣連線著父提交。

Merkle DAG擁有如下的功能:

  • 內容定址:使用多重雜湊來唯一識別一個資料塊的內容
  • 防篡改:可以方便的檢查雜湊值來確認資料是否被篡改
  • 去重:由於內容相同的資料塊雜湊是相同的,可以很容去掉重複的資料,節省儲存空間

詳細的Git命令解釋請點選

3.Bittorrent和BitSwap

點對點的資料傳輸

  • 資料不是儲存在中心化的伺服器,而是儲存在各個節點上。
  • 節點是對等的,節點即是客戶端,又充當伺服器的角色。

Bittorrent
特點:

  • 一種點對點傳輸的網路協議。
  • 對於一個檔案,下載的使用者數越大,下載速度就越快。
  • 部分的網路擁堵或伺服器宕機並不會對整個傳輸鏈路造成太大的影響。
  • 常見的BT軟體有:迅雷、QQ旋風、位元精靈等。

存在問題:

  • 節點只索取不貢獻,導致資料交換的效率極速下降,甚至點對點網路癱瘓。
  • 容易遭受女巫攻擊,即惡意機器不斷請求,佔用本機上傳頻寬。

BitSwap
IPFS在BitTorrent的基礎上實現了p2p資料交換協議:BitSwap協議。
IPFS每一個節點都維護了兩個列表:

  • 已有的資料塊(have_list)
  • 想要的資料塊(want_list)

當兩個節點建立連線後,他們會根據hava_list和want_list互通有無。跟BitTorrent不一樣的是:BitSwap獲取資料塊的時候不限於從同一個torrent裡面。也就是說BitSwap可以從不屬於本檔案的其他檔案獲取資料塊(只要資料塊的雜湊值一樣,資料內容必然是一樣的,同樣的資料塊只會保留一份)。從全域性考慮,這使得BitSwap的效率相比於BitTorrent更高。
對於p2p網路,有一個很重要的問題是:如何激勵大家分享自己的資料?IPFS實現了自己的特殊的資料分享策略。IPFS的策略體系由信用、策略、賬單組成。
後期將會使用filecoin來實現激勵策略

信用體系:BitSwap協議必須能夠激勵節點去樂於分享資料,即使這個節點暫時沒有資料需求。IPFS根據節點的之間的資料收發建立了一個信用體系:傳送給其他節點資料可以增加信用值;從其他節點接受資料降低信用值。如果一個節點只接收資料而不分享資料,信用值就會降得很低而被其他節點忽略掉。
簡單來講就是:你樂於分享資料,其它節點也樂於傳送資料給你,如果你不願意分享,那麼其它節點也不願意給你資料。

賬單:BitSwap節點會記錄下來和其他節點通訊的賬單(資料收發),可以保持節點間資料交換的歷史和防止篡改。當兩個節點之間建立連線的時候,BitSwap會相互交換賬單資訊,如果賬單不匹配,則清除重新記賬。惡意節點可能會故意“丟失”賬單,以希望清除掉自己的債務。其它互動節點會把這些都記下來,如果總是發生故意“丟失”賬單的情況,該節點就會被拒絕。

實現策略:根據上面的信用體系,BitSwap可以採取不同的策略來實現,每一種策略都會對系統的整體效能產生不同的影響。策略的目標是:

  • 節點資料交換的整體效能和效率最高;
  • 阻止“吃白食”(freeloaders)的現象,即就是不能夠只下載資料不上傳資料;
  • 可以有效的防止一些攻擊行為(比如:女巫攻擊)
  • 對信任節點建立寬鬆機制(lenient)

IPFS提供一個可參考的策略機制(實際的實現可以有所變化)

4.IPNS

到目前為止,IPFS堆疊形成了構建內容定址物件 DAG 的P2P交換。它可以用於釋出和檢索不可變的物件,甚至可以跟蹤這些物件的版本歷史。但是,仍缺少一個關鍵元件:可變命名。沒有它,使用者就得在IPFS系統外獲取到新的內容地址了。

自驗證命名
1.將節點公鑰的雜湊結果定義節點的NodeId;
2.通過 /ipns/NodeId的方式可以訪問該節點下的內容;
3.當其他節點從該節點獲取檔案時,可以先驗證其公鑰和NodeId是否匹配,以到達檔案物件的真實性。
通過自驗證命名,我們可以實現這樣的訪問效果/ipns//docs/test.md而不必用/ipfs/

場景模擬

  1. 加入IPFS網路,在網路中搜尋叫ABC的檔案(通過IPNS——去中心化的檔案命名系統)

  2. IPFS網路迅速索引區塊鏈上的雜湊值,反饋出搜尋結果。

  3. 你支付一點FileCoin代幣, 獲取ABC檔案快取到本地,ABC檔案不是從雲或者伺服器上下載下來的,而是由這個網路的參與者貢獻的,它可能是離你最近的一個網路節點。這樣的好處就是不僅不需要中間伺服器,而且網路效率最快。

  4. 如果ABC檔案恰好你周邊好幾個人都有,那IPFS網路會把這個檔案拆成一小片一小片,節省了這些節點的儲存成本,也讓你用最具效率的方式下載到該視訊。

  5. 這個視訊檔案快取在自己電腦裡,不僅自己觀看,同時也為其他人提供資源。

  6. 另外也可以自己釋出新內容到這個網路上,並且有機會獲得FileCoin代幣,因為你也為網路做了貢獻。