Interplanetary File System(IPFS)は、ピアツーピアのファイルストレージネットワークです。従来の Web ホスティングのように単一サーバーへファイルを置くのではなく、世界中の多数のコンピューターにファイルを分散します。
どのコンピューターも、IPFS ソフトウェアをインストールすれば IPFS ネットワークに参加し、ファイルのホストと配信を始められます。
誰かが IPFS ネットワークにファイルをアップロードすると、IPFS を動かしているほかの人もそのファイルを閲覧・ダウンロードできます。中央サーバーは介在しません。
IPFS に追加したファイルには、ファイル内容のハッシュから導出した一意のアドレスが付きます。このアドレスをコンテンツ識別子(Content Identifier、CID)と呼びます。CID には、ファイルのハッシュと、使ったハッシュアルゴリズムの識別子という 2 つの情報が、1 つの文字列にまとめて入ります。
CID は内容そのものから決まるため、同一のファイルは常に同じ CID になり、ファイルを少しでも変えると別の CID になります。これが IPFS を「コンテンツアドレス方式」にしている理由です。保存場所ではなく、中身でファイルを探します。
IPFS はデフォルトで SHA-256 ↗ を使い、結果を Base58 ↗ でエンコードします。Base58 は、ゼロと大文字の O など見た目が紛らわしい文字を除き、転記ミスを減らすエンコード方式です。
CID は次のような見た目です: QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco
IPFS はほかのエンコード(Base32 ↗)やハッシュアルゴリズム(SHA-3 ↗、BLAKE2 ↗)にも対応しています。
IPFS は、どのコンピューターがどのファイルを持つかを 分散ハッシュテーブル(Distributed Hash Table、DHT) ↗ で追跡します。DHT は、CID をそのコンテンツをホストしているコンピューターのネットワークアドレスへ対応付ける検索システムです。ルックアップテーブル全体を 1 台が持つことはありません。各コンピューターが一部を保持し、残りがどこにあるかを知っています。
IPFS へコンテンツを「アップロード」するとは、中央サーバーへファイルを送ることではありません。ファイルの CID と自分のネットワークアドレスを対応付けるエントリを DHT に追加し、そのコンテンツを持っていることをネットワークに知らせることです。ほかの人がそのファイルをダウンロードしたいときは、DHT で CID を調べ、あなたのアドレスを見つけ、あなたから直接データを取得します。
同じファイルを複数のコンピューターがホストできるため、ダウンロードはその全体に分散します。1 台のホストがオフラインになっても、ほかのホストが配信を続けます。この冗長性が、単一サーバーホスティングに対する IPFS の速度と信頼性の利点です。
アップロードできるのは個別ファイルだけではありません。たとえば example というフォルダーがあり、中身が I'm trying out IPFS という文字列だけを含む example_text.txt 1 ファイルだとします。
このフォルダーを ipfs add -r ./example コマンドでアップロードすると、フォルダーとその中のファイルのそれぞれに CID が付きます。この例では、フォルダーの CID は QmdbaSQbGU6Wo9i5LyWWVLuU8g6WrYpWh2K4Li4QuuE8Fr、ファイルの CID は QmXnnyufdzAWL5CqZ2RnSNgPbvCc1ALT73s6epPrRnZ1Xy です。
ファイルには次の 2 通りでアクセスできます。
- ファイルを直接リクエストする:
https://cloudflare-ipfs.com/ipfs/QmXnnyufdzAWL5CqZ2RnSNgPbvCc1ALT73s6epPrRnZ1Xy - ディレクトリからファイル名でリクエストする:
https://cloudflare-ipfs.com/ipfs/QmdbaSQbGU6Wo9i5LyWWVLuU8g6WrYpWh2K4Li4QuuE8Fr/example_text.txt
ファイルの CID は、ファイル自体が変わったときだけ変わります。一方、ディレクトリの CID は、中のファイルが 1 つでも 変わったとき、またはファイルの追加・削除があったときに変わります。
ディレクトリを使うと、静的サイト全体を 1 つの CID でアドレス指定し、ディレクトリ内の別ファイルをリクエストして各ページにアクセスできます。
その他の概念は、IPFS ↗ のドキュメントを参照してください。