IPFS 筆記和教學 (繁體中文)
Switch branches/tags
Nothing to show
Clone or download
Philippe Z Lin (RD-TW)
Philippe Z Lin (RD-TW) 與 CloudFlare 的整合
Latest commit bfdaa90 Sep 21, 2018

README.md

IPFS 教學和筆記

因為 IPFS 的繁中資料實在太少了,決定邊學習邊筆記。

本篇教學的網址是:

為什麼要使用 IPFS

IPFS (星際檔案系統) 是用來取代已經太過集中化的 HTTP 的一種方案,這裡不做一般性的介紹,因為其它 blog / Wikipedia 上都有寫了。我想使用 IPFS 的理由是:

  1. 網路過度集中化,使用者自願放棄自由,請參考 網際網路已經完蛋了
  2. 依賴單一公司提供的平台所發佈的文章,即使沒有反政府、侵權、政治不正確 blah blah 還是有各種不同的可能被下架,而你已經在 EULA 中同意不去追究了。
  3. Google Blogspot, Tumblr, Facebook Blog 提供的免費、高品質 blog,仍然有上述的疑慮。
  4. 即使是自己架的 Word Press,哪一天被警察用任何理由抄掉了,上面的網頁就沒有了。

去中心化,才能有民主、自由的網路。即使如此,去中心化仍然需要網路中立性的支持,不然你的 ISP 仍然可以獨厚(加速)大公司的網站。

本篇教學 不會 論述以下主題:

  • 免責或匿名性。這是另一個大題目,去中心化不代表你可以匿名。
  • 挖礦、區塊鏈、或任何虛擬貨幣。
  • ICO 特別是 IPFS 最近的 Filecoin ICO 。

完整的介紹性文章,可以參考 InfoQ 的 IPFS:替代HTTP的分布式网络协议

下載、安裝

下載

下載很簡單,請直接到 IPFS 官網 或直接 點這裡下載。我直接下載了 go-ipfs 0.4.10, Mac OS X 請下載 Darwin amd64, Ubuntu 請下載 Linux amd64。

安裝

直接在命令列下打這些指令就好:

$ ipfs init     # 會在 ~/.ipfs 開一個目錄,存放區塊檔,預設是最大 10GB

$ ipfs id       # 列出自己的 ID, 但其實不需要太介意
{
	"ID": "QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR",
	"PublicKey": "...",
	"Addresses": [
		"..."
	],
	"AgentVersion": "go-ipfs/0.4.10/",
	"ProtocolVersion": "ipfs/0.1.0"
}

想修改預設的暫存大小的話,請下這個指令:

export EDITOR=/usr/bin/vim
ipfs config edit

找到 "StorageMax": "10GB", 這行,把 10GB 換成你要的大小即可。

新增檔案

先來隨便新增一個檔案吧。打開記事本,隨便打幾行字 lorem ipsum dolor sit amet 存成 README.md

ipfs add 可以把檔案加進 IPFS 裡,它會傳回一組 HASH, 那個 HASH 就是這個檔案的唯一識別代碼了。

$ ipfs add README.md
added QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd README.md

$ ipfs cat /ipfs/QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd
lorem ipsum dolor sit amet

即使你換到別台機器,一樣可以用 ipfs cat /ipfs/QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd 看到這個檔案的內容。

如果要分享給沒有安裝 IPFS 的朋友(建議順便推坑!) 可以請他使用 IPFS Gateway: https://ipfs.io/ipfs/QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd 把後面的 HASH 換成你剛剛新增的檔案的 HASH,就可以了!

我比較習慣目錄

大家都還是比較習慣目錄結構吧?已經 ipfs add 的檔案,可以被放進目錄裡。

$ ipfs files mkdir /SmartCity   # 開一個目錄
$ ipfs files cp /ipfs/QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd /SmartCity/README.md
$ ipfs files ls /
SmartCity
$ ipfs files ls /SmartCity/
README.md
$ ipfs files read /SmartCity/README.md
lorem ipsum dolor sit amet

我目前還不知道怎麼把目錄 export 出去,讓別人也可用使用同樣的目錄結構。

上傳一整個目錄

使用 ipfs add -r 可以上傳一整個目錄。比方說,這篇教學可以用這種方式上傳 (小心 不要把 .git/ 下面的東西都傳上去了!)

