IPFS の紹介

IPFS とは

IPFS とは P2P 技術を用いた分散ファイルシステムです。最近話題の "Dapps" で利用される事例が増えています。
IPFS は HTTP で提供されている Web の世界をより良いものとする事を目的としています。

IPFS is the Distributed Web

詳細はホワイトペーパーに記述されているので、そちらを参照してください。

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

非公式ですが、日本語で且つ非常に詳しく説明しているスライドもあります。

Introduction to the IPFS // Speaker Deck

この記事は主に IPFS の技術に関する内容をまとめたものです。
以下の構成になります。

IPFS のスタックと簡単な説明

IPFS は以下のスタックで構成されています。

(merkledag 部分は現在IPLD として定義されているため、Data Format と変更しています。)

specs/architecture at master · ipfs/specs · GitHub

Naming

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

Data Format

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-dag

merkle-links を持つオブジェクトはグラフ (merkle-graph) を形成します。
リンクの参照は必ず有向 (Directed) なので、 非巡回 (Acyclic) となります。
したがって、merkle-links を使用するグラフは DAG (merkle-dag) となります。

merkle-path

merkle-path は Unix スタイルのパス (/a/b/c/d) と同じですが、参照されたノードからまた別のノードへのアクセスを可能とします。

IPLD Data Model

IPLD Data Model は複数の制約をもった json ベースの構造をしたオブジェクトです。

specs/ipld at master · ipld/specs · GitHub

IPLD Serialized Formats

IPLD は シリアライズされたデータを任意のデータ形式にコーデックすることができます。
言語によってサポートされているフォーマットは異なりますが、Golang 実装は JSON, CBOR, Protocol Buffers, Message Pack などがサポートされています。

Exchange

IPFS ではデータブロック交換のためのプロトコル BitSwap を利用しています。
IPFS ノードがネットワークからデータブロックをフェッチする要求を処理します。 他の IPFS ノードの BitSwap エージェントと相互作用し、必要に応じてデータブロックをフェッチします。

specs/bitswap at master · ipfs/specs · GitHub

Routing

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

Peer Routing はネットワーク内の他のピアが見つかるまで意図的にクエリを発行します。
DHT の他に、新しく Delegated Peer Routing を開発中です。

Content Routing

Content Routing はコンテンツがネットワーク内のどこにあるかを見つける方法を提供します。
こちらも Delegated Content Routing を開発中です。

Network

Network は以下のスタックに分かれます。

Swarm

ストリームマルチプレクサ、NAT トラバーサル、接続の中継、マルチトランスポート(TCP, UDP, UTP, SPDY, TLSなど) に関わる全てを処理します。

Discovery

接続可能なピアを検索します。
以下の実装があります。

specs/4-architecture.md at master · libp2p/specs · GitHub

Distributed Record Store (IPRS)

go-iprsjs-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 を用いたアプリケーション

IPFS の issue にまとめられているので、そちらのリンクから最新情報を辿ることができます。
Outline the Various Applications of IPFS, with Use Cases and Dependencies · Issue #230 · ipfs/ipfs · GitHub

リファレンス

以下のリンク先の情報を参考にして作成しました。