IPFS(The InterPlanetary File System) は P2P でファイル共有を行うプロトコルです。

IPFS の紹介は postd にわかりやすい翻訳記事があります: IPFS 入門 : 新たな P2P ハイパーメディア分散プロトコル

とてもおおざっぱに言えば「HTTP の置き換えを目指したバージョン管理ができてディレクトリも扱える P2P 分散ファイル共有のための仕組み(プロトコル)」です。
ここでは以下の環境で実際に IPFS を使ってみます。

動作環境

  • Debian-9
  • IPFS-0.4.7

インストール

IPFS のコマンドインタフェースは Go 言語で記述されています。アカーブファイルをダウンロードし install.sh を実行すると /usr/local/bin 以下に ipfs コマンドを配置します。

https://ipfs.io/docs/install/

$ wget https://dist.ipfs.io/go-ipfs/v0.4.7/go-ipfs_v0.4.7_linux-amd64.tar.gz
$ tar xvf go-ipfs_v0.4.7_linux-amd64.tar.gz
$ cd go-ipfs
$ sudo ./install.sh
$ ls /usr/local/bin/ipfs
/usr/local/bin/ipfs*
$ ipfs --version
ipfs version 0.4.7

準備

ipfs を実行するまえに、初期化とデーモンの起動を行います。

初期化

$ ipfs init

~/.ipfs 以下に IPFS のファイル郡が生成されます。
IPFS の設定は ~/.ipfs/config です。初期状態では最大 10GB を IPFS 用のストレージとして確保します。

ipfs デーモンの起動

8080/tcp で待機する IPFS のデーモンを起動します。このデーモンを介して他の IPFS とやりとりを行います。

このデーモンを起動しておかないと ipfs 実行時に「Error: merkledag: not found」のエラーが発生します。#85

// 8080/tcp で listen する
$ ipfs daemon
Daemon is ready

今のところ ipfs daemon stop のようなコマンドはないので、kill $PID で停止します。

実行

ファイルの追加

なんらかのファイルを IPFS に追加します。
追加するとすぐに IPFS ネットワークで共有されます。

$ echo "hello" > test.txt
$ ipfs add test.txt
added QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN test.txt

※データが同じなら別ホストから add したファイルも同じハッシュ値なる

ファイルの取得

追加したファイルは IPFS 経由で取得することが可能です。

ファイルに保存

オブジェクトのデータをローカルファイルに保存します。

※保存されるファイル名は ipfs add で指定したファイル名ではなくハッシュ値です

$ ipfs get QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN
$ ls QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN
QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN
$ cat QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN
hello

内容を直接 cat で出力することもできます。

$ ipfs cat QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN
hello

オブジェクトのデータを取得

共有されている ipfs オブジェクトのデータを取得します。

$ ipfs object get QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN
{"Links":[],"Data":"\u0008\u0002\u0012\u0006hello\n\u0018\u0006"}

その他のコマンド

ipfs コマンドリファレンス

ログ

※ ipfs daemon が動いている必要がある

// peer ログを tail 形式で表示
$ ipfs log tail

状態の確認

// 使用しているネットワーク帯域を確認
% ipfs stats bw
Bandwidth
TotalIn: 343 MB
TotalOut: 115 MB
RateIn: 4.2 kB/s
RateOut: 1.3 kB/s

// リポジトリの状態
$ ipfs stats repo
NumObjects       41
RepoSize         4798894
RepoPath         /home/garin/.ipfs
Version          fs-repo@5

ローカルのハッシュを確認

ローカルに保存されているオブジェクトのハッシュをリストします。

$ ipfs refs local

追加したオブジェクトの確認

ipfs add で追加したオブジェクトは ipfs pin のリストに自動で保存されます。

// 新しいオブジェクトを追加
$ echo "hello" | ipfs add -q
QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN

$ ipfs pin ls | grep recursive
QmRnF2MLkznVyV91q7DBPy2AMbbqdCipD8epoNHMtXp8YH recursive
QmSb8DSVmu4Qip56jcqPVz1Cx9RJ3vTf3d1Gf9ixaG2tWg recursive
QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN recursive  # 追加したオブジェクト
QmXsb5VFkkJHG9L7Rsux7vsQVReJEnZFZL5JM68f35HfU8 recursive
QmVLDAhCY3X9P2uRudKAryuQFPM5zqA3Yij1dY8FpGbL7T recursive

ipfs object と組合せてローカルに保存されているオブジェクトの内容を確認できます。

$ ipfs pin ls  --type=recursive | cut -d' ' -f 1 | xargs -n 1 ipfs object get
{"Links":[],"Data":"\u0008\u0002\u0012\u001bLook! Things have changed!\n\u0018\u001b"}
{"Links":[],"Data":"\u0008\u0002\u0012\u001cLet's have some mutable fun\n\u0018\u001c"}
{"Links":[],"Data":"\u0008\u0002\u0012\u0006hello\n\u0018\u0006"}
...

手動で pin add して pin に追加することもできます

// 上記のオブジェクトを pin する
$ ipfs pin add QmRnF2MLkznVyV91q7DBPy2AMbbqdCipD8epoNHMtXp8YH
pinned QmRnF2MLkznVyV91q7DBPy2AMbbqdCipD8epoNHMtXp8YH recursively

// pin に保存したオブジェクトを確認
$ ipfs pin ls | grep recursive
QmRnF2MLkznVyV91q7DBPy2AMbbqdCipD8epoNHMtXp8YH recursive