Ubuntu上IPFS私有鏈搭建與Java-sdk調用

文章參考了幾位大神的博客,但自己在實踐時遇到了一些問題,因此在原文基礎上做了修改,原文鏈接在文章末尾。

一、拉取相關docker鏡像

docker pull ipfs/go-ipfs

二、私有鏈密鑰生成工具生成密鑰文件

go get github.com/Kubuxu/go-ipfs-swarm-key-gen
cd $GOPATH/src/github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen
go build
$GOPATH/src/github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen > ~/swarm.key

三、在當前宿主機創建ipfs 的data、export目錄

mkdir -p ~/ipfs/ipfs1/data ~/ipfs/ipfs1/export ~/ipfs/ipfs2/data ~/ipfs/ipfs2/export

四、將生成的密鑰文件分別拷貝至 ipfs 對應的 data 文件夾下

cp ~/swarm.key ~/ipfs/ipfs1/data 
cp ~/swarm.key ~/ipfs/ipfs2/data 

五、分別啓動 ipfs 兩個容器

docker run -d --name ipfs_host1 --privileged=true --entrypoint="sh" -v ~/ipfs/ipfs1/export:/export -v ~/ipfs/ipfs1/data:/data/ipfs -p 4001:4001 -p 127.0.0.1:8085:8080 -p 5001:5001 ipfs/go-ipfs:latest -c "while true; do sleep 1;done"
docker run -d --name ipfs_host2 --privileged=true --entrypoint="sh" -v ~/ipfs/ipfs2/export:/export -v ~/ipfs/ipfs2/data:/data/ipfs -p 4011:5001 -p 127.0.0.1:9085:8080 -p 5011:5001 ipfs/go-ipfs:latest -c "while true; do sleep 1;done"

       注意:啓動命令中的參數說明。--entrypoint="sh" 由於 ipfs 容器的 dockerfile 中註明了 entrypoint 執行的命令,當直接運行容器後,容器會根據默認配置文件啓動 ipfs 服務,並連接 ipfs 公網環境。由於我們需要搭建自己的私有鏈環境所以需要改寫entrypoint執行我們制定的命令,並在容器中修改相應的配置文件,運行私有鏈環境。這裏我們設置 entrypoint 運行 sh命令,並執行上訴命令最後部分的參數 -c "while true; do sleep 1;done",啓動一個主進程來保持 ipfs 容器運行。

六、修改 ipfs 服務默認配置

分別進入ipfs_host1與ipfs_host2容器中執行以下命令:

1、進入 ipfs_host容器

docker exec -it ipfs_host1 sh   

2、初始化節點配置

ipfs init

3、運行初始化命令後,會在/data/ipfs目錄下創建啓動配置信息,並且在屏幕中出現以下初始化信息:

initializing IPFS node at /data/ipfs
generating 2048-bit RSA keypair...done
peer identity: QmQo6nD6ARu8V1bS4KDtpoNbVKQy2aJHkMxAnbQLgojjCp
to get started, enter:

    ipfs cat /ipfs/QmQo6nD6ARu8V1bS4KDtpoNbVKQy2aJHkMxAnbQLgojjCp/readme

記住ipfs_host1中的peer identity: QmQo6nD6ARu8V1bS4KDtpoNbVKQy2aJHkMxAnbQLgojjCp信息,在後面啓動 ipfs_host2服務的時候需要用到,若是忘記了則在容器中執行ipfs id命令,也可以顯示出來。

4、刪除默認配置中的引導節點信息

ipfs bootstrap rm --all

5、修改接口調用地址

打開服務啓動配置文件

cd /data/ipfs
vi config

修改配置文件中 Addresses中的 API值

將"API": "/ip4/127.0.0.1/tcp/5001" 修改爲 "API": "/ip4/0.0.0.0/tcp/5001"

注意,修改後調用 sdk 初始化 IPFS 對象的時候才能遠程訪問 ipfs 服務。如果沒有修改則初始化 IPFS 對象的時候則會出錯。