$ ipfs add -r ipfs-tutorial-taiwan-mandarin
added QmdpYD8hejksA5SHNdRfDzE2EYzpSkbazyVAJq5hRwbKtp ipfs-tutorial-taiwan-mandarin/README.md
added QmWe7m2K8DThCUTPuw5KcbYvpAwogScXt8gazfG7QiRpSo ipfs-tutorial-taiwan-mandarin

這樣就可以用下列方式取得 README.md 的內容:

  1. ipfs cat /ipfs/QmdpYD8hejksA5SHNdRfDzE2EYzpSkbazyVAJq5hRwbKtp
  2. ipfs cat /ipfs/QmWe7m2K8DThCUTPuw5KcbYvpAwogScXt8gazfG7QiRpSo/README.md

避免被垃圾回收 (Garbage Collection, GC)

ipfs 會自動做垃圾回收,減少佔用的本機空間。為了避免我們剛發佈的網頁被垃圾回收,可以把整個目錄 pin 起來。

$ ipfs pin add -r /ipfs/QmWe7m2K8DThCUTPuw5KcbYvpAwogScXt8gazfG7QiRpSo

記得要 pin 的是目錄的 hash 不要貼錯了喲!

我在 IPFS 上的第一個網頁

IPFS 的本質是分散式的檔案系統,如果只是要 host 分散式的部落格的話,可以使用 ZeroNet 。晚一點我會再寫一篇 ZeroNet 的介紹。

請注意 如果在 pinpublish 的過程中遇到任何問題,可能是防火牆的關係。跑 ipfs daemon 的時候,它會列出對外連線的 port 請在防火牆打開。

% ipfs daemon
Initializing daemon...
Adjusting current ulimit to 2048...
Successfully raised file descriptor limit to 2048.
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip4/192.168.2.1/tcp/4001
Swarm listening on /ip4/220.xxx.xx.xxx/tcp/4001 ← 這個!!
Swarm listening on /ip6/::1/tcp/4001
API server listening on /ip4/127.0.0.1/tcp/5001
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
Daemon is ready

Debian 系的 Linux 請愛用 sudo ufw allow 4001 即可。

出於莫名的原因,我決定不要使用最常見的 Jekyll 。以下範例是 Hugo 做的 :)

Huge 後面還有使用 ipfs 範例中的 mdown 來 render 的例子。

安裝 Hugo

參考 Hugo官網 的說明,在 Mac 上安裝 Hugo:

$ brew install hugo
Updating Homebrew...
Warning: hugo 0.26 is already installed
$ hugo version
Hugo Static Site Generator v0.26 darwin/amd64 BuildDate: 2017-08-08T14:55:38+08:00
$ hugo new site ipfs-tutorial-zh-TW
Congratulations! Your new Hugo site is created in /Users/miaoski/github/ipfs-tutorial-zh-TW.
$ git init
Initialized empty Git repository in /Users/miaoski/github/ipfs-tutorial-zh-TW/.git/
$ git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke
Cloning into '/Users/miaoski/github/ipfs-tutorial-zh-TW/themes/ananke'...
$ echo 'theme = "ananke"' >> config.toml

修改 config.toml 設定一下 title 和語系什麼的,就可以了。

新增 blog 文章

$ hugo new posts/ipfs-tutorial.md
/Users/miaoski/github/ipfs-tutorial-zh-TW/content/posts/ipfs-tutorial.md created
$ cat ../ipfs-tutorial/README.md >> ./content/posts/ipfs-tutorial.md

修改一下,把 draft: true 改成 draft: false 再執行一次 hugo 就可以 render 出網頁了。

把部落格新增到 IPFS 上

依據 hugo 的建議,先 rm -fr public/ 再重新執行 hugo 比較好...

$ rm -fr ./public/
$ hugo
$ ipfs add -r ./public/
added QmW7dJkAjtLgUtJcgUrTPC2jSLTD8uS4bfzPPXYdsZGhFN public/posts
added QmecA1oy5du9TwNrJrwxjq5emUdG7jbukv8Pzuo2q8CjRc public/tags
added QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf public
$ ipfs pin add -r /ipfs/QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf
pinned QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf recursively

請跳到 IPNS 一節閱讀。

mdown

mdown 是 ipfs 範例中的 markdown-viewer 是以 MIT 版權宣告的。有時候我們只是想分享一份簡單的 markdown,它十分輕量,render 出來的效果也不錯。它的背後是 StrapDownJS。

本文的 Github repo 已經把 mdown 加在裡面了,直接 make 就會看到 ipfs add 上去的 HASH。它也會寫在 published-version 檔案裡。接著我們可以用 IPNS 發佈它。

