IPFS Kubo を試してみる
はじめに
IPFS の Go 実装である Kubo を使ってノードを構築してみる
まずは Docker でお手軽にやってみる
Hello Kubo
mkdir hello-kubo
cd hello-kubo
mkdir -p export data/ipfs
touch start-ipfs-node.sh
docker run -d \
--name ipfs_host \
-v `pwd`/export:/export \
-v `pwd`/data/ipfs:/data/ipfs \
-p 4001:4001 \
-p 4001:4001/udp \
-p 127.0.0.1:8080:8080 \
-p 127.0.0.1:5001:5001 \
ipfs/kubo:latest
source start-ipfs-node.sh
docker logs -f ipfs_host
Changing user to ipfs
ipfs version 0.18.0
generating ED25519 keypair...done
peer identity: 12D3KooWN7ZWvXbvnDBR6hjq44MpgqVXv44Kg41SQjLxEDAVC3Xn
initializing IPFS node at /data/ipfs
to get started, enter:
ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
Initializing daemon...
Kubo version: 0.18.0-6750377
Repo version: 13
System version: amd64/linux
Golang version: go1.19.1
Computing default go-libp2p Resource Manager limits based on:
- 'Swarm.ResourceMgr.MaxMemory': "2.1 GB"
- 'Swarm.ResourceMgr.MaxFileDescriptors': 524288
Applying any user-supplied overrides on top.
Run 'ipfs swarm limit all' to see the resulting limits.
2023/01/24 07:47:22 failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size for details.
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip4/127.0.0.1/udp/4001/quic
Swarm listening on /ip4/127.0.0.1/udp/4001/quic-v1
Swarm listening on /ip4/127.0.0.1/udp/4001/quic-v1/webtransport/certhash/uEiBQSQNk2waz5Qhsbi-SDT2-uj1JWhxQJEja0yPGTcg7MQ/certhash/uEiC5cQtGdmYslVmXi0xhPlUUByUviUdj5isFc69F_QWKHw
Swarm listening on /ip4/172.17.0.2/tcp/4001
Swarm listening on /ip4/172.17.0.2/udp/4001/quic
Swarm listening on /ip4/172.17.0.2/udp/4001/quic-v1
Swarm listening on /ip4/172.17.0.2/udp/4001/quic-v1/webtransport/certhash/uEiBQSQNk2waz5Qhsbi-SDT2-uj1JWhxQJEja0yPGTcg7MQ/certhash/uEiC5cQtGdmYslVmXi0xhPlUUByUviUdj5isFc69F_QWKHw
Swarm listening on /p2p-circuit
Swarm announcing /ip4/127.0.0.1/tcp/4001
Swarm announcing /ip4/127.0.0.1/udp/4001/quic
Swarm announcing /ip4/127.0.0.1/udp/4001/quic-v1
Swarm announcing /ip4/127.0.0.1/udp/4001/quic-v1/webtransport/certhash/uEiBQSQNk2waz5Qhsbi-SDT2-uj1JWhxQJEja0yPGTcg7MQ/certhash/uEiC5cQtGdmYslVmXi0xhPlUUByUviUdj5isFc69F_QWKHw
Swarm announcing /ip4/172.17.0.2/tcp/4001
Swarm announcing /ip4/172.17.0.2/udp/4001/quic
Swarm announcing /ip4/172.17.0.2/udp/4001/quic-v1
Swarm announcing /ip4/172.17.0.2/udp/4001/quic-v1/webtransport/certhash/uEiBQSQNk2waz5Qhsbi-SDT2-uj1JWhxQJEja0yPGTcg7MQ/certhash/uEiC5cQtGdmYslVmXi0xhPlUUByUviUdj5isFc69F_QWKHw
Swarm announcing /ip4/202.208.152.34/udp/59081/quic
API server listening on /ip4/0.0.0.0/tcp/5001
WebUI: http://0.0.0.0:5001/webui
Gateway (readonly) server listening on /ip4/0.0.0.0/tcp/8080
Daemon is ready
IPFS コマンド実行
docker exec ipfs_host ipfs <args...>
下記は接続しているピアを一覧表示するコマンド
docker exec ipfs_host ipfs swarm peers
下記のような行が何十件も表示される
/ip4/123.123.123.123/tcp/4001/p2p/12D3KooWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ファイルの追加
echo 'Hello IPFS!' > export/message.txt
docker exec ipfs_host ipfs add -r /export/message.txt
12 B / 12 B 100.00%added QmYWAifyw2V5dEq7c5GgdSPffeKoYXQZggnYzw5RbXpig4 message.txt
追加したファイルはどうやって見れば良いのだろうか
IPFS ノードを server プロファイルで起動する
環境変数 IPFS_PROFILE
を "server" に指定すれば良い
docker run -d \
--name ipfs_host \
-e IPFS_PROFILE=server \
-v `pwd`/export:/export \
-v `pwd`/data/ipfs:/data/ipfs \
-p 4001:4001 \
-p 4001:4001/udp \
-p 127.0.0.1:8080:8080 \
-p 127.0.0.1:5001:5001 \
ipfs/kubo:latest
せっかくなので初期化してみる
docker stop ipfs_host
docker rm ipfs_host
rm -rf data
mkdir -p data/ipfs
source start-ipfs-node.sh
IPFS Kubo Tutorial
docker exec ipfs_host \
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-notes
Quick Start も見てみる
docker exec ipfs_host \
ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/quick-start
# 0.1 - Quick Start
This is a set of short examples with minimal explanation. It is meant as
a "quick start".
Add a file to ipfs:
echo "hello world" >hello
ipfs add hello
View it:
ipfs cat <the-hash-you-got-here>
Try a directory:
mkdir foo
mkdir foo/bar
echo "baz" > foo/baz
echo "baz" > foo/bar/baz
ipfs add -r foo
View things:
ipfs ls <the-hash-here>
ipfs ls <the-hash-here>/bar
ipfs cat <the-hash-here>/baz
ipfs cat <the-hash-here>/bar/baz
ipfs cat <the-hash-here>/bar
ipfs ls <the-hash-here>/baz
References:
ipfs refs <the-hash-here>
ipfs refs -r <the-hash-here>
ipfs refs --help
Get:
ipfs get <the-hash-here> -o foo2
diff foo foo2
Objects:
ipfs object get <the-hash-here>
ipfs object get <the-hash-here>/foo2
ipfs object --help
Pin + GC:
ipfs pin add <the-hash-here>
ipfs repo gc
ipfs ls <the-hash-here>
ipfs pin rm <the-hash-here>
ipfs repo gc
Daemon:
ipfs daemon (in another terminal)
ipfs id
Network:
(must be online)
ipfs swarm peers
ipfs id
ipfs cat <hash-of-remote-object>
Mount:
(warning: fuse is finicky!)
ipfs mount
cd /ipfs/<the-hash-here>
ls
Tool:
ipfs version
ipfs update
ipfs commands
ipfs config --help
open http://localhost:5001/webui
Browse:
WebUI:
http://localhost:5001/webui
video:
http://localhost:8080/ipfs/QmVc6zuAneKJzicnJpfrqCH9gSy6bz54JhcypfJYhGUFQu/play#/ipfs/QmTKZgRNwDNZwHtJSjCp6r5FYefzpULfy37JvMt9DwvXse
images:
http://localhost:8080/ipfs/QmZpc3HvfjEXvLWGQPWbHk3AjD5j8NEN4gmFN8Jmrd5g83/cs
markdown renderer app:
http://localhost:8080/ipfs/QmX7M9CiYXjVeFnkfVGf3y5ixTZ2ACeSGyL1vBJY1HvQPp/mdown
Web UI にアクセスしてみる
やはり UI はありがたい
IPFS のピアについて
<transport address>/p2p/<hash-of-public-key>
/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
IP + TCP ポートと公開鍵のハッシュの組み合わせのようだ
後から知ったが Multiaddr というフォーマットみたい
オブジェクトの取得
docker exec ipfs_host \
ipfs cat /ipfs/QmSgvgwxZGaBLqkGyWemEDqikCqU52XxsYLKtdy3vGZ8uq > export/spaceship-launch.jpg
リダイレクトは docker
プロセスに対して行われるので /export
ではなくて export
を指定する
ファイルが見つからない場合
ハングアップしているような状態になる
docker exec ipfs_host \
ipfs cat /ipfs/QmQPk9Vi9iSm4aAPEd73txGjqwbHhLYWfoUEpG5eYmy2PW
ファイルの追加
Hello IPFS!
docker exec ipfs_host ipfs add -q /export/message.txt
docker exec ipfs_host \
ipfs cat /ipfs/QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk
Hello IPFS!
curl https://ipfs.io/ipfs/QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk
Hello IPFS!
タイミングが悪いと 429 Too Many Requests が発生する
<html>
<head><title>429 Too Many Requests</title></head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<hr><center>openresty</center>
</body>
</html>
MFS へのコピー
IPFS では MFS (Mutable FileSystem) というものがあり、MFS を使うと普通の名前付きファイルシステムのようにデータを管理できる
IPFS に追加したファイルを MFS へコピーするには下記のコマンドを実行する
docker exec ipfs_host \
ipfs files cp /ipfs/QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk /dest
MFS にコピーされたファイルは Web UI の Files ページに表示される
IPFS Companion
Chrome 拡張などをインストールすることでアドレスバーに ipfs:
のURLを入力してアクセスできる
ディレクトリの追加を試してみる
mkdir export/foo
mkdir export/foo/bar
echo "baz" > export/foo/baz
echo "baz" > export/foo/bar/baz
docker exec ipfs_host ipfs add -r /export/foo
4 B / 8 B 50.00%added QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR foo/bar/baz
8 B / 8 B 100.00%added QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR foo/baz
added QmeBpzHngbHes9hoPjfDCmpNHGztkmZFRX4Yp9ftKcXZDN foo/bar
8 B / 8 B 100.00%added QmdcYvbv8FSBfbq1VVSfbjLokVaBYRLKHShpnXu3crd3Gm foo
ディレクトリに ls や cat を試してみる
docker exec ipfs_host ipfs ls QmdcYvbv8FSBfbq1VVSfbjLokVaBYRLKHShpnXu3crd3Gm
QmeBpzHngbHes9hoPjfDCmpNHGztkmZFRX4Yp9ftKcXZDN - bar/
QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR 4 baz
そういえば CID の前に /ipfs/
はいらないのだろうか
docker exec ipfs_host ipfs cat QmdcYvbv8FSBfbq1VVSfbjLokVaBYRLKHShpnXu3crd3Gm
Error: this dag node is a directory
ディレクトリを cat しようとするとエラーになる
$ docker exec ipfs_host ipfs ls QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR
$
ファイルを ls しても何も表示されない
Refs とは何か?
$ docker exec ipfs_host ipfs refs -h
USAGE
ipfs refs <ipfs-path>... - List links (references) from an object.
ipfs refs [--format=<format>] [--edges | -e] [--unique | -u]
[--recursive | -r] [--max-depth=<max-depth>] [--] <ipfs-path>...
Lists the hashes of all the links an IPFS or IPNS object(s) contains,
with the following format:
<link base58 hash>
List all references recursively by using the flag '-r'.
NOTE: Like most other commands, Kubo will try to fetch the blocks of the passed path if they can't be found in the local store if it is running in online mode.
SUBCOMMANDS
ipfs refs local - List all local references.
For more information about each command, use:
'ipfs refs <subcmd> --help'
ディレクトリに含まれるファイルの CID を一覧表示することらしい
$ docker exec ipfs_host ipfs refs QmdcYvbv8FSBfbq1VVSfbjLokVaBYRLKHShpnXu3crd3Gm
QmeBpzHngbHes9hoPjfDCmpNHGztkmZFRX4Yp9ftKcXZDN
QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR
オブジェクトのダウンロード
オブジェクトを一気にダウンロードしたいときは ipfs get
が便利そう
$ docker exec ipfs_host ipfs get -h
USAGE
ipfs get <ipfs-path> - Download IPFS objects.
ipfs get [--output=<output> | -o] [--archive | -a] [--compress | -C]
[--compression-level=<compression-level> | -l] [--progress=false]
[--] <ipfs-path>
Stores to disk the data contained an IPFS or IPNS object(s) at the given path.
By default, the output will be stored at './<ipfs-path>', but an alternate
path can be specified with '--output=<path>' or '-o=<path>'.
To output a TAR archive instead of unpacked files, use '--archive' or '-a'.
To compress the output with GZIP compression, use '--compress' or '-C'. You
may also specify the level of compression by specifying '-l=<1-9>'.
For more information about each command, use:
'ipfs get <subcmd> --help'
試してみる
$ docker exec ipfs_host \
ipfs get QmdcYvbv8FSBfbq1VVSfbjLokVaBYRLKHShpnXu3crd3Gm \
-o /export/foo2
Saving file(s) to /export/foo2
167 B / 167 B 100.00% 0s
ipfs object は deprecated
$ docker exec ipfs_host ipfs object -h
WARNING: DEPRECATED, command will be removed in the future
USAGE
ipfs object - Deprecated commands to interact with dag-pb objects. Use 'dag'
or 'files' instead.
ipfs object
'ipfs object' is a legacy plumbing command used to manipulate dag-pb objects
directly. Deprecated, use more modern 'ipfs dag' and 'ipfs files' instead.
For more information about each command, use:
'ipfs object <subcmd> --help'
DEPRECATED SUBCOMMANDS
ipfs object data <key> - Deprecated way to read the raw bytes of a
dag-pb object: use 'dag get' instead.
ipfs object diff <obj_a> <obj_b> - Display the diff between two IPFS objects.
ipfs object get <key> - Deprecated way to get and serialize the
dag-pb node. Use 'dag get' instead
ipfs object links <key> - Deprecated way to output links in the
specified dag-pb object: use 'dag get'
instead.
ipfs object new [<template>] - Deprecated way to create a new dag-pb
object from a template.
ipfs object patch - Deprecated way to create a new merkledag
object based on an existing one. Use MFS
with 'files cp|rm' instead.
ipfs object put <data> - Deprecated way to store input as a DAG
object. Use 'dag put' instead.
ipfs object stat <key> - Deprecated way to read stats for the
dag-pb node. Use 'files stat' instead.
今日はこの辺りにしておこう
ピン
$ docker exec ipfs_host ipfs pin -h
USAGE
ipfs pin - Pin (and unpin) objects to local storage.
ipfs pin
SUBCOMMANDS
ipfs pin add <ipfs-path>... - Pin objects to local storage.
ipfs pin ls [<ipfs-path>]... - List objects pinned to local storage.
ipfs pin remote - Pin (and unpin) objects to remote
pinning service.
ipfs pin rm <ipfs-path>... - Remove object from pin-list.
ipfs pin update <from-path> <to-path> - Update a recursive pin.
ipfs pin verify - Verify that recursive pins are
complete.
For more information about each command, use:
'ipfs pin <subcmd> --help'
$ docker exec ipfs_host ipfs pin ls
QmQGiYLVAdSHJQKYFRTJZMG4BXBHqKperaZtyKGmCRLmsF indirect
QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc recursive
QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR indirect
QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y indirect
QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk recursive
QmdcYvbv8FSBfbq1VVSfbjLokVaBYRLKHShpnXu3crd3Gm recursive
QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB indirect
QmQy6xmJhrcC5QLboAcGFcAE1tC8CrwDVkrHdEYJkLscrQ indirect
QmU5k7ter3RdjZXu3sHghsga1UQtrztnQxmTL22nPnsu3g indirect
QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn recursive
QmeBpzHngbHes9hoPjfDCmpNHGztkmZFRX4Yp9ftKcXZDN indirect
QmejvEPop4D7YUadeGqYWmZxHhLc4JBUCzJJHWMzdcMe2y indirect
QmQ5vhrL7uv6tuoN9KeVBwd4PwfQkXdVVmDLUZuTNxqgvm indirect
まだ何もピンしていないのにピンされているオブジェクトがある
ipfs cat
や ipfs ls
で中身を見たところ、これまでに cat
したりして見たファイルやディレクトリのようだ
$ docker exec ipfs_host ipfs pin add -h
USAGE
ipfs pin add <ipfs-path>... - Pin objects to local storage.
ipfs pin add [--recursive=false] [--progress] [--] <ipfs-path>...
Stores an IPFS object(s) from a given path locally to disk.
For more information about each command, use:
'ipfs pin add <subcmd> --help'
BAYC のトークン番号 0 の画像データをピンしてみる
$ docker exec ipfs_host ipfs pin add QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ
pinned QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ recursively
$ docker exec ipfs_host ipfs pin ls QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ
recursively
とあるがファイルなのに関係あるのだろうか
ガベージコレクション
$ docker exec ipfs_host ipfs repo -h
USAGE
ipfs repo - Manipulate the IPFS repo.
ipfs repo
'ipfs repo' is a plumbing command used to manipulate the repo.
SUBCOMMANDS
ipfs repo gc - Perform a garbage collection sweep on the repo.
ipfs repo ls - List all local references.
ipfs repo migrate - Apply any outstanding migrations to the repo.
ipfs repo stat - Get stats for the currently used repo.
ipfs repo verify - Verify all blocks in repo are not corrupted.
ipfs repo version - Show the repo version.
For more information about each command, use:
'ipfs repo <subcmd> --help'
DEPRECATED SUBCOMMANDS
ipfs repo fsck - Remove repo lockfiles.
$ docker exec ipfs_host ipfs repo stat
NumObjects: 5973
RepoSize: 41839023
StorageMax: 10000000000
RepoPath: /data/ipfs
Version: fs-repo@13
$ docker exec ipfs_host ipfs repo gc
removed bafkreias34q5t2mvly2f4v5xwn5pvprt5wvezxox36plzgu3umyelwg5na
removed bafkreicjwu5ym6256guny7jlxmgilxdiwkdnbuqme5jqyczxcxvdnmq5na
removed bafkreibn3wvv7pni64ukvm4w4jm2hlzylw4zvvrl4qiuh3vtpvzn4xv5n4
... (全部で6366件が削除された様子)
$ docker exec ipfs_host ipfs repo stat
NumObjects: 931
RepoSize: 789814
StorageMax: 10000000000
RepoPath: /data/ipfs
Version: fs-repo@13
Web UI からも減っている様子がわかる
ブロックについて
ファイルが 256 KiB 以上だとブロックに分割される
$ docker exec ipfs_host \
ipfs ls QmSgvgwxZGaBLqkGyWemEDqikCqU52XxsYLKtdy3vGZ8uq
QmdXmL2dyFU5ZT51G7bXzc3D1sPaBLEJiQtDRgzDhEAwx1 262144
QmUfYrWyvRbdJVpUfp3A7oCKBf13uLouaJ3VBMZtkBnb5b 14238
1つ目の方にアクセスすると同じような画像が表示される
2つ目の方にアクセスするとバイナリデータがダウンロードされる
調べてみると1つ目の方のサイズは 262,144 Byte = 256 KiB だった
Block 操作
ipfs block get
コマンドを実行するとブロック生データをバイナリで取得できる
$ docker exec ipfs_host \
ipfs block get QmSgvgwxZGaBLqkGyWemEDqikCqU52XxsYLKtdy3vGZ8uq
*
" ?-d????-~F?X)??m???_?X_?????)
" ]??d!5 Npѐ ?O(z<?V#?:@`ʹ?o
?? ?? ?o
ipfs object links
は ipfs ls
と同等
$ docker exec ipfs_host \
ipfs object links QmSgvgwxZGaBLqkGyWemEDqikCqU52XxsYLKtdy3vGZ8uq
QmdXmL2dyFU5ZT51G7bXzc3D1sPaBLEJiQtDRgzDhEAwx1 262158
QmUfYrWyvRbdJVpUfp3A7oCKBf13uLouaJ3VBMZtkBnb5b 14249
$ docker exec ipfs_host \
ipfs ls QmSgvgwxZGaBLqkGyWemEDqikCqU52XxsYLKtdy3vGZ8uq
QmdXmL2dyFU5ZT51G7bXzc3D1sPaBLEJiQtDRgzDhEAwx1 262144
QmUfYrWyvRbdJVpUfp3A7oCKBf13uLouaJ3VBMZtkBnb5b 14238
ハッシュだけが必要な場合は ipfs refs
の方が良い
$ docker exec ipfs_host ipfs refs QmSgvgwxZGaBLqkGyWemEDqikCqU52XxsYLKtdy3vGZ8uq
QmdXmL2dyFU5ZT51G7bXzc3D1sPaBLEJiQtDRgzDhEAwx1
QmUfYrWyvRbdJVpUfp3A7oCKBf13uLouaJ3VBMZtkBnb5b
ブロックとオブジェクトは違うのかな?
$ echo "This is some data" | docker exec -i ipfs_host ipfs block put
bafkreih5o5lixipg5nmhrerhlgphbgschpdw5ithq35vbkjjckxleyb7ga
$ docker exec ipfs_host \
ipfs block get bafkreih5o5lixipg5nmhrerhlgphbgschpdw5ithq35vbkjjckxleyb7ga
This is some data
$ docker exec ipfs_host \
ipfs cat bafkreih5o5lixipg5nmhrerhlgphbgschpdw5ithq35vbkjjckxleyb7ga
This is some data
一方 ipfs add
を使う場合
$ echo "This is some data" | docker exec -i ipfs_host ipfs add
18 B / ? added Qmdi3Q6EZXusjMSRovDdVfnkroJnnwaburvb6deDbECDH4 Qmdi3Q6EZXusjMSRovDdVfnkroJnnwaburvb6deDbECDH4
18 B / 18 B 100.00%
$ docker exec -i ipfs_host \
ipfs cat Qmdi3Q6EZXusjMSRovDdVfnkroJnnwaburvb6deDbECDH4
This is some data
$ docker exec -i ipfs_host \
ipfs block get Qmdi3Q6EZXusjMSRovDdVfnkroJnnwaburvb6deDbECDH4
This is some data
今のところアドレスがちょっと違うくらいで違いがわからない
CID のバージョンが異なるので同じ内容なのかどうかはわからない
下記のコマンドを実行して変換できる
$ docker exec -i ipfs_host \
ipfs cid format -v 1 -b base32 Qmdi3Q6EZXusjMSRovDdVfnkroJnnwaburvb6deDbECDH4
bafybeihelit6mpirtze5dmm45efbuizcwvj7aok63zr3d3fs5ocddl27tm
ga
で終わるものとは違うブロックが出てきた
まずは tm
で終わる方(ipfs add
した方)を色々と探ってみる
$ docker exec -i ipfs_host \
ipfs refs bafybeihelit6mpirtze5dmm45efbuizcwvj7aok63zr3d3fs5ocddl27tm
$ docker exec -i ipfs_host \
ipfs cat bafybeihelit6mpirtze5dmm45efbuizcwvj7aok63zr3d3fs5ocddl27tm
This is some data
$ docker exec -i ipfs_host \
ipfs block get bafybeihelit6mpirtze5dmm45efbuizcwvj7aok63zr3d3fs5ocddl27tm
This is some data
$ docker exec -i ipfs_host \
ipfs object stat bafybeihelit6mpirtze5dmm45efbuizcwvj7aok63zr3d3fs5ocddl27tm
NumLinks: 0
BlockSize: 26
LinksSize: 2
DataSize: 24
CumulativeSize: 26
$ docker exec -i ipfs_host \
ipfs dag get bafybeihelit6mpirtze5dmm45efbuizcwvj7aok63zr3d3fs5ocddl27tm
{"Data":{"/":{"bytes":"CAISElRoaXMgaXMgc29tZSBkYXRhChgS"}},"Links":[]}
続いて ga
で終わる方(ipfs block put
した方)
$ docker exec -i ipfs_host \
ipfs refs bafkreih5o5lixipg5nmhrerhlgphbgschpdw5ithq35vbkjjckxleyb7ga
$ docker exec -i ipfs_host \
ipfs cat bafkreih5o5lixipg5nmhrerhlgphbgschpdw5ithq35vbkjjckxleyb7ga
This is some data
$ docker exec -i ipfs_host \
ipfs block get bafkreih5o5lixipg5nmhrerhlgphbgschpdw5ithq35vbkjjckxleyb7ga
This is some data
$ docker exec -i ipfs_host \
ipfs object stat bafkreih5o5lixipg5nmhrerhlgphbgschpdw5ithq35vbkjjckxleyb7ga
NumLinks: 0
BlockSize: 18
LinksSize: 0
DataSize: 18
CumulativeSize: 18
$ docker exec -i ipfs_host \
ipfs dag get bafkreih5o5lixipg5nmhrerhlgphbgschpdw5ithq35vbkjjckxleyb7ga
{"/":{"bytes":"VGhpcyBpcyBzb21lIGRhdGEK"}}
同じ内容なのに別のブロックとして表現されるのが興味深い
CID のバージョン
- なんで CID が小文字だけだったり大文字が含まれていたりするのか気になった
- 調べたところ CID のバージョンの違いのようだ
- しかも小文字だけの方がバージョンが上らしい
Remove pinning services
Pinata のようなサービスは remote pinning service と言われるようだ
ipfs コマンドで Pinata を操作できる
なんと ipfs
コマンドで Pinata のような remote pinning service を操作できる
せっかく頑張って Pinata SDK の使い方を覚えたのに、時間返して笑
ipfs コマンドを使って Pinata にピンしてみる
$ docker exec -i ipfs_host \
ipfs pin remote service add pinata https://api.pinata.cloud/psa <JWT>
$ docker exec -i ipfs_host \
ipfs pin remote add --service pinata --name fromIpfsCommand Qmdi3Q6EZXusjMSRovDdVfnkroJnnwaburvb6deDbECDH4
Error: reason: "INVALID_ORIGINS", details: "provider array entry: /ip4/127.0.0.1/udp/4001/quic-v1/webtransport/certhash/uEiCB9bFQtPDdYcx3vN3qNNO_mSM3d9F-XFM_loTMTN2hwQ/certhash/uEiDAbWd55WlzsuYo968ZStHkfVCiokjzQjGEn6r1VfPQRw/p2p/12D3KooWPqZVUQP4fokXZ8za28nYxqZaMj1PHDCk1rKe97DeezgK is not a valid peer multiaddr": 400 Bad Request
エラーが表示されてピンできない、グローバル IP アドレスじゃないとダメなのかな?
そんなはずはないと思って色々やっていたらできた
- Web UI のナビゲーションから SETTINGS を選んでクリック
- IPFS Config の
Addresses.Swarms
からAddresses.NoAnnounce
へ下記3点を移動- "/ip4/0.0.0.0/udp/4001/quic",
- "/ip4/0.0.0.0/udp/4001/quic-v1",
- "/ip4/0.0.0.0/udp/4001/quic-v1/webtransport"
-
docker stop ipfs_host && docker start ipfs_host
で設定を反映
$ docker exec -i ipfs_host \
ipfs pin remote add --service=pinata --name=byIpfsCommand bafybeihelit6mpirtze5dmm45efbuizcwvj7aok63zr3d3fs5ocddl27tm
CID: bafybeihelit6mpirtze5dmm45efbuizcwvj7aok63zr3d3fs5ocddl27tm
Name: byIpfsCommand
Status: pinned
Pinata の My Files に表示された
変更した設定は一応元に戻しておこう
Pinning Service API のコードは自動生成できる
OpenAPI すごいですね
ipfs mount できない
$ docker exec ipfs_host ipfs mount
Error: fuse failed to access mountpoint /ipfs
そろそろ Mac に IPFS をインストールする時だろうか
IPFS に Git レポジトリを保存する
mkdir export/myrepo
cd export/myrepo
touch main.js
console.log("Hello, world!");
git init
git add .
git commit -m "Initial commit"
cd ..
git clone --mirror myrepo myrepo2
cd myrepo2
git update-server-info
mv objects/pack/*.pack .
git unpack-objects < *.pack
rm -f *.pack objects/pack/*
docker exec ipfs_host ipfs add -r /export/data
21 B / ? added QmbRUdVtdtxcpdqyJE3iZwTJq7FPcXR1ErQRFB76sQCg9H myrepo2/HEAD
252 B / ? added QmQGeJdtRfMAPiUGZyUwpofsMW73RyDm8VZJ5KGqYYkPuw myrepo2/config
325 B / ? added Qmdy135ZFG4kUALkaMhr6Cy3VhhkxyAh264kyg3725x8be myrepo2/description
803 B / ? added QmY2duvZ5Resxt8astYUgQ8RXQz1N9axe77gCb5j6M95Gf myrepo2/hooks/applypatch-msg.sample
1.66 KiB / 23.91 KiB 6.94%added QmQbraCfKaCTZkqtdXCJPc11CWEiZGw1yYGwtbA6nbXWeh myrepo2/hooks/commit-msg.sample
6.27 KiB / 23.91 KiB 26.24%added QmfUn9iq4rWKhKyzcdN9EG4HPDqnrgiWy1gZb7zuo33Bjo myrepo2/hooks/fsmonitor-watchman.sample
6.46 KiB / 23.91 KiB 27.02%added QmQjYxVj9iwitDGkmR48Cemr1JTgc6pvwo5cFkumNWqnjm myrepo2/hooks/post-update.sample
6.87 KiB / 23.91 KiB 28.75%added QmdzjzkpM31jTKd5YBJkWsbDXJeeW1Uy1UxVPwfKFxwy89 myrepo2/hooks/pre-applypatch.sample
8.88 KiB / 23.91 KiB 37.16%added QmY33NoK9jzqitkPK1QdWTnNQt7m6DsE4fYvyohjdbyfju myrepo2/hooks/pre-commit.sample
10.23 KiB / 23.91 KiB 42.77%added QmPte81MJoXgCngK75SVZTn2DAXskuo9gdVr2uR5PfVVQE myrepo2/hooks/pre-merge-commit.sample
added QmQVg6D9VT3Ro9JWnUYECobpTvVVh4hgz9jNEmXKEok1S9 myrepo2/hooks/pre-push.sample
15.54 KiB / 23.91 KiB 65.00%added QmSQrei5kUrb4RaEp4c7oobLEHURhPJ8AFZS1uiRg4JfLv myrepo2/hooks/pre-rebase.sample
added QmRKbU9DFRNWjR1UwV4nC6MXPnrNanfsBM5579t4HLUuig myrepo2/hooks/pre-receive.sample
17.00 KiB / 23.91 KiB 71.10%added QmPku8ai5p4sSCDHe19n9Ekfo21xM5urFdkq9Rg1wBHjcV myrepo2/hooks/prepare-commit-msg.sample
23.28 KiB / 23.91 KiB 97.37%added Qma763g2HDRav2QxLaAEWKiyE42Z3e2vcojWThMzYNHyRq myrepo2/hooks/push-to-checkout.sample
added QmcV7YCAafpfa79M4Ys1Ffq4gbJEc8NukKxu4izEedgAno myrepo2/hooks/update.sample
23.51 KiB / 23.91 KiB 98.35%added QmcfzxUpw36y8fu2GR3s7Vgq7RBgooKtc6BgsqFnadsDLc myrepo2/info/exclude
23.70 KiB / 23.91 KiB 99.11%added QmVeWm24Pd8x3fCaWHCTFbyAtgTbuYmk8iDTn7mwHcNJcM myrepo2/info/refs
23.71 KiB / 23.91 KiB 99.17%added QmYP9FYQhX7KqVSAUGdBW15V6fhZErnGPdrFjby3pHB4sv myrepo2/objects/02/700be738d125f3bbfb53fd3166ecff734b091b
23.75 KiB / 23.91 KiB 99.36%added QmW6g1zwNU91L9rm8q3d6JUg43oRM5Y2QDy97kxLrQvPqK myrepo2/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
23.81 KiB / 23.91 KiB 99.58%added QmZVqS7wcpJZgjSxWFVDM6toXZgRwAocGTydnuX53HuQBz myrepo2/objects/a8/141d3b18d3421ad3fd4ba372edf6e319252622
23.81 KiB / 23.91 KiB 99.58%added QmbJJkyMpnaZy2hPbYhH9Q6LW2pA37oMYp9gsrMPEpV1EM myrepo2/objects/a9/ba3a185500c5abeca9db8dc0cb22fa314be10d
added Qmc5m94Gu7z62RC8waSKkZUrCCBJPyHbkpmGzEePxy2oXJ myrepo2/objects/info/packs
23.91 KiB / 23.91 KiB 100.00%added QmVocythgPAprAkH3m3ZMnY8HvzdqKTjWppSRj57kENWka myrepo2/packed-refs
23.91 KiB / 23.91 KiB 100.00%added QmbjKH6bppx7ce55qFt1AwSEpTmVJKYYPhbgAbsNNDh8LN myrepo2/hooks
added QmV1R83Y5HFi4RGRFdCY2oyESZbaunFXFAfyQ6mvrKxTFH myrepo2/info
added QmQTLLCURiMWeU1m7gBTzJmhbgYcHY4ZzbB8utYAj8jjjf myrepo2/objects/02
23.91 KiB / 23.91 KiB 100.00%added QmTvqgarvbWaGa41HewF3GAexbHYsJ8Za3FH1JyAyaCiUZ myrepo2/objects/4b
23.91 KiB / 23.91 KiB 100.00%added Qmei6r4htgvN2cf28MeF8dcFyGErqcDcaLzs3h1QV6B8bG myrepo2/objects/a8
23.91 KiB / 23.91 KiB 100.00%added QmW1en8k7uDrWVoGoX2hvhyTqUVHaGucEarmWQBFzpnYLn myrepo2/objects/a9
added QmXaZFVFt87ZdXpuLbt1SLspjCFt89AN3Ec48cC7zZtnqt myrepo2/objects/info
added QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn myrepo2/objects/pack
added QmehSUbe6Hrx1xHKE8o3xPzsugqq48Kg1pktMyzRU3oNRD myrepo2/objects
23.91 KiB / 23.91 KiB 100.00%added QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn myrepo2/refs/heads
23.91 KiB / 23.91 KiB 100.00%added QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn myrepo2/refs/tags
added QmWYtSEta2Fzgy4u4ttdwwiKMUikwZrFHxa5quWXMVyBhy myrepo2/refs
added QmPs2Fd7Pe6TB1xSykbXkzzrMVan6ssD65MEefzDMJjwfh myrepo2
git clone http://localhost:8080/ipfs/QmPs2Fd7Pe6TB1xSykbXkzzrMVan6ssD65MEefzDMJjwfh myrepo3
cat myrepo3/main.js
console.log("Hello, world!");
どういう場面で使えば良いだろう
IPNS を使ってみる
$ docker exec ipfs_host ipfs add /export/message.txt
added QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk message.txt
11 B / 11 B [=========================================================] 100.00%
$ docker exec ipfs_host ipfs name publish QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk
Published to k51qzi5uqu5dldi96bmpio1vdb0rabo26tgwinhced3es3gkni0p71fv0pr1tw: /ipfs/QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk
-
ipfs name publish
の実行には結構時間がかかる、体感で 1 分弱くらい - http://localhost:8080/ipns/k51qzi5uqu5dldi96bmpio1vdb0rabo26tgwinhced3es3gkni0p71fv0pr1tw にアクセスすると http://k51qzi5uqu5dldi96bmpio1vdb0rabo26tgwinhced3es3gkni0p71fv0pr1tw.ipns.localhost:8080/ にリダイレクトされてファイルの内容が表示される
- https://gateway.ipfs.io/ipns/k51qzi5uqu5dldi96bmpio1vdb0rabo26tgwinhced3es3gkni0p71fv0pr1tw では 504 Gateway Time-out になる
touch export/new-message.txt
Hello IPFS! by tatsuyasusukida
$ docker exec ipfs_host ipfs add /export/new-message.txt
30 B / ? added QmSRwmAKDKBr7Ba3vfpbncnrngYBM9s2ZGnqRcnc9FLbg4 new-message.txt
30 B / 30 B 100.00%
$ docker exec ipfs_host ipfs name publish QmSRwmAKDKBr7Ba3vfpbncnrngYBM9s2ZGnqRcnc9FLbg4
Published to k51qzi5uqu5dldi96bmpio1vdb0rabo26tgwinhced3es3gkni0p71fv0pr1tw: /ipfs/QmSRwmAKDKBr7Ba3vfpbncnrngYBM9s2ZGnqRcnc9FLbg4
- http://localhost:8080/ipns/k51qzi5uqu5dldi96bmpio1vdb0rabo26tgwinhced3es3gkni0p71fv0pr1tw にアクセスすると更新を確認できる
- 1 ノードあたり 1 つの IPNS しか貰えないのかな?
- いまだに gateway.ipfs.io の方では 504 Gateway Time-out になる
Fleek を試してみる
IPFS で Web サイトを運用するのに便利な Fleek を試してみる
mkdir my-first-fleek-website
cd my-first-fleek-website
touch index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello Fleek!</title>
</head>
<body>
<h1>Hello Fleek!</h1>
</body>
</html>
git init
git add .
git commit -m "Initial commit"
gh repo --public create my-first-fleed-website
git remote add origin git@github.com:tatsuyasusukida/my-first-fleed-website
git push origin main
あとは Fleek の Web UI を操作する
Deploy started at 3:06:31 PM 01/26/2023
3:06:31 PM 01/26/2023: Deploy started
3:06:33 PM 01/26/2023: Docker image: 'node:slim'
3:06:33 PM 01/26/2023: Build command: ''
3:06:33 PM 01/26/2023: Triggering build execution...
3:07:04 PM 01/26/2023: Deployed to IPFS and got the hash:
3:07:04 PM 01/26/2023: QmVM3ovAMkFrG5w1xGVAo8wHRv6zBMfth811xUm5Mysgjg
3:07:04 PM 01/26/2023: Checking content availability on IPFS...
3:07:05 PM 01/26/2023: Updating DNS records...
3:07:06 PM 01/26/2023: DNS was updated. You can visit the new site at:
3:07:06 PM 01/26/2023: https://bold-night-2699.on.fleek.co
デプロイしたサイトには下記のいずれかでアクセスできる
- https://ipfs.fleek.co へのアクセスが https://fleek.ipfs.io/ へ転送される
- ipfs.io って IPFS 公式が所有しているドメインだと思っていたが fleek 専用のサブドメインがあるのは何故だろう
Pinata のゲートウェイでも確認できる
さすが Fleek、個人ノードとは違う
DNSLink という便利なものを知った
- _dnslink.www.loremipsum.co.jp という名前で TXT レコードを作る
- レコード内容は "dnslink=/ipns/k51qzi5uqu5di9kl58x19u26pvm1gbhou4a7fhn8d4gr827rqx6221dq5ntcfv" のようにする
- /ipns/www.loremipsum.co.jp/ でアクセスできるようになる
森 亮介さんの DevelopersIO の記事が豊富で素晴らしい
IPNS は複数所有できる
今日はここまで