|
|
本帖最后由 赤膊医数 于 2021-4-22 23:41 编辑 & H" v G: I; t% s' G8 ?
2 s y$ A+ c8 p2018年,最火爆且值得期待的区块链项目莫过于EOS和IPFS。1、IPFS简介- IPFS是什么! X, V/ q! |3 ~1 {. S6 U Z
星际文件系统IPFS(InterPlanetary File System)是一个面向全球的、点对点的分布式版本文件系统,目标是为了补充(甚至是取代)目前统治互联网的超文本传输协议(HTTP),将所有具有相同文件系统的计算设备连接在一起。原理用基于内容的地址替代基于域名的地址,也就是用户寻找的不是某个地址而是储存在某个地方的内容,不需要验证发送者的身份,而只需要验证内容的哈希,通过这样可以让网页的速度更快、更安全、更健壮、更持久。; F% A# T. @/ L A8 B4 X: D: U' c
以上内容来自巴比特官网介绍8 _2 z% h+ r" j+ J" K
IPFS是基于区块链技术的去中心化存储网络,实现了永久性存储。
( N! w: a* L* |2 P4 C' \ - IPFS的火热
: _8 t2 p M' I: }Filecoin ICO是迄今为止涉及金额最大的ICO,仅一小时就募集了接近2亿美元,打破ICO记录,成为2017年最火爆的区块链项目。IPFS项目吸引了世界各地数字货币投资者和互联网从业者的密切关注,2018年比较值得期待的是IPFS主网的上线。然而就在前段时间,官方公布说上线时间延期到年底。: ^2 Z9 u5 D$ \
注:Filecoin是IPFS激励层的加密数字货币(即代币),有点类似于以太坊平台上的以太币。
9 i% M; B9 r# u/ z) F8 A- } P9 KIPFS官网:https://ipfs.io/
9 r, Y- M3 {5 F& `; KFilecoin官网:https://filecoin.io/ K. d4 Z* H. |4 W3 J- Y. Z
- IPFS的应用案例
, G: W( }5 F) u( m5 h5 VGitHub有两款开源项目,且有对应网址,分别是音乐播放器和视频播放器。
`1 q5 \4 b% l! \+ L) P) ^( j, b7 h$ l) H
- IPFS音乐播放器/ z+ _2 Z8 @( y# U A; ?
' C0 a: E! v' l% @
0 h2 k% }# ?+ o5 {! ?
7 J5 r' S9 o* o( ^' v4 H
, _, k6 Z' w8 QIPFS音乐播放器
, F1 N+ W! j- z, \" e5 j
& P$ t$ H( u4 {; }! r* ?: kIPFS音乐播放器网址:https://diffuse.sh/
a/ j6 n% U9 f' p2 n! eGitHub地址:https://github.com/icidasset/diffuse4 Z t7 V7 I( I# h5 @+ Z
- IPFS视频在线播放器& J% I; }3 P1 z d7 \% H
( r, P k3 x5 q( O0 N
& X+ j3 Q- Z9 X; X- q% b5 F4 |' O* {
2 c$ n+ O( ?3 r' V9 s. |0 V0 W/ ~) R
IPFS视频在线播放器首页" U1 V3 U( A9 C) Q) h* N
+ Z. s6 V- p" x4 c# V, b2 s" o
4 t( `9 e9 b1 W9 X# l * E5 S* \% ^2 c0 W
: w% j# m8 X" G5 t
1 ?, \( N- l' }IPFS视频在线播放器播放电影
8 T# z) Y3 C; c2 Z2 m! k. X
6 U" n* Q; L- ]* m, F6 j& d号称是国内第一个IPFS应用" N" i7 ]" M) ^3 F# j L/ ~6 s
IPFS视频在线播放器网址:http://www.ipfs.guide/: X6 g* x* Q8 h+ F h
GitHub地址:https://github.com/download13/ipfstube
6 p6 D! Y2 L+ ]/ d2 P x% S& G! n可用于测试的电影视频Hash(这里只列举两部):& |8 @" X2 @ f% |5 K s0 c
神秘巨星:QmWBbKvLhVnkryKG6F5YdkcnoVahwD7Qi3CeJeZgM6Tq68% Z# O0 A) K( L. P1 h7 y1 w$ G
盗梦空间:QmQATmpxXvSiQgt9c9idz9k3S3gQnh7wYj4DbdMQ9VGyLh
8 j: C( A6 [1 k, v( y2 X 2、IPFS的安装既然IPFS这么牛,有必要了解一下IPFS的开发,先从IPFS的安装开始。 d8 I# d5 @- a& j2 I \: ~
- IPFS Desktop2 e9 ]7 q8 V/ V7 U/ J6 B+ ^, F0 O
当然,可以直接安装IPFS节点桌面管理软件来体验一下。该软件可以方便地运行和管理自己的节点,查看IPFS节点资源信息,支持二次开发。该项目是Node.js编写的,已开源。/ V6 M9 `$ T! `/ @3 H
8 K# b, K8 }4 I: l
+ _$ e( i9 X7 I7 U! m: I7 _; l! \3 G
" E! B5 A# f, b% K7 B' i2 _0 C r3 P
IPFS节点桌面管理软件" U' W; T6 E0 E$ K X
( j% r. a: G' P# G
GitHub地址:
6 q* L) W4 g5 P/ |/ q* J1 A1 xhttps://github.com/ipfs-shipyard/ipfs-desktop
$ Q) w0 G+ Q: r0 ~$ K$ `" f; ? - Go-IPFS8 B6 O1 c" d$ S9 V& I
进入IPFS的官网,找到并切换到"Install"页面,点击"Download IPFS for your platform",会跳转到如下网址(需要翻墙):% N8 a4 l Q+ Y7 G& @
https://dist.ipfs.io/#go-ipfs0 I m! ]* l; G: Y- F+ |7 P5 c
- O6 I8 S& b1 R. _
0 ?0 s5 A0 | |) n2 ]
& X# G3 o% K+ `6 G4 S下载Go-IPFS
3 l% J y0 |+ O+ M7 o, z* J* R0 z# j& S- ~3 c' k3 o/ M* W
如果打不开,可以试着去Github查看安装方法
6 z7 q3 L+ y5 _+ nGitHub地址:https://github.com/ipfs/go-ipfs
4 [- n$ U, H$ ]$ R- e5 q将网页下载好的文件解压出来,下载的是"go-ipfs_v0.4.13_darwin-amd64.tar.gz",解压出来的是go-ipfs文件夹,
& M& p/ A" l9 I然后打开终端,进入到go-ipfs文件夹根目录,复制ipfs文件到系统的bin目录,然后可以通过"ipfs version"来检查,操作如下:
3 n% m+ C0 n6 D& C4 a DwenzildeiMac: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
- U: D# |: \0 j1 b+ K7 J 3、IPFS节点的创建、查看和启动以下是安装官网的Go-IPFS步骤下实验的5 F6 ]1 I* D' G. c. ]
- 创建节点) @- H0 M' A0 u N3 `& F
进入到当前用户的根目录,并使用"ipfs init"命令创建节点,可以用"open ./"打开创建节点生成的".ipfs"目录。
! j& s4 a* o n2 m' T0 q8 zwenzildeiMac: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 ./, S3 m$ ~1 W l, Y) x" Z
7 A& p% ^4 e! c* _' d# Y: D' g5 w
3 a; |6 j! n& R2 d7 E8 Q) [: v
2 G5 W, B7 u$ ?9 Z; FIPFS节点的创建
5 T! i: x5 C, v5 Q0 E! F+ m! h$ |2 ]! V3 [4 u5 }
- 查看节点id9 B. y- n- m3 V5 t; B Z
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默认存储空间
; ~: [. }3 {+ k/ A( b7 F& q; A, t存储节点默认存储大小为10G,如果你想修改存储空间,可以修改config配置文件,找到StorageMax并修改. ~9 R6 C, x1 s# j# z4 D
wenzildeiMac:~ wenzil$ export EDITOR=/usr/bin/vimwenzildeiMac:~ wenzil$ ipfs config edit $ g: `+ g: J7 T/ }. q
; M7 \" a3 a. P u7 e' t
1 P s3 t* e$ Q. j修改IPFS默认存储空间! I9 G( y0 {' D% O7 J/ d
7 S( G2 c/ v& K. w9 y/ E
- 启动和同步节点服务器: ]$ b0 L! f( M
执行"ipfs daemon"命令,可以同步节点数据到IPFS网络。7 y' i, K) N n3 J; v
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
5 ~1 C6 _3 D3 w* I3 T# O' e1 p 4、IPFS运行体验- IPFS查看ReadMe
+ @1 \" c f+ }/ p( u7 v可以回去查看执行"ipfs init"命令的时候,返回的内容。打开一个新的终端,操作如下:% B; ]% I; C9 W2 a0 ?4 u+ \
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管理界面
; U5 N9 J2 w, ? zIPFS节点服务器启动后,可以用浏览器访问:http://localhost:5001/webui, T5 r* j5 \. S
有本地配置、节点连接、本地节点文件等信息,如图:
7 ~* |& V. U; j3 [# N/ M' y! ~2 e0 r; p' T Z8 d6 L0 S
b1 w' N; D) h; ?2 }9 W
2 o- Y( c. g1 }/ Y5 t/ D" ^% c
% \+ I# X( g y4 @# E+ ~
IPFS的Web管理界面# ^) z, r& G, ? h+ K# A
5 \" G3 U- |. e: j5 s, A
5 [; P' p' M" D8 C c
) o4 ?) s1 l& Q: x( c1 @ 5、设置跨域资源共享当我们在前端通过js接口操作ipfs时,会遇到跨域资源访问问题,可以在终端执行以下配置来解决:( M S0 ~: ]$ ]
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节点- 新建文件- f! ^. ` _- u
wenzildeiMac:ifps_test wenzil$ vi test.txtwenzildeiMac:ifps_test wenzil$ cat test.txt IPFS测试文件 - 添加文件到IPFS节点3 D6 M. B. x- X% ?* y
wenzildeiMac:ifps_test wenzil$ ipfs add test.txt added QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab test.txt添加文件到IPFS节点后,返回了文件的哈希值
$ \; g1 M2 w. M, k4 n# e5 R& k7 W - 查看IPFS节点的文件
/ g/ u( ?4 j* D/ G5 _0 l+ jwenzildeiMac:ifps_test wenzil$ ipfs cat QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbIPFS测试文件注意:此时的文件只是添加到了本地的IPFS节点,读取的是本地数据,可以通过如下网址查看。
4 G/ U7 n# P+ j) \, Y* Q; vhttp://localhost:8080/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab. g4 a5 [( m* V/ U$ d
通过"ipfs daemon"命令启动节点服务器,会将本地节点文件同步到外网,同步成功后,这时就可以访问如下网址来查看(如果访问失败,试着翻墙看看)。6 C, I! |/ i+ G) K+ D- ^
https://ipfs.io/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab
5 \5 J5 m/ O) ]% p2 a: e$ G/ J) w7 O6 v% J" X
1 b! M" D7 A B/ C' g
N, j0 _# o; \" X K6 \! x- i查看IPFS文件内容 ]* f7 p Z4 C c9 m
6 ~$ o/ i+ J( t4 ^% m
如果访问成功的话,说明已经存储到IPFS网络中。目前IPFS网络暂未加入代币Filecoin机制,所以存储读取文件免费,速度也比较慢。# J( K+ H6 T8 n, S
- 下载IPFS节点的文件
, M7 |: K1 M k& OwenzildeiMac:ifps_test wenzil$ ipfs get QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbSaving file(s) to QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab 25 B / 25 B [========================================================] 100.00% 0s查看当前目录,发现多了一个"QmSV..."的文件"& S5 T% \2 X: R$ }) T0 y4 ]2 _
( B" x. c7 n( E" k
r5 e) s) ^' `
& `2 L: I5 t8 H6 {7 K% V# ~+ x; |5 h1 D1 e% p. p9 B
下载IPFS节点的文件
6 }" j* v) @6 j) c/ i
* K' e7 N. \% G; m3 O' _: Y5 Q7 I1 I$ ~# B/ C
6.2 创建文件夹存储文件- ipfs命令新建文件夹
7 A" ^ q5 k, F/ lwenzildeiMac: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 /文件夹名"可以删除文件夹。9 `2 @$ y$ u& [4 ~; D! Q S
; x# T* Q& Y# a8 p4 x
6.3 IPFS上传文件夹- ipfs命令添加文件夹
+ R% Y( x" y1 z( D/ r' C先在本地创建一个文件夹和对应文件,如图:
' ]1 U4 {# k2 J( L; ^/ O* \) b' I! c7 m# r ^' M1 |
& N+ }+ y0 e! N% d+ ~7 _5 o8 Y
0 h; S. P0 ?& q! A7 n0 f- @
2 _6 N# e& l$ k& h; X G$ ?本地创建文件夹及文件
5 }+ q1 R% y4 D1 w$ Z! _" G0 @4 Z3 x; g
: @; o* h& _7 T& N( X7 K1 `然后通过"ipfs add -r 文件夹"命令添加整个文件夹. z. @# H. N* F" ]& W1 a8 k. d8 Z. 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$ - 查看文件夹的文件内容
; R/ o5 K: F+ F: z3 y9 SwenzildeiMac: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对应文件夹$ J: |, ^% |/ N0 \
访问文件夹对应的IPFS地址:* A. _- R+ S% [2 S6 L, j' M
https://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj
. n9 b0 B/ b. o3 z6 {第一次访问的时候,需要同步数据到IPFS网络,等待时间有点久,慢到让你以为同步失败了。# C z) {- m. P
! n* Z7 f: z* X
$ E/ h$ ]6 S6 e( h9 }$ W& S# z1 b l [# x" v2 a I5 c
查看IPFS对应文件夹
" b! e- S2 T0 e `: U
/ C" p/ W% Q2 R3 l5 }, U8 P访问文件夹对应的文件,如看到图片文件,访问ipfs网关:
- t V+ U3 t: ]/ p4 Xhttps://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj/portrait.jpeg: t" W8 T* t1 f, R6 X
. L. }% n- N/ n9 d
6 G$ u S9 X! O( s$ y! h8 b
# w4 g+ u) s% A' @" L* o1 B查看IPFS文件夹对应文件
' `0 A7 J% j7 e# ?# @- p5 R& Y& K/ a& r8 E1 X- x5 g
或者通过文件的Hash来访问,如访问txt文件的地址:
& l6 R& d% h" R% s) Y4 \5 x& ihttps://ipfs.io/ipfs/QmPEWgwQEHD6qxm5cUivTEZ252T123DvQ5L6HyUDgViQvT
. Q5 U& H, @+ T+ e8 e
9 ~ h. \# B& q6 t) d
7 P( T& m7 O) v- c5 M- |1 D9 Q9 P) P2 e* v9 [
通过文件Hash访问查看9 @0 t8 H I1 h( X0 K7 j% c
, V1 p# ?& B! C# w( x
1 u7 t# U C) m C 6.4 添加简单网页到IPFS节点- 网页效果和项目结构; m$ |% O& ]9 [# L
实现一个简单的实时显示系统当前时间的网页,效果如图:
% Q& K* B9 }9 }! O$ v/ u" B" U& D
, W) K7 ]3 L( G) `: ^+ h6 z
/ x! ` L O1 U5 n
* Y3 H/ f' ?# U: Z7 e3 G& T/ l3 @
IPFS添加简单网页
: V5 Q( Z0 F% |& j: R9 L) O) c7 b. A, }7 _
工程结构如图:6 P# U! z8 S) {7 U
! U& f O6 J# {. F9 _% L' y' a3 t: b6 z
* B w; ?, h* V; m2 h4 C8 d! [# ~! b- l, B0 z* l
网页工程结构
# g4 d( J( ]3 N! I
; j- |2 h$ g' ~/ x! U/ k
) O! k6 _: q% z9 R+ s 实现代码比较简单,这里就不贴代码了。
' {) r2 U+ _8 t- ipfs命令添加文件夹" A! P- _7 S b 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"命令在新的终端窗口打开运行。
) J8 \2 {4 z/ q: v2 f% g" CwenzildeiMac:~ 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对应文件
7 U/ u) J, [6 }" w2 E. A浏览器访问ipfs网关:! `& _4 n# I( c8 X
https://ipfs.io/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD// j" R4 v2 ^5 {
) z- f2 u3 R9 t% B$ |1 A( }9 N+ E
3 p& L0 w. n8 s6 A! l1 J$ m* b2 |' L3 E& ?! L) u E; m: U
查看IPFS对应网页* g: W' S# @# [8 |. x( R
6 A$ T! B' c; V$ M7 n7 _' M; W" [6 B, [# _2 O8 x3 }' r0 c! P5 ^
6.5 IPNS绑定节点名- IPNS绑定节点操作9 R; w4 D" V9 q( e r q: }& v
每次修改文件内容后,文件的哈希值就会发生变化。对于网站而言,发布后可能还需要做修改,这时需要IPNS绑定节点名。每次更新网站内容后,重新publish一次更新发布到IPNS即可。8 z7 B1 q5 k d' z- h
刚才的html根目录的哈希值是QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD,操作如下:
9 @# k5 L3 y/ [( N4 q$ dwenzildeiMac:study wenzil$ ipfs name publish QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDDPublished to QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz: /ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 查看当前节点
8 k1 J$ s0 U2 D# |* jwenzildeiMac: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"
' u, u7 G q% _ - 验证节点
0 y9 O. j2 G$ q# u4 \* p命令为:"ipfs name resolve 节点ID“
0 ?" q Y2 u" j6 C- f! @wenzildeiMac:study wenzil$ ipfs name resolve QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 访问IPNS对应文件
. x& t' ^" F9 N( K* r浏览器访问ipfs网关:
+ R/ P$ v# U; S1 c9 j) `https://ipfs.io/ipns/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/, i3 f: z# Z6 G. M" V# r6 r
( k8 N$ X" f0 h$ ?; `9 V. x
0 X: u+ N1 ~& T Q" A3 B
6 V, L9 x$ X) X$ M% ~; C
: N8 d/ O, U- ^: r
查看IPNS对应网页
, \. X4 n6 ^8 W
j0 w% T# X2 {9 K8 m7 ~5 D7、IPFS与以太坊DApp开发实战- IPFS与以太坊DApp结合的好处& c3 t w1 C0 v
在以太坊平台上,往区块链写入数据需要花费以太币,调用智能合约执行每一行代码的时候,都需要一定量的gas交易费。区块链存储大数据成本很高,而且不合理。
+ v, _) g* Q5 f! w5 u# \) }可以先将文件存储到IPFS,然后得到文件的Hash存储到以太坊区块链中。读取文件的时候,从以太坊区块链中获取文件的Hash,再通过Hash来读取IPFS网络上的文件。
d0 ?4 }8 }1 Z# I使用官方提供的ipfs-api,可以很方便地在代码中操作节点将数据上传到IPFS,或者通过Hash从IPFS读取数据。# ]" \0 R' {& Z' T: i& m2 S: Q$ I
Truffle框架提供了快速搭建包含以太坊智能合约的React项目,可以通过"truffle unbox react"创建工程,然后安装ipfs-api依赖库。于是,可以在前端方便地调用IPFS的接口来读取、上传文件。3 d5 j0 S1 e) m2 t7 U9 Q
truffle unbox react官网:
6 i T/ x, H" s! w2 Ahttp://truffleframework.com/boxes/react
% s% T/ a+ c* q n - IPFS与DApp开发实战
! h' u' ?! Q- S8 P+ W9 t话不多说,开始进入实战开发。
2 i* v# e0 Z6 [! S( X! t7.1 安装Truffle unbox react新建一个空目录"ipfs_dapp",然后执行安装命令
5 y6 j6 |. e& f) ?' ltruffle 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",修改后完整代码:
+ s. I4 S9 g# r2 Y- t7 Bpragma 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"
/ g# I; B. y q/ }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"进行智能合约的部署+ i. g7 }1 Y: q' e2 x# k
/ c7 ~4 q: A& H( V$ ~
; y+ G9 N7 `- u* K
) y2 r3 i d0 j7 P* F: E% l$ r
Remix-IDE部署智能合约7 N+ a6 M- M+ T) K" Q
[/ r r2 j8 b: V8 _$ A2 f! ], o+ a) m v+ @9 H9 k- o( C9 X! g: H
) T. V+ Z ~( c, \
- n9 h q- k) V0 B
Remix-IDE部署智能合约-确认
2 E# H. b2 x$ J* ~. j- ~6 o# Q o" Y/ E& p5 ]1 ^" Q$ ~
然后复制智能合约地址,App.js文件中会用到合约地址为:"0xb177d6cf6916f128c9931e610c63208d9c5a40f3"
3 Y$ }+ w9 `9 _' T7.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"命令,结果如图:
. F2 Y0 B, p, I# ?7 I8 U
) S9 Z6 H9 v% A3 j0 |
0 t1 V2 }8 C8 B5 Vnpm_start2 z5 L" e: C) m- }$ o5 t
5 v0 b2 w3 U. `4 C/ D9 z会自动打开网页,然后上传一张本地图片,之后点击"图片哈希写入区块链"按钮
" _7 d& F- V* V( \6 x4 \; F3 g$ _
: }0 M# s1 ^' [* T5 G- u2 Q
+ {, h0 a" m- C( i+ o+ Y! M5 I
运行结果1, f4 c7 V" R5 \0 Q% M
5 q2 g$ X; p/ i0 L0 Y: f最终效果如图:
$ U, a3 ?$ a0 F7 ~/ f/ l3 x7 ~) Y5 i% c, X1 k$ E
( r" ]: M) h/ y7 t2 T. _3 k
! `4 f2 X. K, g
* V, f7 n0 u( V. Z% t' }' M6 O运行结果( W- _- \7 f8 r# ?2 x! k
; m3 [2 Q* N. ?+ ~
访问IPFS网关:, ]4 k5 y5 j# D. F* o( A. L$ ~# c
https://ipfs.io/ipfs/QmbHptfJfyuGAZxstFYgAVfz33cytR1seTD3ZabBSDd899
. U+ h' D$ R6 J# x% N, a: p发现图片已经成功写入IPFS,如图:' A8 z. h4 Q$ g
3 w# d! } }1 |3 O! Z, Z
% S$ N' A4 ?. n z$ L, V
# k" y( k; n5 M }7 ^! {
! p; g$ g( x1 q运行结果3, e) W+ q9 b1 g
9 j9 v1 b' \8 @+ P. b! b备注:本地IPFS网关端口默认为8080,我的电脑上端口冲突了,系统自动修改为8082。3 g" n- M: @5 {9 J
搞定,收工。5 u- e4 }# L. v; o/ Q# s9 ~
PS:刚入坑的小白,很多不懂,还请各位大佬多赐教,谢谢!
+ ]6 g; U1 t8 `/ E- c3 \' s- Q5 S8 M+ K/ M4 B: P; j: C% V6 ?
|
|