IPNS

拿到網站的 HASH 後,建議註冊 IPNS ,因為每次更新部落格的內容,上面的 HASH 都會變,我們需要一個固定的 ID 指向最新的 HASH 。以本文為例:

$ ipfs name publish QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf
Published to QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR: /ipfs/QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf 
$ ipfs name resolve QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR
/ipfs/QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf

以後每次更新完網站,都要重新 ipfs add -r ./public/ 一 次,然後再執行 ipfs name publish ... ,這樣/ipns/QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR 才會指向最新的 HASH 哦! (注意是 IPNS 不要搞錯!)

使用 hugo 的同學,順便更新 config.toml:

baseURL = "https://ipfs.io/ipns/QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR/"
languageCode = "zh-tw"
title = "第一次用 IPFS 就上手"
theme = "ananke"

快取 (pin)

把內容快取到本地端,並且提供給其他人。

ipfs pin add QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf

add 本身就是遞歸的,所有的子目錄都會被 pin 住。可以用 ipfs pin ls 看看本地端 pin 了什麼。 這一篇 的指令都可以玩玩看。

TXT

因為一串 HASH 真的很難記,所以可以用修改 DNS 的 TXT 欄的方式,讓使用者可以用 https://ipfs.io/ipns/miaoski.idv.tw/ 這種方式,存取到你的檔案或部落格。要特別注意, TXT 設定完後,如果你用筆電的話,不要太快離線,不然別人可能還來不及 cache 住 TXT 解析的內容。

$ host -t TXT miaoski.idv.tw
miaoski.idv.tw descriptive text "dnslink=/ipns/QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR"

下面的情況都是正常的。但是 ipfs name resolve -r 必須要能正確解析出 /ipfs/ 的位址,別人才看得到你公開的內容。

$ ipfs name resolve miaoski.idv.tw
Error: Could not resolve name (recursion limit exceeded).

$ ipfs dns -r atnnn.com
Error: not a valid domain name

$ ipfs dns atnnn.com
Error: Could not resolve name (recursion limit exceeded).

來試試看我的網頁吧! https://ipfs.io/ipns/miaoski.idv.tw/

推上 CloudFlare

CloudFlare 在 2018.9.17 的時候和 IPFS 合作,提供入口及 SSL 憑證,應該會讓 IPFS 穩定許多。建議要發佈網頁的朋友,可以和 CloudFlare 連在一起。做法如下:

  1. 需要有自己的 domain name
  2. 可以修改 TXT 欄位 (像上面寫的 ipns 那樣)
  3. 把網頁內容丟進一個目錄裡,入口是 index.html
  4. 把網頁的網域名稱 CNAME 到 www.cloudflare-ipfs.com
  5. 加一個 _dnslink.your.website = dnslink=/ipfs/<your_hash_here>
  6. https://www.cloudflare.com/distributed-web-gateway/#connectingyourwebsite 登錄

舉例而言,

  1. 我在 DNS Server 上新增一個 ipfs.miaoski.idv.tw
  2. 把它 CNAME 到 www.cloudflare-ipfs.com
  3. 新增 TXT 欄位 Hostname: _dnslink.ipfs.miaoski.idv.tw / TXT: dnslink=/ipfs/QmR2PvgrHny4ispfEVygvvWkNqwjbU7hareWda41ASF5wC
  4. https://www.cloudflare.com/distributed-web-gateway/#connectingyourwebsite 登錄

這樣以後看 https://ipfs.miaoski.idv.tw/ 就會自動被轉址為 https://cloudflare-ipfs.com/ipfs/QmR2PvgrHny4ispfEVygvvWkNqwjbU7hareWda41ASF5wC 而且會有合法的 SSL 憑證。

nslookup 檢查一下:

$ nslookup
> set type=ANY
> ipfs.miaoski.idv.tw.

ipfs.miaoski.idv.tw	canonical name = www.cloudflare-ipfs.com.

> _dnslink.ipfs.miaoski.idv.tw.

_dnslink.ipfs.miaoski.idv.tw	text = "dnslink=/ipfs/QmR2PvgrHny4ispfEVygvvWkNqwjbU7hareWda41ASF5wC"

我還不懂的部份

  • BitSwap
  • DHT
  • 把 git repo 和 IPFS 整合在一起

參考資料

License 版權聲明

我自己編寫的部份,全部使用 CC BY-SA 4.0 聲明。如果有引用他人的部份,請參考各該文件所屬的版權聲明。