IPFS とは P2P 技術を用いた分散ファイルシステムです。最近話題の "Dapps" で利用される事例が増えています。
IPFS は HTTP で提供されている Web の世界をより良いものとする事を目的としています。
詳細はホワイトペーパーに記述されているので、そちらを参照してください。
IPFS - Content Addressed, Versioned, P2P File System (DRAFT 3)
非公式ですが、日本語で且つ非常に詳しく説明しているスライドもあります。
Introduction to the IPFS // Speaker Deck
この記事は主に IPFS の技術に関する内容をまとめたものです。
以下の構成になります。
IPFS は以下のスタックで構成されています。
(merkledag 部分は現在IPLD として定義されているため、Data Format と変更しています。)
specs/architecture at master · ipfs/specs · GitHub
IPFS はルーティングシステムを利用してノード ID とオブジェクトのハッシュを紐づける機能 IPNS を提供しています。
(DNS の様な機能)
Publisher の実装は以下の2つ
また Resolver の実装は以下の4つの方法があります。
go-ipfs/namesys.go at master · ipfs/go-ipfs · GitHub
最新版の IPFS 0.4.14 では pubsub での Publisher と Resolver が追加されました。
この機能を有効にするとリアルタイムで公開・解決が可能となります。
go-ipfs 0.4.14 released
IPFS では各ノード間で通信が行われるデータフォーマット IPLD を利用しています。
簡単に説明すると横断可能な merkle-links を保持した json フォーマットです。
IPLD では以下を定義します。
Juan Benet: Enter the Merkle Forest
specs/ipld at master · ipld/specs · GitHub
merkle-links は、コンテンツアドレスを持ち暗号化された2つのオブジェクト間のリンクです。
リンクされたオブジェクトを、ハッシュを用いて整合性を確認することができるため、変更不可能なデータ構造となります。
以下が link オブジェクトの例です。
{ "/" : "/ipfs/QmUmg7BZC1YP1ca66rRtWKxpXp77WgVHrnv263JtDuvs2k" }
// "/" link key
// "/ipfs/QmUmg7BZC1YP1ca66rRtWKxpXp77WgVHrnv263JtDuvs2k" link
merkle-links を持つオブジェクトはグラフ (merkle-graph) を形成します。
リンクの参照は必ず有向 (Directed) なので、 非巡回 (Acyclic) となります。
したがって、merkle-links を使用するグラフは DAG (merkle-dag) となります。
merkle-path は Unix スタイルのパス (/a/b/c/d) と同じですが、参照されたノードからまた別のノードへのアクセスを可能とします。
IPLD Data Model は複数の制約をもった json ベースの構造をしたオブジェクトです。
specs/ipld at master · ipld/specs · GitHub
IPLD は シリアライズされたデータを任意のデータ形式にコーデックすることができます。
言語によってサポートされているフォーマットは異なりますが、Golang 実装は JSON, CBOR, Protocol Buffers, Message Pack などがサポートされています。
IPFS ではデータブロック交換のためのプロトコル BitSwap を利用しています。
IPFS ノードがネットワークからデータブロックをフェッチする要求を処理します。 他の IPFS ノードの BitSwap エージェントと相互作用し、必要に応じてデータブロックをフェッチします。
specs/bitswap at master · ipfs/specs · GitHub
IPFS では以下 2つの Routing インターフェースが定義されています。
S/Kademlia DHT は Peer Routing であり、Content Routing でもあります。
Kademlia は木構造型の DHT を持つ P2P システムで、S/Kademlia は Kademlia をよりセキュアにした実装になります。
ホワイトペーパー内では Coral DSHT の実装について言及していますが、現在はまだ未実装です。
Implement peer-discovery interface · Issue #222 · libp2p/go-libp2p · GitHub
Peer Routing はネットワーク内の他のピアが見つかるまで意図的にクエリを発行します。
DHT の他に、新しく Delegated Peer Routing を開発中です。
Content Routing はコンテンツがネットワーク内のどこにあるかを見つける方法を提供します。
こちらも Delegated Content Routing を開発中です。
Network は以下のスタックに分かれます。
ストリームマルチプレクサ、NAT トラバーサル、接続の中継、マルチトランスポート(TCP, UDP, UTP, SPDY, TLSなど) に関わる全てを処理します。
接続可能なピアを検索します。
以下の実装があります。
specs/4-architecture.md at master · libp2p/specs · GitHub
go-iprs と js-iprs-record のリポジトリがあるが、両方とも他のプロジェクトでは使われていない。
仕様について書かれたドキュメントが一応あるが理解できず。
specs/iprs at master · ipfs/specs · GitHub
IPFS には大きく2つ JavaScript の実装 js-ipfs と Golang の実装 go-ipfs があります。
go-ipfs はModularity を高めるためのリファクタリングをしつつ、Core API の開発を進めています。
Core API を用いると Golang で IPFS 組込みのアプリケーションを作成することができます。そのため OpenBazaar の様に ユーザーは IPFS のインストールをすることなく、分散アプリケーションを利用することができます。
js-ipfs を用いると、ブラウザ拡張を必要とせず IPFS のフルノードの作成ができる様になりました。しかし、CPU使用率が高いのでCPU 利用率の改善を行っています。
また js-ipfs では IPNS がサポートされていませんが、今年の Q2 で実装される予定で、もし実現すればブラウザでの IPFS 利用が加速する可能性があります。
go-ipfs, js-ipfs それぞれの実装ステータス一覧はここで確認できます。
ipfs/IMPLEMENTATION_STATUS.md at master · ipfs/ipfs · GitHub
iPhone, Android 上で IPFS をフルノードで動かすこともできるようになってきたようです。
Android に関しては IPFSDroid があり、OpenBazaar が iOS で動作していると同社の CEO が記事にしています。
もしスマートフォンアプリ上で IPFS を動かしたい場合、はこちらの issue を参考にしてオプションの設定をすると良いかもしれません。
Low Power Mode · Issue #4137 · ipfs/go-ipfs · GitHub
Add low power init profile by magik6k · Pull Request #4154 · ipfs/go-ipfs · GitHub
また、IPFS は HTTP ベースの API を提供しており、クライアントの実装はメジャーな言語ほぼ全てで対応しています。
IPFS の issue にまとめられているので、そちらのリンクから最新情報を辿ることができます。
Outline the Various Applications of IPFS, with Use Cases and Dependencies · Issue #230 · ipfs/ipfs · GitHub
以下のリンク先の情報を参考にして作成しました。