|
|
本帖最后由 赤膊医数 于 2021-4-22 23:41 编辑
2 {; Y) r1 ?* N+ o5 |2 [7 t# V- s& Q( }1 v) L6 |. I/ n: ]
2018年,最火爆且值得期待的区块链项目莫过于EOS和IPFS。1、IPFS简介- IPFS是什么
a! N9 F' E+ n. s8 h3 R9 o星际文件系统IPFS(InterPlanetary File System)是一个面向全球的、点对点的分布式版本文件系统,目标是为了补充(甚至是取代)目前统治互联网的超文本传输协议(HTTP),将所有具有相同文件系统的计算设备连接在一起。原理用基于内容的地址替代基于域名的地址,也就是用户寻找的不是某个地址而是储存在某个地方的内容,不需要验证发送者的身份,而只需要验证内容的哈希,通过这样可以让网页的速度更快、更安全、更健壮、更持久。
* G" z$ u% H# \ Z& e }; l& ?以上内容来自巴比特官网介绍
# b0 N- G2 A9 \, hIPFS是基于区块链技术的去中心化存储网络,实现了永久性存储。3 Q6 A7 A: C1 p/ V: Y" y2 f" L
- IPFS的火热5 V( [8 R; _9 W. b5 H# k9 E
Filecoin ICO是迄今为止涉及金额最大的ICO,仅一小时就募集了接近2亿美元,打破ICO记录,成为2017年最火爆的区块链项目。IPFS项目吸引了世界各地数字货币投资者和互联网从业者的密切关注,2018年比较值得期待的是IPFS主网的上线。然而就在前段时间,官方公布说上线时间延期到年底。
1 g: f# |% y0 T8 }; d6 E注:Filecoin是IPFS激励层的加密数字货币(即代币),有点类似于以太坊平台上的以太币。
8 I, ^. o. o1 O7 @IPFS官网:https://ipfs.io/
* i0 ^% ~* F( f! |9 XFilecoin官网:https://filecoin.io/6 ?5 V9 t; e6 S
- IPFS的应用案例
# Y9 r3 h& ?! b/ K( p2 {# j+ l9 YGitHub有两款开源项目,且有对应网址,分别是音乐播放器和视频播放器。
/ T( X) D1 \1 h! }. E& H6 A( Q7 f) i4 }0 n. n6 e
- IPFS音乐播放器
5 ?: L$ C2 D, B3 _) X0 G9 @
) C E( P) g f2 z# W$ d/ y: P. a6 b
. V$ p6 [. m# d0 K
0 z# z& V. R# d7 L/ x* H& t% H
) B9 d% Z3 o; u9 b. k9 D
IPFS音乐播放器
& c( ^8 P9 Q* P4 _1 |
/ J: G" @6 G* V, |IPFS音乐播放器网址:https://diffuse.sh/( v% O8 k* |: M4 P- l/ ?# d5 t7 x
GitHub地址:https://github.com/icidasset/diffuse
$ v5 d T4 O4 ^/ f - IPFS视频在线播放器
/ `1 u4 D3 G% p. Q; Z) \* Z* c. D) `% a; Q5 l% m; D
4 X: A. L& c) G5 o
8 n3 [/ t# r6 R) M$ o' t
/ ~" ?: d0 P/ U! C) tIPFS视频在线播放器首页
1 q5 ^) ?7 s* `1 X/ W+ {* ]0 T3 h4 g7 E
, F! V" K+ H2 S: w
; y. |/ |7 R6 H M$ L* r& ?7 X
3 @, I, a7 S$ R8 N- ^8 B# x
7 w' @& Q) U3 E; v7 e* J3 S
IPFS视频在线播放器播放电影3 s# k- U" h0 A* P/ ^! M% u
9 h/ _8 p% U1 h( M0 u/ C& K
号称是国内第一个IPFS应用
& [# C) g' j4 l) mIPFS视频在线播放器网址:http://www.ipfs.guide/
4 d! _0 l8 p2 [7 J' TGitHub地址:https://github.com/download13/ipfstube
) V6 {9 M- ]" e0 N3 G. N4 @可用于测试的电影视频Hash(这里只列举两部):3 M7 {9 r6 n, d
神秘巨星:QmWBbKvLhVnkryKG6F5YdkcnoVahwD7Qi3CeJeZgM6Tq68# `- B: w- E# B
盗梦空间:QmQATmpxXvSiQgt9c9idz9k3S3gQnh7wYj4DbdMQ9VGyLh3 b N8 u* [" E1 e- X
2、IPFS的安装既然IPFS这么牛,有必要了解一下IPFS的开发,先从IPFS的安装开始。
$ @. h: h Q/ y; k+ g, C- IPFS Desktop( B; _( U3 M4 X+ `4 E7 O. D
当然,可以直接安装IPFS节点桌面管理软件来体验一下。该软件可以方便地运行和管理自己的节点,查看IPFS节点资源信息,支持二次开发。该项目是Node.js编写的,已开源。
N; u. @. [: C9 _$ K
+ z( O$ A5 F! z- Y3 c2 y
5 _, ]; Y, W, @4 { ^7 N
) M* u: _1 h, W# N( f
+ Y, F. k# T* E4 MIPFS节点桌面管理软件$ M( q8 n7 P; o7 ? O
, o* a& V5 s( o- v" N0 Y4 VGitHub地址:
; A* [" A6 R$ E# ^) f8 @8 U# [https://github.com/ipfs-shipyard/ipfs-desktop
1 Z& l. d; D) d7 ?- V - Go-IPFS
5 Q' y# i/ b$ E, L& G/ p& I7 s, ?进入IPFS的官网,找到并切换到"Install"页面,点击"Download IPFS for your platform",会跳转到如下网址(需要翻墙):6 w# a/ f7 _& p/ e' o2 O# ^$ l% K
https://dist.ipfs.io/#go-ipfs3 i: ~( E4 F2 O/ h8 i* v
, H$ C' p* T) O: H0 {- R
; k7 h- v8 K. v: \9 g
# {: |) r" U/ D+ k( r下载Go-IPFS
% g! `3 L+ [* g. M3 w
7 s ]- N( `: ?6 }; S如果打不开,可以试着去Github查看安装方法$ L8 K1 E. w4 ~' j
GitHub地址:https://github.com/ipfs/go-ipfs- q$ m! _' I1 F/ E+ N1 R( i1 m
将网页下载好的文件解压出来,下载的是"go-ipfs_v0.4.13_darwin-amd64.tar.gz",解压出来的是go-ipfs文件夹,+ ?0 y# R8 F3 K l4 k: f9 g$ k& t' J
然后打开终端,进入到go-ipfs文件夹根目录,复制ipfs文件到系统的bin目录,然后可以通过"ipfs version"来检查,操作如下:
: s9 i2 q' G7 n" T4 ~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
$ H2 A- N; u! k 3、IPFS节点的创建、查看和启动以下是安装官网的Go-IPFS步骤下实验的. \6 y/ u9 X/ |7 g7 ~9 c! {* x" U+ L
- 创建节点
2 e$ }+ d9 u. N- v J进入到当前用户的根目录,并使用"ipfs init"命令创建节点,可以用"open ./"打开创建节点生成的".ipfs"目录。
+ T$ Y/ K" p8 m4 z# b ~wenzildeiMac: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 ./
/ z2 ]- I u# B
9 G& P+ E p) v3 T% i4 `: w* `
% H* W/ t: R6 T8 ^# |) c( q# B
! g" O# a; s7 n3 Q; \# @IPFS节点的创建
: \6 a( d/ t9 w. _1 s: k& r+ W2 R! F7 {' Z7 ~
- 查看节点id
/ M8 K9 C7 P6 S& P' q2 s9 P* pwenzildeiMac:.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默认存储空间
; o& G% M, n3 J& p1 S存储节点默认存储大小为10G,如果你想修改存储空间,可以修改config配置文件,找到StorageMax并修改" G! d/ u* |/ w' {
wenzildeiMac:~ wenzil$ export EDITOR=/usr/bin/vimwenzildeiMac:~ wenzil$ ipfs config edit
: ^8 b* x3 g0 D/ t4 Q+ U
$ f2 F; z6 C- T$ G2 r5 s. n1 [+ R9 R Z1 |" H: e7 P: \& ?6 t
修改IPFS默认存储空间1 V) b2 K- |0 {. l$ w# \( N
( ?8 ^' A; N9 U8 x. b
- 启动和同步节点服务器
3 d0 E5 }% t2 ~3 v执行"ipfs daemon"命令,可以同步节点数据到IPFS网络。; ~# Z- p0 l! ^) 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& S) w8 m9 l; n; `. g k9 x @
4、IPFS运行体验- IPFS查看ReadMe
! S- W: B1 P, I* p- J4 X9 _. S5 |9 T可以回去查看执行"ipfs init"命令的时候,返回的内容。打开一个新的终端,操作如下:' X4 [5 M0 `) w1 w
wenzildeiMac:~ 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- |3 E9 u" D+ K0 oIPFS节点服务器启动后,可以用浏览器访问:http://localhost:5001/webui- p, u# X* m& r6 j) F
有本地配置、节点连接、本地节点文件等信息,如图:# M. r9 M9 C: ?
6 |& K" l |5 ^) k
. z. k: B$ n9 ], O5 |& p; q/ b9 e
3 ?$ L3 v2 V' W( z- F& Q% p* F5 `6 B
( ^2 I7 O1 t, N; N, @( D
IPFS的Web管理界面0 Y6 _5 P8 r, ~. m: j/ N$ Z' e
$ Y4 L/ b; Z) m( g: ]! v/ f+ d! h* ?
: f+ W. `( k) c- I: `1 ~) Q% h; z/ o7 Q* F) T7 _3 j1 W
5、设置跨域资源共享当我们在前端通过js接口操作ipfs时,会遇到跨域资源访问问题,可以在终端执行以下配置来解决:! i4 |- _; |: b7 n( e0 |
ipfs 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节点- 新建文件
5 h. n' x2 P" |, c5 y* q& o, xwenzildeiMac:ifps_test wenzil$ vi test.txtwenzildeiMac:ifps_test wenzil$ cat test.txt IPFS测试文件 - 添加文件到IPFS节点
& B0 X: G- O7 x% v u% CwenzildeiMac:ifps_test wenzil$ ipfs add test.txt added QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab test.txt添加文件到IPFS节点后,返回了文件的哈希值
: i- {3 n% L& Y t: J& i - 查看IPFS节点的文件
" _4 h6 o0 F% _; X. W4 TwenzildeiMac:ifps_test wenzil$ ipfs cat QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbIPFS测试文件注意:此时的文件只是添加到了本地的IPFS节点,读取的是本地数据,可以通过如下网址查看。+ T5 U0 y( h0 x* K6 Y8 h4 b( m
http://localhost:8080/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab, N% o& C; @* e- \
通过"ipfs daemon"命令启动节点服务器,会将本地节点文件同步到外网,同步成功后,这时就可以访问如下网址来查看(如果访问失败,试着翻墙看看)。
6 @4 X9 j2 q/ {+ z9 thttps://ipfs.io/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab1 g2 N8 b/ c& V
4 W0 E+ q: ]6 D2 r; V# @+ o
& u' Y4 E8 g. R' B C" T
* o5 b8 W: P: H
查看IPFS文件内容
! u4 Y# }9 p0 W# C2 c8 ?. Q6 M
! `0 O" h! f( Q如果访问成功的话,说明已经存储到IPFS网络中。目前IPFS网络暂未加入代币Filecoin机制,所以存储读取文件免费,速度也比较慢。
: M' V" O" }# q* n8 B' _ - 下载IPFS节点的文件
4 `! b+ W, q5 p5 X6 J1 BwenzildeiMac:ifps_test wenzil$ ipfs get QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbSaving file(s) to QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab 25 B / 25 B [========================================================] 100.00% 0s查看当前目录,发现多了一个"QmSV..."的文件"
( I* c! \: \' k
+ u9 @+ R& J0 {7 P, T
9 y4 q- H; d) b( ~) |, m! V9 `- P* @
/ ^0 Q7 i* d& r- S( L! F: d2 F4 q r" e" T
下载IPFS节点的文件# n& ]/ [2 h% |; @ P1 X
% Y& l" V' K, o3 s, t! S5 T
9 C& Y, ?* R* k8 [! F
6.2 创建文件夹存储文件- ipfs命令新建文件夹: K' D* j$ r/ v( V l
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 /文件夹名"可以删除文件夹。3 {' o6 n# u+ P/ i
v! {- w( Z! h, I1 A" [& m5 |
6.3 IPFS上传文件夹- ipfs命令添加文件夹
# T7 w+ I1 g" A2 z$ \- X3 @先在本地创建一个文件夹和对应文件,如图:
0 o1 q, |! V: k, c: e8 m" I
/ z/ J7 G$ B8 Z' j3 Q% P$ F q2 n/ n" ?1 A2 i
( P) q5 @( Q+ h7 h* p" p( a+ ]4 t6 |; h9 x6 Z) G
本地创建文件夹及文件 X: I2 ?, E% K) X/ S/ [
( U% e q' b2 I4 o( D
然后通过"ipfs add -r 文件夹"命令添加整个文件夹
( T4 x8 r" C: f1 y9 z7 F. a# Z 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$ - 查看文件夹的文件内容) ]! }3 R: X9 z @3 H/ t1 T
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对应文件夹1 o6 x" q; A8 P- }
访问文件夹对应的IPFS地址:0 J/ B7 f* _, k1 i& j- t
https://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj8 k2 d8 Z8 {# L" A& F
第一次访问的时候,需要同步数据到IPFS网络,等待时间有点久,慢到让你以为同步失败了。
5 U! _4 R. F+ l" b$ N3 R* B% F
D4 C! r1 j8 K4 t, I) O0 T
- P' A. U- _4 w. N( P! V2 t$ Z/ D# t$ K
查看IPFS对应文件夹1 z. ^4 D6 O2 Y( O7 i0 V- @
8 l1 X% N2 H5 H
访问文件夹对应的文件,如看到图片文件,访问ipfs网关:
4 q2 \( q! H1 b1 H6 A# khttps://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj/portrait.jpeg, ~9 C2 p6 {# a& A8 N
1 P2 C; U, B! v: [
/ V8 ^% E3 M' k, P* Z1 K1 o, e" Z) U M- h5 M+ E
查看IPFS文件夹对应文件/ h/ X9 E* u' X, Z; m+ f
7 x& S0 t: ~4 N" _- ]% [或者通过文件的Hash来访问,如访问txt文件的地址:
4 u- ?$ T6 |0 h( x3 H4 [7 q+ j* \https://ipfs.io/ipfs/QmPEWgwQEHD6qxm5cUivTEZ252T123DvQ5L6HyUDgViQvT0 f2 [/ B* ]/ N; o
5 K% N- Y# u' o0 O4 Z
" Y9 q. S5 }! \
2 ]' _5 S/ D, F: Z* L( w2 V2 a4 {
通过文件Hash访问查看
( d2 |+ q# t' h. ^. S* K7 _
( P' c) R ^* I" w6 T" g- q& B( f- \' B. a5 Y9 b: }
6.4 添加简单网页到IPFS节点- 网页效果和项目结构
* ]! U1 F& ]) f! ~$ o实现一个简单的实时显示系统当前时间的网页,效果如图:' F& y0 x7 Q0 C8 m5 M
, V6 D9 y1 I+ X/ S* G8 n
, S$ u2 v2 c9 n Y4 w7 _( U
. o9 o2 \! ^, s2 e0 Y' \& B
! @ G1 l8 R& L0 ?1 VIPFS添加简单网页
6 ^' C4 d N3 G: M) j$ |3 B ?
$ r, m. x |1 N" }' |- D7 Q' O工程结构如图:& S, ~) \7 W8 d7 A0 Z
* |5 |) `# J( S6 o9 G+ g( J5 B
$ r) m! t: D1 R+ m0 ^" W) o
' r' r- K F' V7 F6 P/ }+ O2 G3 O
. @+ M. }5 o( F# A/ d1 G网页工程结构
4 x) ?( J/ P7 R9 E4 R
! p' x V* Z. K
; B- W3 ?% k0 D! }, i 实现代码比较简单,这里就不贴代码了。2 `7 C) K3 n# X
- ipfs命令添加文件夹5 E2 ^6 U4 z) ?! r3 N' M
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"命令在新的终端窗口打开运行。
& V; P9 e+ r/ R6 f) LwenzildeiMac:~ 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对应文件
% P+ l6 x7 y9 ]' l6 U6 O$ |浏览器访问ipfs网关:5 x, m, L/ f. j9 _8 o) K4 X( j
https://ipfs.io/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD/
9 Q+ `- f/ F- J& T3 N1 A [) M G6 D; G$ a x1 C
8 Q' X2 {% |: \" S& o$ Z6 ^. [2 L6 v5 J
查看IPFS对应网页
" `" V% M9 j0 m2 b( L" q& k- ~+ q8 \# U
. \- i3 Q7 H+ o: N4 q0 P0 m
6.5 IPNS绑定节点名- IPNS绑定节点操作
, p7 ~) H& t8 r+ |+ Z$ a6 O& ]每次修改文件内容后,文件的哈希值就会发生变化。对于网站而言,发布后可能还需要做修改,这时需要IPNS绑定节点名。每次更新网站内容后,重新publish一次更新发布到IPNS即可。
4 k q; K: u( [) c- ^( I刚才的html根目录的哈希值是QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD,操作如下:4 n+ k8 t/ q6 \3 ?9 l( B
wenzildeiMac:study wenzil$ ipfs name publish QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDDPublished to QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz: /ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 查看当前节点8 O* X7 {( O3 B- i8 m- k( t
wenzildeiMac: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": ?- M" Z3 R2 N
- 验证节点
8 ?! w* e+ C4 d命令为:"ipfs name resolve 节点ID“
& A. i6 H2 L- X! K; kwenzildeiMac:study wenzil$ ipfs name resolve QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 访问IPNS对应文件& W( p- Y8 ^2 s( F% f) y
浏览器访问ipfs网关:: W$ |/ ~& J! V* u. J0 X9 e% j
https://ipfs.io/ipns/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/; \# @: K0 f9 Z r" J7 z
& c; m3 U( _+ ^; \. j5 @: W, r
' }0 I0 E- }) _, T1 l1 s& c
9 ?( W/ U& | ^! p! Y ^
4 O4 i, f; v; o8 d, S* |) H; V, T0 g查看IPNS对应网页
# \9 k" x5 v$ D
( ]' ~4 H1 v8 G" o7、IPFS与以太坊DApp开发实战- IPFS与以太坊DApp结合的好处$ e* _6 D' L% y/ Y8 J
在以太坊平台上,往区块链写入数据需要花费以太币,调用智能合约执行每一行代码的时候,都需要一定量的gas交易费。区块链存储大数据成本很高,而且不合理。" z9 b/ Q1 {1 B% _( `. G; }1 V
可以先将文件存储到IPFS,然后得到文件的Hash存储到以太坊区块链中。读取文件的时候,从以太坊区块链中获取文件的Hash,再通过Hash来读取IPFS网络上的文件。
, O- `: q ?- B$ @6 Y使用官方提供的ipfs-api,可以很方便地在代码中操作节点将数据上传到IPFS,或者通过Hash从IPFS读取数据。
7 t6 [) w( W4 ETruffle框架提供了快速搭建包含以太坊智能合约的React项目,可以通过"truffle unbox react"创建工程,然后安装ipfs-api依赖库。于是,可以在前端方便地调用IPFS的接口来读取、上传文件。
- o0 }4 ]1 l8 J, P+ S( etruffle unbox react官网:
0 k! X& @& Z! H9 mhttp://truffleframework.com/boxes/react
& I- a+ r( j0 D, s2 _ - IPFS与DApp开发实战6 g2 h$ U- P s$ u2 [
话不多说,开始进入实战开发。
2 c2 j- O' `0 R% F7.1 安装Truffle unbox react新建一个空目录"ipfs_dapp",然后执行安装命令
[) P1 {" K- f, Etruffle 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",修改后完整代码:1 E4 t9 e& R, V; z9 Q B6 Y
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"0 L1 _6 Y) i- M* c
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"进行智能合约的部署' b% V! U3 [: F" ?& t+ K. ?0 Z, `
! Z" ?- @ Z0 q2 W1 M+ N
! c& h7 u/ U5 w+ O4 \# E& H2 l. B! B& x' p( @8 _3 b- E
Remix-IDE部署智能合约
" A9 U2 H1 {6 M" {2 A# p+ c ^8 G- x( S2 K4 p9 |6 N6 v+ Q: B
4 h) f- g! `/ t9 d
l$ I4 f7 [; `* s% \7 e
* ]; H" ?$ w4 t- I) }1 O6 E
Remix-IDE部署智能合约-确认
7 ^- I, H: ^7 ~( r+ t3 @# c- W5 h
4 ?& U; ?! |6 f; J$ ]- `) b然后复制智能合约地址,App.js文件中会用到合约地址为:"0xb177d6cf6916f128c9931e610c63208d9c5a40f3"
( V' o( a' b) W7.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"命令,结果如图:
( w' s: Y: s8 l( h
3 b" d( p% _8 {: `$ ]1 \7 M) w7 P
7 i3 _! c4 M' m1 znpm_start
" x7 [8 j4 m; G" {1 ]7 a6 m9 N& g$ Y" q; N
会自动打开网页,然后上传一张本地图片,之后点击"图片哈希写入区块链"按钮
$ t) a( C. j' F9 ^$ ?5 t) V% T% d+ n1 ]
& g6 s& `; T2 g% j7 [8 p# u; j7 K+ t* c" A1 V- f& e
运行结果1
; l+ H2 m( [* m7 x! C& f' B; [8 i/ k1 u- W: ]7 U
最终效果如图:
& u+ h2 a1 R' G
" _$ R+ @, ]2 }& ?/ }
) q' o; |" o( ?3 v1 q6 z
5 s: D0 R8 _) R2 |
& r/ @- D! V6 X4 }# b+ Z+ j" n
运行结果
. k5 f1 Y+ x! R2 l' O
# ~# o( n0 m0 `" B访问IPFS网关:: P5 _# P# _2 ?
https://ipfs.io/ipfs/QmbHptfJfyuGAZxstFYgAVfz33cytR1seTD3ZabBSDd899
( {8 R2 H) p* L+ z/ A发现图片已经成功写入IPFS,如图:
0 M- |- w4 `4 a o. |
1 z" O t( U: Z$ l* R+ Q0 H6 y, J, R- J: N* Z8 b5 W$ S( ~
& d; T- |9 T. h) J7 \) B7 N! Y; F+ C$ O- Q1 g" S
运行结果3
% D R, E; Z4 m( W
3 S8 D _% c8 [ }备注:本地IPFS网关端口默认为8080,我的电脑上端口冲突了,系统自动修改为8082。
+ K% v& @# M6 ]$ R搞定,收工。& f! q6 j5 r1 K/ Z0 }& ^
PS:刚入坑的小白,很多不懂,还请各位大佬多赐教,谢谢!- _9 R! o$ ~+ h. P8 T+ N
" O! I7 u6 i& L4 R. }" n9 }
|
|