|
|
本帖最后由 赤膊医数 于 2021-4-22 23:41 编辑 / u! g, z( D8 U2 i4 A/ x' f% S& T; {
2 f& ?6 Z5 |& ~" c: {+ p
2018年,最火爆且值得期待的区块链项目莫过于EOS和IPFS。1、IPFS简介- IPFS是什么* [8 s) X) h: g! ]- O, s1 a
星际文件系统IPFS(InterPlanetary File System)是一个面向全球的、点对点的分布式版本文件系统,目标是为了补充(甚至是取代)目前统治互联网的超文本传输协议(HTTP),将所有具有相同文件系统的计算设备连接在一起。原理用基于内容的地址替代基于域名的地址,也就是用户寻找的不是某个地址而是储存在某个地方的内容,不需要验证发送者的身份,而只需要验证内容的哈希,通过这样可以让网页的速度更快、更安全、更健壮、更持久。# V) L; V& m$ }) q
以上内容来自巴比特官网介绍
$ ~/ U# Z. _6 g5 o$ D3 _+ `IPFS是基于区块链技术的去中心化存储网络,实现了永久性存储。# H4 B0 T4 W6 \) Z4 e( s
- IPFS的火热1 P9 e& \: s+ I7 L1 w1 L. z
Filecoin ICO是迄今为止涉及金额最大的ICO,仅一小时就募集了接近2亿美元,打破ICO记录,成为2017年最火爆的区块链项目。IPFS项目吸引了世界各地数字货币投资者和互联网从业者的密切关注,2018年比较值得期待的是IPFS主网的上线。然而就在前段时间,官方公布说上线时间延期到年底。6 t0 o: q2 D! t5 O) `
注:Filecoin是IPFS激励层的加密数字货币(即代币),有点类似于以太坊平台上的以太币。
2 M& `( C$ _/ e+ L' JIPFS官网:https://ipfs.io/
l( y5 l8 a# k5 X! W. X1 \5 nFilecoin官网:https://filecoin.io/
- u* G V% X" F+ W/ [4 z: u - IPFS的应用案例3 P( F! j' K( c$ ^& G' g6 J
GitHub有两款开源项目,且有对应网址,分别是音乐播放器和视频播放器。- C; c7 e- B) }" h; w" s
/ {: E9 d2 h1 _; }' n- IPFS音乐播放器
" w# d* |% }8 b3 o; N
A9 w( [5 \ H D9 w, |" k% S- k# ?( ~- e' J5 b4 O: `
) J1 b, ?" J7 ~1 J+ _9 i" }
7 v9 i% I+ [7 }8 B
IPFS音乐播放器
/ `& |0 ^. @4 }0 }3 g- }$ Z( ~3 M! K. [( N' U$ g
IPFS音乐播放器网址:https://diffuse.sh/
; g; Y; L; d# z0 ~' s$ [GitHub地址:https://github.com/icidasset/diffuse
4 p2 r _; g, A8 H - IPFS视频在线播放器- A2 b0 r! P- L& o( z/ x
+ j" E( l, T$ L& z+ V8 P5 a
& P( y' B( v, r& w- h) U
3 W; m" s( M5 u# `' O: @% }
4 ?, D h2 r) F& U% \' LIPFS视频在线播放器首页% E& Z5 `1 L% `1 w8 O
$ X5 \' H. r- d6 B
0 e9 j% e/ n8 \" u
- s: N" e( C3 l
/ ?. Y: g( R, o/ Y! x% M2 a% ~5 M+ O! G+ H/ K
IPFS视频在线播放器播放电影; o9 ^( f/ ?. M4 B8 A0 y% _
% Q7 c; f, C6 p4 K3 W+ o
号称是国内第一个IPFS应用* k2 ]3 C0 B. f9 y) b
IPFS视频在线播放器网址:http://www.ipfs.guide/; m9 K h9 Z4 r; R4 s6 C- [& H
GitHub地址:https://github.com/download13/ipfstube
7 q' m/ @* [9 |9 }# X可用于测试的电影视频Hash(这里只列举两部):
$ z% l; G3 t( z: I( r$ r# q% i神秘巨星:QmWBbKvLhVnkryKG6F5YdkcnoVahwD7Qi3CeJeZgM6Tq68
" t2 q8 {" H) p盗梦空间:QmQATmpxXvSiQgt9c9idz9k3S3gQnh7wYj4DbdMQ9VGyLh
! e* F8 R7 u4 f7 ^( [ t 2、IPFS的安装既然IPFS这么牛,有必要了解一下IPFS的开发,先从IPFS的安装开始。
; L; \& w! S; l F9 A" Q- IPFS Desktop
8 ]6 F- I6 t6 z8 W6 ^$ D当然,可以直接安装IPFS节点桌面管理软件来体验一下。该软件可以方便地运行和管理自己的节点,查看IPFS节点资源信息,支持二次开发。该项目是Node.js编写的,已开源。
: X5 b* r. f' F
2 X4 ]) @5 k: F/ P7 s5 t; |/ n. p
! x* r% |2 C( n* ^5 M
- D4 x k+ m* [" uIPFS节点桌面管理软件+ {9 I1 ~* T2 ^" g- W
5 O. \5 c0 G% o! I- H9 v, B, F
GitHub地址:5 S' s: v/ A. @4 d" W! C" u2 w
https://github.com/ipfs-shipyard/ipfs-desktop& S( x) H \, D2 \) E k4 f3 W1 B
- Go-IPFS
6 C, @6 a; L* g8 c: L+ r6 d进入IPFS的官网,找到并切换到"Install"页面,点击"Download IPFS for your platform",会跳转到如下网址(需要翻墙):; L" v7 @, K) v" m$ f* H& f. v
https://dist.ipfs.io/#go-ipfs* M5 W4 g; p0 M( U* E5 E) n
3 n; \1 r- B! l7 f& b0 l) K1 Q
: W; y _: z4 u
: Y$ Z* ]3 z7 |" I7 R
下载Go-IPFS2 j6 g$ x7 h' b1 u6 @. f( J
+ Y8 K* f7 Q0 X6 A* g: X
如果打不开,可以试着去Github查看安装方法( d2 `+ M# H2 D2 F6 E3 c6 J" G
GitHub地址:https://github.com/ipfs/go-ipfs: c2 T, x/ ~0 p6 l
将网页下载好的文件解压出来,下载的是"go-ipfs_v0.4.13_darwin-amd64.tar.gz",解压出来的是go-ipfs文件夹,9 I% V- X. g2 Q. k" v
然后打开终端,进入到go-ipfs文件夹根目录,复制ipfs文件到系统的bin目录,然后可以通过"ipfs version"来检查,操作如下:
; ~3 U% [: k+ g& jwenzildeiMac: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' B- K3 `4 t2 E) T7 L( J5 Q) H/ `
3、IPFS节点的创建、查看和启动以下是安装官网的Go-IPFS步骤下实验的
4 Y) f. G6 h( W2 @* {. u) G# ` }- 创建节点; Z1 Z7 l* H7 q3 K
进入到当前用户的根目录,并使用"ipfs init"命令创建节点,可以用"open ./"打开创建节点生成的".ipfs"目录。* ~- }, D7 Z& N
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 ./
( }% e! s V( w0 P! J* R# q z F+ t) _# ^3 Z6 T! q& q2 v
! m( V: `0 ]: w( p' L! q4 z
1 W& F9 {# B! h, R. a4 YIPFS节点的创建3 e/ J/ G# W$ y7 J/ G/ B4 R
1 [" X+ _0 t$ O; j4 b& S- 查看节点id+ i) V" ^+ D+ ?# ]
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默认存储空间
% T. e8 P8 u- z% H+ Q7 J2 \存储节点默认存储大小为10G,如果你想修改存储空间,可以修改config配置文件,找到StorageMax并修改
8 z* X# Q I7 D: H8 r8 WwenzildeiMac:~ wenzil$ export EDITOR=/usr/bin/vimwenzildeiMac:~ wenzil$ ipfs config edit % M. t5 S$ ~% D) c. L2 j u
. v, X, E! q0 Y4 i" B& j g- ]& \9 n
6 R- z1 r2 ?7 x8 T) ~/ f% b
修改IPFS默认存储空间, R+ H* f" _0 `- `
8 k% B4 ]9 P. Q( K8 L - 启动和同步节点服务器
) y7 n- W+ i8 z$ B; i执行"ipfs daemon"命令,可以同步节点数据到IPFS网络。; K6 S$ K& D& n/ ]& v! C
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
( E# m) ?3 |- a9 d3 X$ Z1 B 4、IPFS运行体验- IPFS查看ReadMe& w' M1 l4 ~/ u' J+ U/ F$ S
可以回去查看执行"ipfs init"命令的时候,返回的内容。打开一个新的终端,操作如下:! ?$ m1 |3 @. v0 O$ B
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管理界面
- f' J* i1 G4 @" L# W$ f+ E+ DIPFS节点服务器启动后,可以用浏览器访问:http://localhost:5001/webui
5 p# T( F8 }. l有本地配置、节点连接、本地节点文件等信息,如图:
4 X; d7 R e a3 j' V+ G' e" c' V! j! Q) `8 b0 t. n/ `5 c5 l& s* `
! F$ j7 B2 E# Z+ f. ~4 X* y( ?
4 @% w6 c6 l; b7 x$ s! m
( P$ @1 v4 B# t' o6 j5 _0 PIPFS的Web管理界面8 p& I, s% d5 Q! ~. h0 [
; p) \$ I+ G, j! T6 `; c+ A0 S9 @& \) s% y; W6 R' y) k
6 _9 B; J* i: V9 L) w: |
5、设置跨域资源共享当我们在前端通过js接口操作ipfs时,会遇到跨域资源访问问题,可以在终端执行以下配置来解决:
6 I. j" L2 y6 D$ R) A1 R+ j* i- l+ {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节点- 新建文件9 {: F' M& j& [* M# W, d3 U
wenzildeiMac:ifps_test wenzil$ vi test.txtwenzildeiMac:ifps_test wenzil$ cat test.txt IPFS测试文件 - 添加文件到IPFS节点. E5 @/ |& o9 a
wenzildeiMac:ifps_test wenzil$ ipfs add test.txt added QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab test.txt添加文件到IPFS节点后,返回了文件的哈希值9 [+ Y. v8 c, d X0 S
- 查看IPFS节点的文件" t6 d5 i3 F. m$ V( q
wenzildeiMac:ifps_test wenzil$ ipfs cat QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbIPFS测试文件注意:此时的文件只是添加到了本地的IPFS节点,读取的是本地数据,可以通过如下网址查看。
# p2 f3 p8 n7 t9 y& Whttp://localhost:8080/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab4 I/ M3 ^ k0 @6 k9 i4 U2 I/ u
通过"ipfs daemon"命令启动节点服务器,会将本地节点文件同步到外网,同步成功后,这时就可以访问如下网址来查看(如果访问失败,试着翻墙看看)。
% T; T/ E+ N$ E- {9 Y3 shttps://ipfs.io/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab
( `+ g8 k/ E) a: a. W% P
( e! {; U X8 H9 n6 i+ T: f* W
6 h$ S1 ]2 [4 L0 ~- n" F; l
- u/ F( [# o8 O0 ]查看IPFS文件内容
9 a/ W) z5 X) u5 K0 C0 B- O/ l
5 i$ z% L M" ?/ d( Y% f6 F如果访问成功的话,说明已经存储到IPFS网络中。目前IPFS网络暂未加入代币Filecoin机制,所以存储读取文件免费,速度也比较慢。
: e+ E8 ~& P( |2 J3 ` - 下载IPFS节点的文件+ o9 R9 O& ]' t
wenzildeiMac:ifps_test wenzil$ ipfs get QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbSaving file(s) to QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab 25 B / 25 B [========================================================] 100.00% 0s查看当前目录,发现多了一个"QmSV..."的文件": V: ^; |& M) O6 Q% s7 f) H
( P/ R! o5 Q% o: e5 O: A( ~* D
+ U# v/ n% q5 W
# h" D, E; Y3 E; s$ q
8 Z+ Y$ m; Y) }5 f下载IPFS节点的文件. X4 L! Z0 I( ~( U0 l2 p+ a
$ l# j) M- {, l5 c& S
: ?" F; o" } B' d 6.2 创建文件夹存储文件- ipfs命令新建文件夹8 V8 D- S) z; L! P( U
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 /文件夹名"可以删除文件夹。2 O1 E* I& {2 B( o) N9 z
( M6 F7 x2 g3 k: j 6.3 IPFS上传文件夹- ipfs命令添加文件夹
4 B, H r/ y! X% [' L, U- `先在本地创建一个文件夹和对应文件,如图:
1 o: n1 X% d0 h' X, o
2 V; ?# h& N* J8 c4 M( q
8 t" l+ E6 Y C" Z$ c
1 a" v8 i; ?5 L5 U! x5 o5 J5 M% D& N, ^+ Y p$ X
本地创建文件夹及文件9 f/ U- s* C" H' y
* ?3 g- k* Y7 b8 n9 g/ ~& Q* {1 Z( M
然后通过"ipfs add -r 文件夹"命令添加整个文件夹4 S3 {4 {3 c" |5 T6 S
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$ - 查看文件夹的文件内容% K+ B4 @. _0 R3 B7 M
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对应文件夹8 b6 A g3 i% n: h8 j9 R R# }
访问文件夹对应的IPFS地址:
: s3 S9 c) [0 ]* ~2 Hhttps://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj; a( a9 H0 {9 H7 V6 W) A& X% Y! A
第一次访问的时候,需要同步数据到IPFS网络,等待时间有点久,慢到让你以为同步失败了。3 L8 D, V+ s' i! w- K
8 e' {0 j! j5 ~
$ g4 }, h0 V+ ]6 @& B: a. x( c- |
8 y/ C G! o& v; u" _" J3 {! y5 j查看IPFS对应文件夹" k$ `, ^" A* T
8 m; u/ K: W* O5 n
访问文件夹对应的文件,如看到图片文件,访问ipfs网关:# Q3 M! W6 M, |8 O5 a/ j/ h
https://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj/portrait.jpeg0 E9 d! U0 n, c: _3 }- e9 D
' a% g5 J! `4 P8 O" A" P% ]/ J
0 X }/ x1 S% V
+ I( V7 D/ j, a查看IPFS文件夹对应文件) U, {) [0 f# F2 m; p- m
; \! i) X0 V6 Q" C/ N5 Z2 E: H
或者通过文件的Hash来访问,如访问txt文件的地址:
- g+ a: ?8 y- _7 d; lhttps://ipfs.io/ipfs/QmPEWgwQEHD6qxm5cUivTEZ252T123DvQ5L6HyUDgViQvT+ u! d7 ]5 v% |# A
; b I' y0 N% w! Q' S/ t4 Q! t
. H' z3 M$ p4 t
- U$ a/ V# e: X2 z通过文件Hash访问查看
4 `1 U& K# c' K( Z2 k
" T. |3 T$ b, Q9 a0 N% A# `1 r- [2 @& o: H, u
6.4 添加简单网页到IPFS节点- 网页效果和项目结构
- W1 ~+ `2 s9 I实现一个简单的实时显示系统当前时间的网页,效果如图:
" c% Y$ T9 b1 b( O+ K$ J8 }5 D+ x" Z8 k1 ?2 t' D( P
6 I/ A( c9 x0 \
/ F$ n: M, w8 \$ k- F8 j* g- ~3 o5 d! ~
IPFS添加简单网页
* i5 q" C# {4 Y1 j! n7 ~6 ?& K/ q6 | Z/ R+ u* d
工程结构如图:
5 H$ r5 V* E: m' r$ U; X% J
8 I) K7 W1 Y8 Q3 W; C& G( y6 u4 E$ Q* e
( C# i& ^1 U3 w: l: d [: D& z2 v# O1 y/ Q5 L' C$ F- e: e* Q) y5 w' [
网页工程结构
* y" e/ n1 d; ~
- }3 N2 I8 C! o! \: N( l d! L9 s' m
实现代码比较简单,这里就不贴代码了。
1 v$ Z4 P8 E* ]2 [4 j6 ]5 e# P3 r- ipfs命令添加文件夹2 b* j) O" C, o# E; p1 {& }
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"命令在新的终端窗口打开运行。: l4 P& e* |& w2 a
wenzildeiMac:~ 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对应文件
$ t# a {- m( ~! V& ], k% c0 g; Q浏览器访问ipfs网关:1 a& H: t1 {3 o" d R1 x5 @) B6 h, o) T
https://ipfs.io/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD/
% [2 M/ N' H. C0 p+ C, e# L' n5 K" v8 z. v4 t" S+ d1 u5 g
+ W5 o. j! R; I( `! Z
7 W, z' M; A. G' J
查看IPFS对应网页
: D0 w. W' q2 k% x$ k% ?% c
5 N. G& l ]/ b$ B; x4 r* F6 B4 ~5 _ B: m4 d4 |; h
6.5 IPNS绑定节点名- IPNS绑定节点操作9 F* o2 t" N$ y- M
每次修改文件内容后,文件的哈希值就会发生变化。对于网站而言,发布后可能还需要做修改,这时需要IPNS绑定节点名。每次更新网站内容后,重新publish一次更新发布到IPNS即可。* x/ A' w& g' J) M- \
刚才的html根目录的哈希值是QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD,操作如下:
" d$ g* M' K6 s' x/ X6 x _" OwenzildeiMac:study wenzil$ ipfs name publish QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDDPublished to QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz: /ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 查看当前节点
8 B( ]- i( |3 f& M$ N/ z: @1 G3 |/ _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": Q* S* }$ `$ }/ \* `% r
- 验证节点
) \/ |7 _, F" ?7 E& ^+ d' x8 _7 @命令为:"ipfs name resolve 节点ID“* ~+ |4 X$ X* l3 t0 y
wenzildeiMac:study wenzil$ ipfs name resolve QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 访问IPNS对应文件
# a6 Y2 K2 N0 U7 n% ?% K6 ^浏览器访问ipfs网关:# y. v4 F; y. B' d
https://ipfs.io/ipns/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/* V9 K; u" {. [: G7 e9 ~( M
% k0 r( t: ]; C+ r& |7 ~9 p
! u' @/ A. @( ^' ~! H( J5 `
: X8 L+ f- e' V; \ K
8 M( u: Z9 R: X `: x; C; f查看IPNS对应网页
" K$ F! d( z& ?1 f
" p1 K, J% E y+ C0 [! z7、IPFS与以太坊DApp开发实战- IPFS与以太坊DApp结合的好处) P5 p/ E w) Q0 ~5 ]4 Z% }+ C7 h
在以太坊平台上,往区块链写入数据需要花费以太币,调用智能合约执行每一行代码的时候,都需要一定量的gas交易费。区块链存储大数据成本很高,而且不合理。3 g5 a2 N1 q6 [2 ]4 W
可以先将文件存储到IPFS,然后得到文件的Hash存储到以太坊区块链中。读取文件的时候,从以太坊区块链中获取文件的Hash,再通过Hash来读取IPFS网络上的文件。
* k: b# R7 v" t/ _1 C使用官方提供的ipfs-api,可以很方便地在代码中操作节点将数据上传到IPFS,或者通过Hash从IPFS读取数据。
7 o2 {3 A2 I. G3 o5 OTruffle框架提供了快速搭建包含以太坊智能合约的React项目,可以通过"truffle unbox react"创建工程,然后安装ipfs-api依赖库。于是,可以在前端方便地调用IPFS的接口来读取、上传文件。+ D, O1 y& G# ^" B: I/ T. u* i
truffle unbox react官网:
- Q4 z6 }$ B/ E8 rhttp://truffleframework.com/boxes/react
" i E8 l- c. r, Q8 t - IPFS与DApp开发实战% s: e) E% v6 r9 M$ r8 ^" u
话不多说,开始进入实战开发。
7 V, h6 X/ C; |0 t7.1 安装Truffle unbox react新建一个空目录"ipfs_dapp",然后执行安装命令
1 L: N* Q* W: ftruffle 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",修改后完整代码:
w+ r: n) p+ h C9 K3 Tpragma 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". }; X3 n, z6 D7 p9 H) O
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"进行智能合约的部署
; q5 u; y- {1 A' J! L. W
8 v% }% N+ A, y0 k: C8 @) c4 N
# f% n& r. E9 B, f9 `# Q
2 p0 r+ b" {* V# A& U! YRemix-IDE部署智能合约
0 D, m. q- }; D' e3 K9 c; D* p, R; ~! Q y7 V' P+ s
! {3 f, m- J- t5 p+ D: ?6 }
3 }- G. M' T! c0 B: I
+ h' w h4 @/ u IRemix-IDE部署智能合约-确认/ V: [9 g5 p0 A. M. u4 a" [
$ k; ?0 W1 q2 Y' } s0 u然后复制智能合约地址,App.js文件中会用到合约地址为:"0xb177d6cf6916f128c9931e610c63208d9c5a40f3"
+ `$ J4 T% K# p' _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"命令,结果如图:7 k, X# Y( m3 {: J1 R4 T9 l
M/ H4 w# j z8 `' s: g
F! Y/ u ?. N/ }1 n& nnpm_start
- @; B- A0 J8 U3 u* g- ?1 a5 `: L! K. F* o
会自动打开网页,然后上传一张本地图片,之后点击"图片哈希写入区块链"按钮
9 X4 x# G2 [' o. |/ w
) Z" E$ I6 @7 z" z. M
+ @0 @# h7 p1 _! J
) K* N1 R/ c' g& D6 |) m- i
运行结果1
1 E& `- X. Y) n# Y- Z7 t
& @2 X' h, h& H: d4 B! T6 j* P! O; z最终效果如图:+ C3 y5 Y" ?) ]
# E# n8 z) W. |% W$ S9 G$ W
) @& {* v4 k& w. z3 L" W
! u/ L/ I5 }1 e7 b3 d0 S* B) s
0 A* {/ b% V: L* U& T3 _
运行结果
0 @0 N- u7 x8 ~- d4 l6 G3 i/ H
1 Q' F" b5 O7 l$ y0 ]访问IPFS网关:
9 c) L) Y3 ~, v7 s. |" \( U) s* phttps://ipfs.io/ipfs/QmbHptfJfyuGAZxstFYgAVfz33cytR1seTD3ZabBSDd899
; f/ r1 {6 ^" _: ]发现图片已经成功写入IPFS,如图:7 b+ `8 |; r `' s; a$ W
) y6 t1 y3 _, Z/ y" I3 Y8 q
: ~5 k, ]' Z/ W, _1 \
% L9 h: r7 c+ l9 p
& L+ r5 C! ]9 `- b: V- H% V7 e! a运行结果30 @% G/ C2 y+ _
& q3 R9 s( g# E! z
备注:本地IPFS网关端口默认为8080,我的电脑上端口冲突了,系统自动修改为8082。
A6 b+ A' S; m b1 [- T! B6 a搞定,收工。
. d5 R& S: X' l( X* R5 tPS:刚入坑的小白,很多不懂,还请各位大佬多赐教,谢谢!
% l9 ?. G9 |/ d9 @7 d" }
F/ W& ~6 z4 C" w; S
|
|