†IPFSを実行しながら学んでいく1†
††学んだ内容をメモメモ††
IPFS(InterPlanetary File System)とはP2Pネットワーク上で動作するハイパーメディアプロトコルとその実装 と定義されています。
ファイル、Webサイト、アプリケーション、データを保存およびアクセスするための分散システムともとれます。
https://dev.classmethod.jp/articles/aaaaaaa/
や/Users/mori.ryosuke/items/aaaa.txt
,C:\Users\mori.ryosuke\My Documents\aaaa.txt
のような現在も使われているURLやファイルパスはロケーション指向と言われ、場所を指定しています。
IPFSは場所ではなく、ファイルの内容またはコンテンツによってファイルのアドレスを指定します(コンテンツ指向)。
例) /ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Aardvark.html
/ipfs/ 後の文字列はコンテンツ識別子(CID)と呼ばれていて、IPFSが複数の場所からコンテンツを取得する方法となります。 暗号化されたハッシュで、元のコンテンツに固有のものです。
IPFSは、コンテンツが一つの場所で管理されていない(複数の場所から同じものを取得できる)ので、
- 回復力が高い
- コンテンツが存在する場所(サーバ等)がダウンしても、他の場所から同じものを取得できる
- 検閲を困難にする
- IPFS上のファイルはさまざまな場所から取得される可能性があるので、どこかのサーバがアクセスを遮断されても、他のどこかの別のサーバから同一の情報が取得可能になり、検閲が難しい
- スピードアップ
- より近いサーバから取得することになるので、一つのサーバーに負荷が集中することを防ぎ、ファイルをより速く取得することができる
といったメリットが挙げられます。
では、実際にIPFSがどんな感じで使えるのか、IPFSのコマンドラインツールを使って試していきます。
インストール
Goで記述されたリファレンス実装であるgo-ipfsをインストールします。
各OSごとのインスtーる方法は以下に。 - Windows - Mac - Linux
使用しているローカルPCはM1 Macなので
$ curl -O https://dist.ipfs.io/go-ipfs/v0.13.0/go-ipfs_v0.13.0_darwin-amd64.tar.gz $ tar -xvzf go-ipfs_v0.13.0_darwin-amd64.tar.gz $ cd go-ipfs && bash install.sh
でインストールします。
$ ipfs --version ipfs version 0.13.0
インストールされたかを確認します。
初期化
IPFSはすべての設定と内部データをリポジトリと呼ばれるディレクトリに保存します。
ipfs init
で初期化できます。
実行結果
generating ED25519 keypair...done peer identity: 12D3KooWHQjFYK75BGHkbsxAFPs8gGJUSwt8c5JEFt3QMCseBBsF initializing IPFS node at /Users/mori.ryosuke/.ipfs to get started, enter: ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
実行ユーザーのホームディレクトリの直下に.ipfs
というフォルダがつくられます(=IPFSのリポジトリ)。
コンテンツ内容を取得
init実行後、最後に出力されたコマンドを実行します。
ipfs cat
はIPFSネットワーク上に保存されているファイルの内容を取得するコマンドです
$ ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme Hello and Welcome to IPFS! ██╗██████╗ ███████╗███████╗ ██║██╔══██╗██╔════╝██╔════╝ ██║██████╔╝█████╗ ███████╗ ██║██╔═══╝ ██╔══╝ ╚════██║ ██║██║ ██║ ███████║ ╚═╝╚═╝ ╚═╝ ╚══════╝ If you're seeing this, you have successfully installed IPFS and are now interfacing with the ipfs merkledag! ------------------------------------------------------- | Warning: | | This is alpha software. Use at your own discretion! | | Much is missing or lacking polish. There are bugs. | | Not yet secure. Read the security notes for more. | ------------------------------------------------------- Check out some of the other files in this directory: ./about ./help ./quick-start <-- usage examples ./readme <-- this file ./security-note
コンテンツ追加
何かファイルを作成し、それをIPFSのレポジトリに追加してみます。
$ echo "hoge" > hoge.txt $ cat hoge.txt hoge
追加には、ipfs add
コマンドを使用します。
$ ipfs add hoge.txt added QmTY2kZZgvgjsivUo4hKjAmqcDHehGyDjueUzeK9At33Xb hoge.txt
ipfs add
は、指定したファイルの内容をIPFSオブジェクト」してIPFSのリポジトリに登録します。
QmTY2kZZgvgjsivUo4hKjAmqcDHehGyDjueUzeK9At33Xb
がそのコンテンツを示すコンテンツID(CID)です。
ipfs cat
を実行すると、中身が確認できました。
$ ipfs cat QmTY2kZZgvgjsivUo4hKjAmqcDHehGyDjueUzeK9At33Xb hoge
<<参考>>
指定したファイルのデータからMerkleDAGを作るのがipfs add
コマンド。
特定のファイルの「ハッシュ」は、実際にはDAGのルート(最上位)ノードのハッシュ。
ファイル名だけ変えたらどうなる?
hogehoge.txtという¥ファイルを作成します。内容はhoge.txtと同じにします。
このファイルをaddすると
$ echo "hoge" > hogehoge.txt $ cat hogehoge.txt hoge $ ipfs add hogehoge.txt added QmTY2kZZgvgjsivUo4hKjAmqcDHehGyDjueUzeK9At33Xb hogehoge.txt
IPFSはコンテンツの内容をもとにCIDが作られるので、hoge.txtと同じCIDがふられることになりました。
$ ipfs cat QmTY2kZZgvgjsivUo4hKjAmqcDHehGyDjueUzeK9At33Xb hoge
hoge.txtやhogehoge.txtという場所を指定せずに中身を取得するということが体験できました。
ブロック?オブジェクト?
IPFSでは、ブロックはキー(ハッシュ)で識別される1つのデータ単位で、どのような種類のデータでもよく、必ずしも何らかの形式が関連付けられている必要はない。
オブジェクトはMerkle DAG protobufのデータ形式に従ったブロック
と定義されています。
※ Merkle DAG: ハッシュ木 とも呼ばれる
オブジェクトをコマンドで色々試す
先ほどから実行してきたipfs add
は、コンテンツやディレクトリをIPFSオブジェクト
として追加するものです。
IPFSはコンテンツのサイズが256KBを超える場合は分割して保存するというのが仕様になっています(UnixFSデータ形式に従う)。
実際に試してみます。郵便局の郵便番号データを用います。
$ ipfs add KEN_ALL.CSV added Qme1M1uCBJZaCVojeLNbzHkLchoQLBmJMYAJEsSfeBWNCa KEN_ALL.CSV $ ipfs cat Qme1M1uCBJZaCVojeLNbzHkLchoQLBmJMYAJEsSfeBWNCa ~~~~
KEN_ALL.CSVは12MBほどのサイズなので仕様に従って分割されるはずです。
分割されたサブブロックを確認するには、<code>ipfs ls</code>コマンドを使用します。
$ ipfs ls Qme1M1uCBJZaCVojeLNbzHkLchoQLBmJMYAJEsSfeBWNCa QmZHj97h6y666Jq3URg5bdfSHsn4tzCnRuF4a7QbtWBdmx 262144 Qma6FoFH6YuCoqQXTCyQJNhPayvH62RbMDYo1A2YWAyB3S 262144 Qmcn1R3T8xZSxkdUdzTg8zZsAmbMRLGC4STKoAHuMhTchm 262144 QmRsP9HHWsUDr8FpewWpRyxVd55Aq42bsNEmcTCVdbnyjy 262144 QmTRZHHfExWuWPatzp9Qav4eu6yEoHcW3YVsG9tVuqavoL 262144 QmPxzn6z8GWWwva7v5rtsNrNAhu2LzT47xNBSuEc17XWSD 262144 QmU4aN9f24NrUUrrNLRi6qiSg9PTXFsE6QZPbHY7xGmi6k 262144 QmWgyZwmyaNvLezgQZNAB9o94apk7eapyxwBiRCZGMCFFr 262144 ~~~ 省略 ~~~ QmYFzF22PinsQZsjwHU6ooiQ9vTf4sjvAbEHRfFiJAT1hP 16279
ファイルのすべての直接のサブブロックと、それらのサイズおよびディスク上の子が表示されます
各サブブロックのハッシュをcatして、分割されたコンテンツの中身を見ることができます。
$ ipfs cat QmYFzF22PinsQZsjwHU6ooiQ9vTf4sjvAbEHRfFiJAT1hP
ipfs add
は、コンテンツやディレクトリをIPFSオブジェクトとして追加するもの とありますが、オブジェクトの実態を確認するコマンドもあります。
ipfs object get
で、KEN_ALL.CSVのルートハッシュで試してみたところ
$ ipfs object get Qme1M1uCBJZaCVojeLNbzHkLchoQLBmJMYAJEsSfeBWNCa { "Links": [ { "Name": "", "Hash": "QmZHj97h6y666Jq3URg5bdfSHsn4tzCnRuF4a7QbtWBdmx", "Size": 262158 }, ... ... ], "Data": "\b\u0002\u0018 <<省略>>" }
オブジェクトは上記のようなデータ構造となっていました
- Links
- 分割されたIPFSオブジェクトへのリンク(IPFSリンク)の配列
- Data
- オブジェクトの中身(unicode)
です。
Linksの一つのハッシュに対してipfs object get
を実行すると、Linksは空の配列になりました(これ以上分割されていないから)。
ブロックをコマンドで色々試す
オブジェクトはMerkle DAG protobufのデータ形式に従ったブロック なので、先ほど実行したipfs object get
の代わりにブロックを扱うコマンド(ipfs block get
)もつかえるのでは?
$ ipfs block get QmRAX8dJYRPmdugaskCQaB6wd94wZaR1DxPp15S689pNdq ��マグントクノシマチョウ","トクワセ","鹿児島県","大島郡徳之島町","徳和瀬",0,0,0,0,0,0 46530,"89174","8917424","カゴシマケン","オオシマグントクノシマチョウ","トドロキ","鹿児島県","大島郡徳之島町","轟木",0,0,0,0,0,0 46530,"89174","8917426","カゴシマケン","オオシマグントクノシマチョウ","ボマ","鹿児島県","大島郡徳之島町","母間",0,0,0,0,0,0 46530,"89171","8917103","カゴシマケン","オオシマグントクノシマチョウ","ミナミハラ","鹿児島県","大島郡徳之島町","南原",0,0,0,0,0,0 ~~~~ 省略 ~~~~
実行してみると、生データを読み取ることができました。今回だとCSV形式のテキストファイルですね。
ipfs block stat
では、特定のブロックの正確なサイズ(子なし)がわかります。
$ ipfs block stat QmRAX8dJYRPmdugaskCQaB6wd94wZaR1DxPp15S689pNdq Key: QmRAX8dJYRPmdugaskCQaB6wd94wZaR1DxPp15S689pNdq Size: 135529 $ ipfs block stat QmUYvfWLpAUBNRxPvGDFeup4Gfvn4ZYbUZTV2JynVhLoMm Key: QmUYvfWLpAUBNRxPvGDFeup4Gfvn4ZYbUZTV2JynVhLoMm Size: 262158
今日はここまで。
途中経過
IPFSの学びのため、IPFSのコマンドラインツールを用いて色々と実行していきました。
今回はIPFSへのコンテンツ追加が中心でした。
https://docs.ipfs.io/ をベースにして引き続き試していく予定です。