七、環境啓動

1、進入ipfs_host1

docker exec -it ipfs_host1 sh   
ipfs daemon

  執行完這步驟以後應該是這樣的狀態:

記着千萬不要關閉該窗口,而是重新開啓一個命令窗口去啓動ipfs_host2服務

2、啓動 ipfs_host2服務,注意下面的命令使用到ipfs_host1初始化時生成的peer identity

ipfs bootstrap add /ip4/宿主ip/tcp/4001/ipfs/QmQo6nD6ARu8V1bS4KDtpoNbVKQy2aJHkMxAnbQLgojjCp //第一條命令只需要在
第一次初始化時寫上,以後每次進入ipfs_host2,直接執行ipfs daemon即可

ipfs daemon

執行完以後是如下狀態:

———————————————————————————————————————————————————————

到此環境配置基本結束,但是要注意的是在執行完ipfs_daemon後兩個窗口就會一直顯示這個狀態。若是想要正常使用ipfs,則這兩個窗口不能關閉,需要在xshell中另外開啓命令行窗口執行docker exec -it ipfs_host1 sh 、docker exec -it ipfs_host2 sh 來使用ipfs相關功能,否則私有鏈不能正常交互。這算是一個問題吧,若是哪位朋友有解決辦法,歡迎提出。

虛擬機關機後重新開機,需要先執行docker start ipfs_host1、docker start ipfs_host1啓動兩個容器(提醒自己的話)

八、環境驗證

進入 ipfs_host1容器中執行以下命令:

創建測試文件:

cd ~
echo test > test.txt

上傳文件

ipfs add test.txt

ipfs 上傳文件後會有如下提示信息反饋

added QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH test.txt

其中QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH就是文件test.txt的hash值,ipfs 是根據文件內容進行 hash 只要文件內容不變,只修改文件名是不會影響最終的上鍊文件 hash 值的。

進入 ipfs_host2容器中驗證上傳文件
執行文件查看命令,查看文件內容

ipfs cat QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH

執行命令後,控制檯會返回查詢結果:test

至此,ipfs 私有網絡搭建成功。

有興趣的朋友可以改寫 dockerfile 的內容重寫 entrypoint執行命令的內容,減少修改 ipfs 服務默認配置部分的操作步驟。

九、java-ipfs-http-client的使用

pom.xml中添加依賴,這裏需要根據 github 上的版本修改$LATEST_VERSION的值

  <repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>com.github.ipfs</groupId>
      <artifactId>java-ipfs-http-client</artifactId>
      <version>$LATEST_VERSION</version> 
    </dependency>
  </dependencies>

使用ipfs上傳文件以及下載文件

// 實例化ipfs對象
IPFS ipfs = new IPFS("/ip4/宿主機ip/tcp/5001");

//保存上傳文件
NamedStreamable.FileWrapper savefile = new NamedStreamable.FileWrapper(new File("/Users/song/Documents/book/test1.pdf"));
MerkleNode result = ipfs.add(savefile).get(0);
System.out.println(result.toJSONString());//返回結果裏面獲取保存文件的唯一hash,基於文件內容的 hash


//下載文件
Multihash filePointer = Multihash.fromBase58("Qmc51yHGyaxdRsUwBozP9tQuTRQuXLkZv3sPEcpSgb8BxP");//參數爲文件 hash
byte[] fileContents = ipfs.cat(filePointer);

//保存文件
File downloadfile = new File("/Users/song/Documents/aaa.pdf");

if(!downloadfile.exists()) {
    downloadfile.createNewFile();
}

FileOutputStream fop = new FileOutputStream(downloadfile);
fop.write(fileContents);
fop.flush();
fop.close();

十、參考

1、https://www.jianshu.com/p/dd1335df2470

2、https://www.jianshu.com/p/0e8119b7577c

3、http://cw.hubwiz.com/card/c/ipfs/1/1/1/

4、runoob.com/docker/docker-command-manual.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章