ipfs私有鏈環(huán)境搭建與java-sdk調(diào)用
環(huán)境準(zhǔn)備
ipfs鏡像文件
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
go build
$GOPATH/src/github.com/Kubuxu/go-ipfs-swarm-key-gen > ~/swarm.key
在宿主機創(chuàng)建ipfs 的data鳄梅、export目錄
mkdir -p ~/ipfs/ipfs1/data ~/ipfs/ipfs1/export ~/ipfs/ipfs2/data ~/ipfs/ipfs2/export
把第2步生成的密鑰文件分別拷貝至 ipfs 對應(yīng)的 data 文件夾下
cp ~/swarm.key ~/ipfs/ipfs1/data
cp ~/swarm.key ~/ipfs/ipfs2/data
環(huán)境配置
分別啟動 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"
注意:啟動命令中的參數(shù)說明测摔。--entrypoint="sh" 由于 ipfs 容器的 dockerfile 中注明了 entrypoint 執(zhí)行的命令队伟,當(dāng)直接運行容器后埃跷,容器會根據(jù)默認配置文件啟動 ipfs 服務(wù)五芝,并連接 ipfs 公網(wǎng)環(huán)境谐丢。由于我們需要搭建自己的私有鏈環(huán)境所以需要改寫entrypoint執(zhí)行我們制定的命令揭蜒,并在容器中修改相應(yīng)的配置文件淘衙,運行私有鏈環(huán)境传藏。這里我們設(shè)置 entrypoint 運行 sh命令,并執(zhí)行上訴命令最后部分的參數(shù) -c "while true; do sleep 1;done"彤守,啟動一個主進程來保持 ipfs 容器運行毯侦。
修改 ipfs 服務(wù)默認配置
分別進入ipfs_host1與ipfs_host2容器中執(zhí)行以下命令
進入 ipfs_host容器
docker exec -it ipfs_host1 sh
初始化節(jié)點配置
ipfs init
運行初始化命令后,會在/data/ipfs目錄下創(chuàng)建啟動配置信息具垫,并且在屏幕中出現(xiàn)以下初始化信息
initializing IPFS node at /data/ipfs
generating 2048-bit RSA keypair...done
peer identity: QmcLnHDuhN7bCbdv5FRbYiTNKuqNhs1WSCUezFPt7F4vHJ
to get started, enter:
ipfs cat /ipfs/QmcLnHDuhN7bCbdv5FRbYiTNKuqNhs1WSCUezFPt7F4vHJ/readme
記住ipfs_host1中的peer identity: QmcLnHDuhN7bCbdv5FRbYiTNKuqNhs1WSCUezFPt7F4vHJ信息侈离,在后面啟動 ipfs_host2服務(wù)的時候需要用到
刪除默認配置中的引導(dǎo)節(jié)點信息
ipfs bootstrap rm --all
修改接口調(diào)用地址
打開服務(wù)啟動配置文件
vi config
修改配置文件中 Addresses中的 API值:
"API": "/ip4/127.0.0.1/tcp/5001" --> "API": "/ip4/0.0.0.0/tcp/5001"
注意,修改后調(diào)用 sdk 初始化 IPFS 對象的時候才能遠程訪問 ipfs 服務(wù)筝蚕。如果沒有修改則初始化 IPFS 對象的時候則會出錯卦碾。
環(huán)境啟動
啟動 ipfs 服務(wù)
啟動 ipfs_host1服務(wù)
ipfs daemon
啟動 ipfs_host2服務(wù),注意下面的命令使用到ipfs_host1初始化時生成的peer identity
ipfs bootstrap add /ip4/宿主機ip/tcp/4001/ipfs/QmcLnHDuhN7bCbdv5FRbYiTNKuqNhs1WSCUezFPt7F4vHJ
ipfs daemon
環(huán)境驗證
進入 ipfs_host1容器中執(zhí)行以下命令
創(chuàng)建測試文件
cd ~
echo test > test.txt
上傳文件
ipfs add text.txt
ipfs 上傳文件后會有如下提示信息反饋
added QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH test.txt
其中QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH就是文件test.txt的hash值
ipfs 是根據(jù)文件內(nèi)容進行 hash 只要文件內(nèi)容不變起宽,只修改文件名是不會影響最終的上鏈文件 hash 值的洲胖。
進入 ipfs_host2容器中驗證上傳文件
執(zhí)行文件查看命令,查看文件內(nèi)容
ipfs cat QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH
執(zhí)行命令后坯沪,控制臺會返回查詢結(jié)果:test
至此绿映,ipfs 私有網(wǎng)絡(luò)搭建成功。
有興趣的朋友可以改寫 dockerfile 的內(nèi)容重寫 entrypoint執(zhí)行命令的內(nèi)容屏箍,減少修改 ipfs 服務(wù)默認配置部分的操作步驟绘梦。
java-ipfs-http-client的使用
pom.xml中添加依賴橘忱,這里需要根據(jù) 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/10.121.60.26/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());//返回結(jié)果里面獲取保存文件的唯一hash,基于文件內(nèi)容的 hash
//下載文件
Multihash filePointer = Multihash.fromBase58("Qmc51yHGyaxdRsUwBozP9tQuTRQuXLkZv3sPEcpSgb8BxP");//參數(shù)為文件 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();
結(jié)語
ipfs 并不僅僅只用于分布式文件存儲卸奉,如果想要深入了解 ipfs 功能可以參考ipfs - 命令手冊钝诚。