|
|
本帖最后由 赤膊医数 于 2021-4-22 23:41 编辑 4 x) U5 a7 ?4 B% v" W/ w
+ u0 B1 O: W/ `3 ]2 u2018年,最火爆且值得期待的区块链项目莫过于EOS和IPFS。1、IPFS简介- IPFS是什么! t; U# Y7 A' p/ E
星际文件系统IPFS(InterPlanetary File System)是一个面向全球的、点对点的分布式版本文件系统,目标是为了补充(甚至是取代)目前统治互联网的超文本传输协议(HTTP),将所有具有相同文件系统的计算设备连接在一起。原理用基于内容的地址替代基于域名的地址,也就是用户寻找的不是某个地址而是储存在某个地方的内容,不需要验证发送者的身份,而只需要验证内容的哈希,通过这样可以让网页的速度更快、更安全、更健壮、更持久。
' g9 {/ U2 f8 a以上内容来自巴比特官网介绍* D" o V- j; d
IPFS是基于区块链技术的去中心化存储网络,实现了永久性存储。- G9 O0 I5 P; _
- IPFS的火热- o2 i1 L7 X8 K% F
Filecoin ICO是迄今为止涉及金额最大的ICO,仅一小时就募集了接近2亿美元,打破ICO记录,成为2017年最火爆的区块链项目。IPFS项目吸引了世界各地数字货币投资者和互联网从业者的密切关注,2018年比较值得期待的是IPFS主网的上线。然而就在前段时间,官方公布说上线时间延期到年底。
6 s7 ]1 d& |5 T注:Filecoin是IPFS激励层的加密数字货币(即代币),有点类似于以太坊平台上的以太币。
+ u% \7 ?' {* c8 R+ h" CIPFS官网:https://ipfs.io/
w5 l9 m5 B% A- lFilecoin官网:https://filecoin.io/
+ r4 ]/ Y8 ^; \ z/ {& b - IPFS的应用案例) S% u5 _0 x% u# z. ~: X( R( a
GitHub有两款开源项目,且有对应网址,分别是音乐播放器和视频播放器。! w( g, Z5 \/ B
1 ^# v0 k" g, V- IPFS音乐播放器
) ]* G$ u- v' f' x8 m1 c6 x1 z- @- z+ S8 j) A; M: Z
+ `# k$ z0 ?, b R5 s* |7 U" o
: Q& D3 R; ^" ?# n- F" S% P" W* f- E; w; D/ z8 A! e
IPFS音乐播放器' @, S' v0 J) X# u- D6 b# o
1 q* w* m' l/ o- ]
IPFS音乐播放器网址:https://diffuse.sh/
3 a( C( |5 `5 U, S& e4 h& |6 l& ]; nGitHub地址:https://github.com/icidasset/diffuse# q3 u9 a. b: O: c
- IPFS视频在线播放器% r7 a5 n- _8 a I$ O6 K
: s7 F$ J" l, }" w. E) Q- |- r% e( m; D9 t( o
4 @( K% j! J" v- b* N: {* V
: X6 n( z- [& w( Q1 TIPFS视频在线播放器首页
; h9 n/ F0 U+ H0 K4 b! V0 V( M. G/ z" w$ G
0 f- K4 S1 D: o! `+ |
9 H3 t3 A6 D w
3 ]7 t6 \: C; N8 }* i
0 g- |6 |. z; i" Y, a0 C( wIPFS视频在线播放器播放电影
4 E9 g; X# B4 I- {
0 M3 L! j3 I' {% k x7 y号称是国内第一个IPFS应用# n! |0 O8 f9 {) K/ H* N8 @
IPFS视频在线播放器网址:http://www.ipfs.guide/
6 S2 U1 k0 _$ f. e$ f4 \5 fGitHub地址:https://github.com/download13/ipfstube7 r/ Z" ^% F1 O6 {: O) q
可用于测试的电影视频Hash(这里只列举两部):
+ Z+ ]+ w* ~2 u9 G8 E* R神秘巨星:QmWBbKvLhVnkryKG6F5YdkcnoVahwD7Qi3CeJeZgM6Tq68; X: C7 g- g) I4 H
盗梦空间:QmQATmpxXvSiQgt9c9idz9k3S3gQnh7wYj4DbdMQ9VGyLh1 \ p) [$ H: [
2、IPFS的安装既然IPFS这么牛,有必要了解一下IPFS的开发,先从IPFS的安装开始。( S# ]5 k. t. m) F6 O
- IPFS Desktop$ [3 a% M# H7 k6 N7 h
当然,可以直接安装IPFS节点桌面管理软件来体验一下。该软件可以方便地运行和管理自己的节点,查看IPFS节点资源信息,支持二次开发。该项目是Node.js编写的,已开源。$ E& t$ f+ t% p4 h
, J( e# J7 p& p# k7 t4 d3 O
; y* J% z% B% a
8 q( ?/ J" @5 r+ ~ j) ]1 S5 I( V- X
( {/ z% |3 ^& t: ^! o- K
IPFS节点桌面管理软件# i, G7 Q ]* q7 K3 Z4 B
_' @7 y6 g/ h. P+ \
GitHub地址:
) X' T% y7 t! h2 r& V1 Ehttps://github.com/ipfs-shipyard/ipfs-desktop
- V1 H2 ~/ q$ o" ~* g. K - Go-IPFS4 t* X, j9 K" D$ y
进入IPFS的官网,找到并切换到"Install"页面,点击"Download IPFS for your platform",会跳转到如下网址(需要翻墙):
8 v, ?; O \" v, D! R' Zhttps://dist.ipfs.io/#go-ipfs
# W7 K6 E' M8 L9 y/ g4 R) d
2 E6 `) u0 _& x7 D/ _ g1 f
4 e5 T6 l% M4 z5 d! }5 t3 B
) p6 r7 E: ]0 x1 O' I% \% d' M下载Go-IPFS
9 }# G+ |% [$ N( A. j+ y' |; T' u( x9 n# x+ j
如果打不开,可以试着去Github查看安装方法
4 b9 {! ~) u0 `5 wGitHub地址:https://github.com/ipfs/go-ipfs
+ o( z7 e; y1 D! U+ P6 F' C将网页下载好的文件解压出来,下载的是"go-ipfs_v0.4.13_darwin-amd64.tar.gz",解压出来的是go-ipfs文件夹,
9 S) a' S7 ^! r5 D然后打开终端,进入到go-ipfs文件夹根目录,复制ipfs文件到系统的bin目录,然后可以通过"ipfs version"来检查,操作如下:
# |5 n6 G3 ? f+ u. l5 ^4 c8 Q: {wenzildeiMac:go-ipfs wenzil$ pwd/Users/wenzil/Desktop/study/go-ipfswenzildeiMac:go-ipfs wenzil$ lsLICENSE README.md build-log install.sh ipfswenzildeiMac:go-ipfs wenzil$ cp ipfs /usr/local/bin/ipfswenzildeiMac:go-ipfs wenzil$ ipfs versionipfs version 0.4.13
+ w$ |+ D+ j0 v9 A- d4 w% o' j 3、IPFS节点的创建、查看和启动以下是安装官网的Go-IPFS步骤下实验的( V* }' W3 V$ K: C
- 创建节点! {) |( g, E/ K) V
进入到当前用户的根目录,并使用"ipfs init"命令创建节点,可以用"open ./"打开创建节点生成的".ipfs"目录。
: g# {8 E! Q' L1 e$ owenzildeiMac:go-ipfs wenzil$ cd ~/wenzildeiMac:~ wenzil$ pwd/Users/wenzilwenzildeiMac:~ wenzil$ ipfs initinitializing IPFS node at /Users/wenzil/.ipfsgenerating 2048-bit RSA keypair...donepeer identity: QmWH4xmGBznY9CJ4SjxpxWqGwMwrFtPdjgeweLCfJxW8j9to get started, enter: ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readmewenzildeiMac:~ wenzil$ cd .ipfswenzildeiMac:.ipfs wenzil$ open ./
6 }% L3 d' }8 I+ n& L / p. A) u2 D# }/ Z9 P( T: u# c& c
& G' H9 T6 J' {6 z, \8 N8 b3 Y" _3 O
* e$ r5 F! N( B/ Z v9 yIPFS节点的创建& Q: q9 W2 ]. Q, G8 y
1 K1 \! k( p, W5 J9 K0 {: |0 }- 查看节点id
0 p v" s$ K. \4 `wenzildeiMac:.ipfs wenzil$ ipfs id{ "ID": "QmWH4xmGBznY9CJ4SjxpxWqGwMwrFtPdjgeweLCfJxW8j9", "PublicKey": "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCt98O5zNptBtmSF6xYdOHAMunQsXE9rAmgqBXVPLJk+AoaBjNiAipB+sTXKwaj8stp9c3iuSzz10+dyYI38bq4TPDCsHnQ3PjKSgZwEaT0M6pJhGqJcSbLY57CjQOEwgFe+tw3b4hcoDvvNJMG0dZZg1r9xnfevBz0DNewlj2vtviSTQL6r/ZXlD04GsytxTSQ2pzMJTG3QmYyokeZ37DT7Vwa+IJjDCiDJC5BlZ204zunZBx3tqWUn2Hr2NtEX+4YDdX4SBHa0ZDNqZmzLRe5YlAXjVI0ONHs+BVsC1v1L5we52iSYCSgVHoxRP/pa9EZdHMvgs9QeAa5jO90yxgTAgMBAAE=", "Addresses": null, "AgentVersion": "go-ipfs/0.4.13/", "ProtocolVersion": "ipfs/0.1.0"} - 修改IPFS默认存储空间
0 u( v4 W6 u" n# p! ?存储节点默认存储大小为10G,如果你想修改存储空间,可以修改config配置文件,找到StorageMax并修改
) e! R: a8 V5 K: J+ q3 MwenzildeiMac:~ wenzil$ export EDITOR=/usr/bin/vimwenzildeiMac:~ wenzil$ ipfs config edit 6 ~: B7 F# m( p7 [4 `2 Y. }
) P, G" Y) e" I |/ W5 F) v
0 }0 {5 C ?) k: r4 F a
修改IPFS默认存储空间
]8 S( F a4 P5 J
8 F7 ]' j7 s3 Q/ O1 N - 启动和同步节点服务器
" [4 J5 G% F) Z执行"ipfs daemon"命令,可以同步节点数据到IPFS网络。
) t) m9 U/ h2 N% q* u3 D* _wenzildeiMac:.ipfs wenzil$ ipfs daemonInitializing daemon...Adjusting current ulimit to 2048...Successfully raised file descriptor limit to 2048.Swarm listening on /ip4/127.0.0.1/tcp/4001Swarm listening on /ip4/192.168.1.100/tcp/4001Swarm listening on /ip6/::1/tcp/4001Swarm listening on /p2p-circuit/ipfs/QmWH4xmGBznY9CJ4SjxpxWqGwMwrFtPdjgeweLCfJxW8j9Swarm announcing /ip4/100.64.9.179/tcp/55898Swarm announcing /ip4/127.0.0.1/tcp/4001Swarm announcing /ip4/192.168.1.100/tcp/4001Swarm announcing /ip6/::1/tcp/4001API server listening on /ip4/127.0.0.1/tcp/5001Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8082Daemon is ready h; ^" E: B5 o- g
4、IPFS运行体验- IPFS查看ReadMe! H) C- s: f, ^) S: c8 n9 ^
可以回去查看执行"ipfs init"命令的时候,返回的内容。打开一个新的终端,操作如下:
Q* ]# ~' ^* i/ Z7 _8 }( vwenzildeiMac:~ wenzil$ ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readmeHello and Welcome to IPFS!██╗██████╗ ███████╗███████╗██║██╔══██╗██╔════╝██╔════╝██║██████╔╝█████╗ ███████╗██║██╔═══╝ ██╔══╝ ╚════██║██║██║ ██║ ███████║╚═╝╚═╝ ╚═╝ ╚══════╝If you're seeing this, you have successfully installedIPFS 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 - Web管理界面# ~ \( v w; N1 z0 G- ^
IPFS节点服务器启动后,可以用浏览器访问:http://localhost:5001/webui
/ j5 T" ?$ _* k7 f; y1 H有本地配置、节点连接、本地节点文件等信息,如图:
* L- k8 G- o& J% }+ ?
$ j7 u7 {3 t k0 w9 M4 e9 d* \. i5 o4 u1 ^4 `
9 x* S; n& O: c# L& }/ E
Q* F' g" a" S, H, \
IPFS的Web管理界面
2 H- ~: j2 n: x1 ?0 a
0 k$ n- L4 I" _# u: t
2 j# {3 J) f! w! K/ L, P: `, {) Z, L( a9 k
5、设置跨域资源共享当我们在前端通过js接口操作ipfs时,会遇到跨域资源访问问题,可以在终端执行以下配置来解决:
& E/ {+ \5 N0 J) D ^+ Yipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT","GET", "POST", "OPTIONS"]'ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]'ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '["Authorization"]'ipfs config --json API.HTTPHeaders.Access-Control-Expose-Headers '["Location"]'6、IPFS的基本操作6.1 添加单个文件到IPFS节点- 新建文件
( p1 w9 h: N" G. t, B, XwenzildeiMac:ifps_test wenzil$ vi test.txtwenzildeiMac:ifps_test wenzil$ cat test.txt IPFS测试文件 - 添加文件到IPFS节点
, I( A* ?% L9 f6 K$ IwenzildeiMac:ifps_test wenzil$ ipfs add test.txt added QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab test.txt添加文件到IPFS节点后,返回了文件的哈希值
1 ?7 k1 f% n8 Y - 查看IPFS节点的文件7 U4 v4 K( W: B7 K. j% `
wenzildeiMac:ifps_test wenzil$ ipfs cat QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbIPFS测试文件注意:此时的文件只是添加到了本地的IPFS节点,读取的是本地数据,可以通过如下网址查看。% A0 i; o2 P. t7 n* v: h
http://localhost:8080/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab4 O4 p: | z$ K# _; F
通过"ipfs daemon"命令启动节点服务器,会将本地节点文件同步到外网,同步成功后,这时就可以访问如下网址来查看(如果访问失败,试着翻墙看看)。7 `" _' @3 P" q- U5 I
https://ipfs.io/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab+ r+ L# U8 S0 T* h# L$ p/ Q9 T8 X
1 `, }* N8 w( K4 H3 ]! ?; t) s& i& W
& V6 k7 L7 R8 D) m
% a2 _* H, V6 _- q/ k ?查看IPFS文件内容- j; Y5 A" k5 W
" i) \4 ?) O2 ^
如果访问成功的话,说明已经存储到IPFS网络中。目前IPFS网络暂未加入代币Filecoin机制,所以存储读取文件免费,速度也比较慢。
4 r3 F9 c9 ^" b - 下载IPFS节点的文件3 T% L) K5 L8 E) B1 }/ ?& y
wenzildeiMac:ifps_test wenzil$ ipfs get QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbSaving file(s) to QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab 25 B / 25 B [========================================================] 100.00% 0s查看当前目录,发现多了一个"QmSV..."的文件") B, x7 p$ C+ w6 ?' n9 [: k3 M
6 A a0 w7 y" B9 J. k+ I
- k8 {- }7 E+ T' [7 P5 ]
6 a1 |; T5 l$ D3 i6 b, H7 `) ~& @
# ?2 i: W' ]" G- \+ _4 M2 _. |" }下载IPFS节点的文件
6 d8 \# @8 `; u/ O9 m; D
/ i2 I9 s* a. d& o5 N" z
2 E' W) r( s+ a+ L2 g* O! U 6.2 创建文件夹存储文件- ipfs命令新建文件夹2 L) `* n( ]! H) g/ B$ @3 j x. |
wenzildeiMac:ipfs_test wenzil$ pwd/Users/wenzil/Desktop/study/ipfs_testwenzildeiMac:ipfs_test wenzil$ ipfs files mkdir /wenzilwenzildeiMac:ipfs_test wenzil$ ipfs files cp /ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab /wenzil/test.txtwenzildeiMac:ipfs_test wenzil$ ipfs files lstestwenzilwenzildeiMac:ipfs_test wenzil$ ipfs files ls /testwenzilwenzildeiMac:ipfs_test wenzil$ ipfs files rm -rf /testwenzildeiMac:ipfs_test wenzil$ ipfs files lswenzilwenzildeiMac:ipfs_test wenzil$ ipfs files ls /wenziltest.txtwenzildeiMac:ipfs_test wenzil$ ipfs files read /wenzil/test.txtIPFS测试文件注:"ipfs files rm -rf /文件夹名"可以删除文件夹。- ~$ b, ~0 ^) O. l
2 O: b c) N* O$ l: O 6.3 IPFS上传文件夹- ipfs命令添加文件夹: F7 O3 M' K+ L0 n3 l2 w5 K
先在本地创建一个文件夹和对应文件,如图:! s4 b" Z g m; z; G( ]4 ? p
6 h( x. ^! B. e g
4 D6 m+ q( a n# e$ o
3 b4 Z2 ~ {$ V# D% f" d8 K; T: |8 [8 k# o4 [. R
本地创建文件夹及文件& h* H4 j. X! D/ ^" n
6 q. \5 J* ?2 i9 ?* m/ D0 u然后通过"ipfs add -r 文件夹"命令添加整个文件夹
# t n W i; @5 B wenzildeiMac:ipfs_folder wenzil$ pwd /Users/wenzil/Desktop/study/ipfs_folder wenzildeiMac:ipfs_folder wenzil$ ls portrait.jpeg readme.txt wenzildeiMac:ipfs_folder wenzil$ cd .. wenzildeiMac:study wenzil$ pwd /Users/wenzil/Desktop/study wenzildeiMac:study wenzil$ ipfs add -r ipfs_folder/ added QmbHptfJfyuGAZxstFYgAVfz33cytR1seTD3ZabBSDd899 ipfs_folder/portrait.jpeg added QmPEWgwQEHD6qxm5cUivTEZ252T123DvQ5L6HyUDgViQv T ipfs_folder/readme.txt added QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj ipfs_folder wenzildeiMac:study wenzil$ - 查看文件夹的文件内容
* n: J, v/ n9 |0 \wenzildeiMac:study wenzil$ ipfs cat QmPEWgwQEHD6qxm5cUivTEZ252T123DvQ5L6HyUDgViQvT 我是区块链开发小白,请大家多多赐教,谢谢。欢迎阅读我的区块链系列文章,简书地址:https://www.jianshu.com/u/5f809ab3698cwenzildeiMac:study wenzil$ ipfs cat /ipfs/QmPEWgwQEHD6qxm5cUivTEZ252T123DvQ5L6HyUDgViQvT我是区块链开发小白,请大家多多赐教,谢谢。欢迎阅读我的区块链系列文章,简书地址:https://www.jianshu.com/u/5f809ab3698cwenzildeiMac:study wenzil$ ipfs cat /ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj/readme.txt我是区块链开发小白,请大家多多赐教,谢谢。欢迎阅读我的区块链系列文章,简书地址:https://www.jianshu.com/u/5f809ab3698c - 查看IPFS对应文件夹% @5 Q1 r! d7 f* a
访问文件夹对应的IPFS地址:
9 l& A. S% S3 }5 s' \https://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj( \0 b1 l9 P X# ^
第一次访问的时候,需要同步数据到IPFS网络,等待时间有点久,慢到让你以为同步失败了。$ _" O r& ]- J, I) c1 |
0 m" f/ F2 s0 j: m2 [- q
7 T* U# W6 k2 k3 r, O( O0 P4 v" n! l' L. ^/ J
查看IPFS对应文件夹6 }3 `- U+ j: q: B5 z
2 n* C* A7 u7 ~
访问文件夹对应的文件,如看到图片文件,访问ipfs网关:8 N3 L0 _7 X9 S$ G8 [
https://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj/portrait.jpeg
( S6 D/ m& ^' d$ k6 K/ D- g6 Y" N! h x
3 l; Q# }/ D* \, p: e
; x6 r a2 y( D查看IPFS文件夹对应文件; R8 I: y* E3 y# Y0 I
& Z8 O' m/ U) w8 [, m或者通过文件的Hash来访问,如访问txt文件的地址: z5 G6 B) t( u# M
https://ipfs.io/ipfs/QmPEWgwQEHD6qxm5cUivTEZ252T123DvQ5L6HyUDgViQvT, _$ f. o. X$ |$ X$ V# N
/ j( @, l6 \4 v1 E7 c
2 w5 ^9 \& J2 H* V6 A+ _1 R
. s6 o/ d+ A" t* m* b
通过文件Hash访问查看2 R& P( \6 G; u
* N9 c: z P/ m1 M0 I4 {
/ a# d l1 e7 R
6.4 添加简单网页到IPFS节点- 网页效果和项目结构
! }1 m( I3 W" E7 @; I5 X9 l0 ]1 _实现一个简单的实时显示系统当前时间的网页,效果如图:
) U0 s, E3 P! \0 |. X9 j2 G! d/ W& l8 } h
4 A/ Q' T( U* J( ?/ p. r" p
. u: {* U& o# Z' x- B
8 x4 h; D( p) P% h, XIPFS添加简单网页
2 ~( L/ k4 }9 \% A# j
3 |9 W, I8 e; r; a! b工程结构如图:
8 G# j8 `4 Y/ ^1 h" T' I; b7 G9 T% m' O
. q9 Q: V6 ?3 w G9 a! S- w
5 j; q8 J1 e* E4 b; P( U) Q! {
" A- L, n, u7 B8 z- D' T3 H' e
网页工程结构" |4 _4 y7 y& k9 g
! H0 k) e; C2 N% q$ ^
( J0 h! ?! c5 o- ?; V 实现代码比较简单,这里就不贴代码了。8 \/ A# q$ m1 S
- ipfs命令添加文件夹7 c; @) u- q: F* y& |
wenzildeiMac:study wenzil$ ipfs add -r ipfs_htmladded QmTj49dgFgFhfNRTUYyUSzk3puj7vvDoVsAynFrL7GAj1d ipfs_html/index.htmladded QmeHFBSyN9KqeZWKyKTWKYzDRU192YWDRjf6sLWFWhwk2z ipfs_html/styles.cssadded QmWkEfgL2pjo7n8b9YBCv4qwE77YWePkSscxiHQfPpwpkp ipfs_html/time.jsadded QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD ipfs_html记得要开启IPFS节点服务器进行数据的同步,可以使用"ipfs daemon"命令在新的终端窗口打开运行。
- M: B8 G6 f' s3 i. QwenzildeiMac:~ wenzil$ ipfs daemonInitializing daemon...Adjusting current ulimit to 2048...Successfully raised file descriptor limit to 2048.Swarm listening on /ip4/127.0.0.1/tcp/4001Swarm listening on /ip4/192.168.6.31/tcp/4001Swarm listening on /ip6/::1/tcp/4001Swarm listening on /p2p-circuit/ipfs/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrzSwarm announcing /ip4/127.0.0.1/tcp/4001Swarm announcing /ip4/192.168.6.31/tcp/4001Swarm announcing /ip6/::1/tcp/4001API server listening on /ip4/127.0.0.1/tcp/5001Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8082Daemon is ready - 访问ipfs对应文件
- h7 L, W' e% c% T x浏览器访问ipfs网关:) A" e. g; \: {% `3 K8 _2 ^( h" c5 O( |
https://ipfs.io/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD/
# N- d* M R3 z; i0 S6 }1 Q& f. X% e: _. S; y, P6 T/ G4 w
) S) q( _% \. \# d" b
9 _6 C4 S; R* F* j$ T查看IPFS对应网页) s* a+ g8 W. C! F
. B7 t' f P( ? O8 z L* [
A3 |1 D! f7 w# A) q! `; y
6.5 IPNS绑定节点名- IPNS绑定节点操作6 @8 r: ^7 ?7 F( D/ A
每次修改文件内容后,文件的哈希值就会发生变化。对于网站而言,发布后可能还需要做修改,这时需要IPNS绑定节点名。每次更新网站内容后,重新publish一次更新发布到IPNS即可。
- q! O4 q& i f6 O6 v8 x1 o% o刚才的html根目录的哈希值是QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD,操作如下:+ F9 O( s# @( t9 S
wenzildeiMac:study wenzil$ ipfs name publish QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDDPublished to QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz: /ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 查看当前节点
) f2 X) ^% L/ E8 |9 s. o& s7 A8 EwenzildeiMac:study wenzil$ ipfs id{ "ID": "QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz", "PublicKey": "CAASpg......", "Addresses": [ "/ip4/127.0.0.1/tcp/4001/ipfs/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz", "/ip4/192.168.6.31/tcp/4001/ipfs/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz", "/ip6/::1/tcp/4001/ipfs/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz", "/ip4/14.xxx.xxx.xxx/tcp/4001/ipfs/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz", "/ip4/61.xxx.xxx.xxx/tcp/20472/ipfs/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz" ], "AgentVersion": "go-ipfs/0.4.13/", "ProtocolVersion": "ipfs/0.1.0"} 发现"ID"和上面"Published to"返回的节点一致,都是"QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz"% ?7 d& {$ D% T7 ~& `
- 验证节点
/ f' F7 O, B1 u2 `命令为:"ipfs name resolve 节点ID“
# b+ o' I- v xwenzildeiMac:study wenzil$ ipfs name resolve QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 访问IPNS对应文件" C: _5 z) Z3 c
浏览器访问ipfs网关:$ B0 Y$ ?8 ^/ {6 M% t
https://ipfs.io/ipns/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/) L' ?6 P% c5 e& f
" }4 u* I" M0 `+ Q+ Y; H+ _6 Q" t i
# L# H- M# m4 x7 @1 C2 I7 B: r
% I1 ^2 z1 y) H. Y H+ @9 I/ W
3 O( Y& l, q7 T( c
查看IPNS对应网页9 ], _& k" W2 K$ P9 v* x' j0 n6 R
3 P# m" a8 N; r. ?% \1 U7、IPFS与以太坊DApp开发实战- IPFS与以太坊DApp结合的好处
1 u4 C3 C `. `在以太坊平台上,往区块链写入数据需要花费以太币,调用智能合约执行每一行代码的时候,都需要一定量的gas交易费。区块链存储大数据成本很高,而且不合理。
& w; Q, R; o; X0 X- Y, D9 T) \可以先将文件存储到IPFS,然后得到文件的Hash存储到以太坊区块链中。读取文件的时候,从以太坊区块链中获取文件的Hash,再通过Hash来读取IPFS网络上的文件。6 Y& K2 E3 V! j& k: u
使用官方提供的ipfs-api,可以很方便地在代码中操作节点将数据上传到IPFS,或者通过Hash从IPFS读取数据。5 B% f9 R/ B5 _6 C* O5 }( i9 j3 r
Truffle框架提供了快速搭建包含以太坊智能合约的React项目,可以通过"truffle unbox react"创建工程,然后安装ipfs-api依赖库。于是,可以在前端方便地调用IPFS的接口来读取、上传文件。) s$ o# ^7 z0 V- L
truffle unbox react官网:6 Q: p$ q, ] U; J
http://truffleframework.com/boxes/react2 n* g; G' x! X+ p4 t; j4 {2 N
- IPFS与DApp开发实战
, ?5 W+ \1 n3 ]/ z* b话不多说,开始进入实战开发。& ^5 K; W3 R5 y- b1 e" q, A+ I# I8 O g
7.1 安装Truffle unbox react新建一个空目录"ipfs_dapp",然后执行安装命令3 Y: B2 c9 }+ \ e7 G- I* O3 f) Z
truffle unbox reactwenzildeiMac:ipfs_dapp wenzil$ pwd/Users/wenzil/Desktop/study/ipfs_dappwenzildeiMac:ipfs_dapp wenzil$ truffle unbox reactDownloading...Unpacking...Setting up...Unbox successful. Sweet! Commands: Compile: truffle compile Migrate: truffle migrate Test contracts: truffle test Test dapp: npm test Run dev server: npm run start Build for production: npm run build7.2 安装ipfs-apinpm install --save ipfs-apiwenzildeiMac:ipfs_dapp wenzil$ npm install --save ipfs-apinpm WARN deprecated bignumber.js@6.0.0: Custom ALPHABET bug fixed in v7.0.2react-box@0.1.0 /Users/wenzil/Desktop/study/ipfs_dapp├—┬ ipfs-api@22.0.0 │ ├—— async@2.6.1 │ ├—— big.js@5.1.1 │ ├—┬ bs58@4.0.1 │ │ └—— base-x@3.0.4 # ...... 省略N多行输出7.3 修改智能合约代码修改contracts目录中的"SimpleStorage.sol",修改后完整代码:. U3 V n# r2 \! _9 @. r" L
pragma solidity ^0.4.18;contract SimpleStorage { // 用于存储图片的哈希值 string storedData; function set(string x) public { storedData = x; } function get() public view returns (string) { return storedData; }} 修改"Migrations.sol"7 P: V* F2 @! j' d
function Migrations() public { owner = msg.sender;}修改为:constructor() public { owner = msg.sender;}7.4 编译智能合约truffle compilewenzildeiMac:ipfs_dapp wenzil$ truffle compileCompiling ./contracts/Migrations.sol...Compiling ./contracts/SimpleStorage.sol...Writing artifacts to ./build/contracts7.5 部署智能合约进入remix-ide,复制SimpleStorage.sol代码,然后切换到"Run"菜单,选择"Injected Web3"进行智能合约的部署* W" u: Z' t$ r
0 I# w# C) b9 r2 |0 e
; ?' k; ?& S$ N' k6 E7 Y% ^! y. B+ K1 e& Z! Q& f% f% I a. a
Remix-IDE部署智能合约; o1 i9 `, J" S7 G# v
6 K% T$ K7 ~" S- |' o$ E% o
. L( }& W# l9 X6 L, ?! T
+ ~% v" u+ \. q# _6 Z
j Q2 r, R8 kRemix-IDE部署智能合约-确认
0 f0 q- X- a: B9 G
' C& Z& S7 c0 ~" o/ Z* U& g% L然后复制智能合约地址,App.js文件中会用到合约地址为:"0xb177d6cf6916f128c9931e610c63208d9c5a40f3"! h0 L! Y, |) q9 L8 b+ r
7.5 修改App.js文件import React, {Component} from 'react'import SimpleStorageContract from '../build/contracts/SimpleStorage.json'import getWeb3 from './utils/getWeb3'import './css/oswald.css'import './css/open-sans.css'import './css/pure-min.css'import './App.css'const ipfsAPI = require('ipfs-api');const ipfs = ipfsAPI({ host: 'localhost', port: '5001', protocol: 'http'});const contract = require('truffle-contract')const simpleStorage = contract(SimpleStorageContract)let account;// Declaring this for later so we can chain functions on SimpleStorage.let contractInstance;let saveImageToIPFS = (reader) => { return new Promise(function(resolve, reject) { const buffer = Buffer.from(reader.result); ipfs.add(buffer).then((response) => { console.log(response) resolve(response[0].hash); }).catch((err) => { console.error(err) reject(err); }) })}class App extends Component { constructor(props) { super(props) this.state = { blockChainHash: null, web3: null, address: null, imageHash: null, isSuccess: false }}componentWillMount() { ipfs.swarm.peers(function(err, res) { if (err) { console.error(err); } else { // var numPeers = res.Peers === null ? 0 : res.Peers.length; // console.log("IPFS - connected to " + numPeers + " peers"); console.log(res); }});getWeb3.then(results => { this.setState({web3: results.web3}) // Instantiate contract once web3 provided. this.instantiateContract() }).catch(() => { console.log('Error finding web3.') })}instantiateContract = () => { simpleStorage.setProvider(this.state.web3.currentProvider); this.state.web3.eth.getAccounts((error, accounts) => { account = accounts[0]; simpleStorage.at('0xb177d6cf6916f128c9931e610c63208d9c5a40f3').then((contract) => { console.log(contract.address); contractInstance = contract; this.setState({address: contractInstance.address}); return; });})}render() { return ( <div className="App"> <div style={{marginTop:10}}>智能合约地址:</div> <div>{this.state.address}</div> <div style={{marginTop:10}}>上传图片到IPFS:</div> <div> <label id="file">选择图片</label> <input type="file" ref="file" id="file" name="file" multiple="multiple"/> </div> <button style={{marginTop:10}} onClick={() => { var file = this.refs.file.files[0]; var reader = new FileReader(); reader.readAsArrayBuffer(file) reader.onloadend = function(e) { console.log(reader); saveImageToIPFS(reader).then((hash) => { console.log(hash); this.setState({imageHash: hash}) }); }.bind(this); }}>开始上传</button> <div style={{marginTop:10}}>图片哈希值:{this.state.imageHash}</div> <button onClick={() => { contractInstance.set(this.state.imageHash, {from: account}).then(() => { console.log('图片的hash已经写入到区块链!'); this.setState({isSuccess: true}); }) }}>图片哈希写入区块链</button> { this.state.isSuccess ? <div style={{marginTop:10}}> <div>图片哈希成功写入区块链!</div> <button onClick={() => { contractInstance.get({from: account}).then((data) => { console.log(data); this.setState({blockChainHash: data}); }) }}>从区块链读取图片哈希</button> </div> : <div/> } { this.state.blockChainHash ? <div style={{marginTop:10}}> <div>从区块链读取到的哈希值:{this.state.blockChainHash}</div> </div> : <div/> } { this.state.blockChainHash ? <div style={{marginTop:10}}> <div>访问本地文件:</div> <div>{"http://localhost:8082/ipfs/" + this.state.imageHash}</div> <div>访问IPFS网关:</div> <div>{"https://ipfs.io/ipfs/" + this.state.imageHash}</div> <img alt="" style={{width: 100, height: 100 }} src={"https://ipfs.io/ipfs/" + this.state.imageHash}/> </div> : <img alt=""/> } </div>); }}export default App7.6 新建终端,执行"npm start"命令,结果如图:2 j1 _9 `! N1 [* N1 i& p
5 o" @: g' e! ] B4 M. }0 r
* h1 z: q: u, ^& ?npm_start
% a8 m3 P9 J% _% d. o9 C$ s/ T2 g7 G- ^9 b0 d) ]
会自动打开网页,然后上传一张本地图片,之后点击"图片哈希写入区块链"按钮
4 Y F( y2 w; n0 }6 e7 A
1 I2 t( y7 g2 ]& @
) U w: i+ H$ p- ^* v. ~+ Y9 _" T& K% @5 c5 ?2 d) |
运行结果1
1 S9 z6 M" _; X/ `6 ~& Q
" a8 `8 u7 D) G6 T7 h最终效果如图:+ d: m0 b, r5 J7 Q- C1 r
0 S" K2 P" t9 P+ W( r0 m0 a, |* a- i3 @& n% {- X' g% ` a* K) d
) z1 z( r4 q) E* a
) ~; C" _5 s8 d9 c运行结果) F+ a9 Q# {$ {. R |
+ c) Z/ }0 Y7 Z- M5 W D访问IPFS网关:4 F! j9 D L: U8 i b6 p( F
https://ipfs.io/ipfs/QmbHptfJfyuGAZxstFYgAVfz33cytR1seTD3ZabBSDd8992 _5 G/ X u; E9 O5 n
发现图片已经成功写入IPFS,如图:
9 z2 L6 r& B! A9 S: i8 b7 e% p
. {8 v5 J+ W, V3 `+ |% P% Y8 A" T9 O9 ]' ^7 N$ v
: g4 l7 j) f, M' f7 X4 J1 M- A) Q1 H! m1 d
运行结果3
B+ c6 ?- g2 ]: P& I, a% c, E( d1 ^3 L" Z+ c7 `
备注:本地IPFS网关端口默认为8080,我的电脑上端口冲突了,系统自动修改为8082。; [4 k$ Z4 e* O+ Q1 N1 O
搞定,收工。) Y" V6 i7 C% S$ Q
PS:刚入坑的小白,很多不懂,还请各位大佬多赐教,谢谢!
: Q: a) J% y5 h$ F3 N2 Q- `8 Z3 p9 A0 I. `9 t( L5 }
|
|