|
|
本帖最后由 赤膊医数 于 2021-4-22 23:41 编辑 , e/ a } p v5 S. s) _0 Y% L
w- u4 h3 f1 z; u9 h" Y' B/ ?2018年,最火爆且值得期待的区块链项目莫过于EOS和IPFS。1、IPFS简介- IPFS是什么
% K3 @# x6 N. N& I' `' E2 _星际文件系统IPFS(InterPlanetary File System)是一个面向全球的、点对点的分布式版本文件系统,目标是为了补充(甚至是取代)目前统治互联网的超文本传输协议(HTTP),将所有具有相同文件系统的计算设备连接在一起。原理用基于内容的地址替代基于域名的地址,也就是用户寻找的不是某个地址而是储存在某个地方的内容,不需要验证发送者的身份,而只需要验证内容的哈希,通过这样可以让网页的速度更快、更安全、更健壮、更持久。& Q) w$ f0 A3 @4 s
以上内容来自巴比特官网介绍
2 w7 c) l# e# \+ ]IPFS是基于区块链技术的去中心化存储网络,实现了永久性存储。
: `# \ e' T( S1 C& K2 Y/ [ - IPFS的火热1 ~, ], n! f& q
Filecoin ICO是迄今为止涉及金额最大的ICO,仅一小时就募集了接近2亿美元,打破ICO记录,成为2017年最火爆的区块链项目。IPFS项目吸引了世界各地数字货币投资者和互联网从业者的密切关注,2018年比较值得期待的是IPFS主网的上线。然而就在前段时间,官方公布说上线时间延期到年底。+ [, O& ]$ E6 U7 y
注:Filecoin是IPFS激励层的加密数字货币(即代币),有点类似于以太坊平台上的以太币。
" x! b, |3 |7 t( q) ?; MIPFS官网:https://ipfs.io/4 y% \! |6 B3 j4 l4 `
Filecoin官网:https://filecoin.io/
8 `: l# P3 D9 H& t# q - IPFS的应用案例- i' g; p. F7 a- m+ n
GitHub有两款开源项目,且有对应网址,分别是音乐播放器和视频播放器。, B% c# F2 F( K7 L8 f
4 F" G- {1 w+ k# b4 X: s% t6 l- IPFS音乐播放器6 V& ~- i+ I3 a1 I3 b% G5 D7 P) H
1 H; ^# L6 D, G
- d; j- C; L d" j8 s& x
0 Z9 H+ {/ C d# r% M9 O4 \+ k- L
/ z8 ?8 l- o- `) F
IPFS音乐播放器
& s+ n5 G% h |3 a1 s" _) K9 c" h6 d- v3 p
IPFS音乐播放器网址:https://diffuse.sh/) f) e0 H2 `% Z9 \
GitHub地址:https://github.com/icidasset/diffuse
+ r6 ]: }5 Z3 z) M- W q$ l - IPFS视频在线播放器& `. |# V) A+ B" ?6 ^
0 B1 C" e( Z* E X7 h# N0 {; R
& J0 p; W* [! _/ {# z
; L7 M ]: Z. P% ?9 L
- W- `& Y3 `2 N0 z
IPFS视频在线播放器首页
% J- q5 d4 U* b, U1 c1 o! c7 h4 A$ a- F/ X1 b1 o5 K4 l0 x" Q" S
4 m( g) L7 q" H* K8 `% A
' ^1 R8 ~5 P. T( W. h
! D: @- ] o3 H H# x8 \5 A1 F f
! v/ C3 b, u B- j8 S8 W
IPFS视频在线播放器播放电影+ R5 A4 l" w8 H" _! _, Y3 W8 @& z: Y8 E
7 p$ q1 H' L; }
号称是国内第一个IPFS应用
! H' l5 j- w6 @IPFS视频在线播放器网址:http://www.ipfs.guide/
1 C; @& W2 |6 B" \4 v; j+ WGitHub地址:https://github.com/download13/ipfstube
; o! w" `2 M: G1 l4 d# n可用于测试的电影视频Hash(这里只列举两部):
; L; n' ]7 V. @0 x$ k5 F ?神秘巨星:QmWBbKvLhVnkryKG6F5YdkcnoVahwD7Qi3CeJeZgM6Tq680 F2 ~" d" g7 K$ C; p- G. D! a# p
盗梦空间:QmQATmpxXvSiQgt9c9idz9k3S3gQnh7wYj4DbdMQ9VGyLh
" U5 A" @" s6 H9 p8 o- n3 t 2、IPFS的安装既然IPFS这么牛,有必要了解一下IPFS的开发,先从IPFS的安装开始。% m# B' ~3 W8 ^% w: o
- IPFS Desktop
0 n Z* u$ o U7 M; y当然,可以直接安装IPFS节点桌面管理软件来体验一下。该软件可以方便地运行和管理自己的节点,查看IPFS节点资源信息,支持二次开发。该项目是Node.js编写的,已开源。
8 [" d. l; J* E# y0 r: `1 o
/ S# v$ T2 r3 a& t8 j) r- Y
4 }: I& x) _. O) \7 l
# \" E8 ]( M9 l2 z* X* Z8 f' u z. ~3 z" W
IPFS节点桌面管理软件- l* H/ B2 b( b" \$ p& O
. l( x+ X7 R, N' h1 l/ ~GitHub地址:
5 l/ J$ b# y0 B. R/ A0 ]9 Zhttps://github.com/ipfs-shipyard/ipfs-desktop
o$ {1 P' ~' L" |' r( L. l/ Y - Go-IPFS
" ~7 Z* a0 m( r, l进入IPFS的官网,找到并切换到"Install"页面,点击"Download IPFS for your platform",会跳转到如下网址(需要翻墙):2 T" g4 @, p% s0 a; b
https://dist.ipfs.io/#go-ipfs, S3 O1 T' N3 S. ?8 ?
' M5 i6 @4 J C8 F& ?4 e# E
) w8 A' Z" X7 ^$ q2 ^8 C0 h: w* |
, S& y' x. T' F/ `% [
下载Go-IPFS$ J4 {, c% C2 e$ _+ ^
1 G& D# j( P9 [" j如果打不开,可以试着去Github查看安装方法
3 L" D8 z- `4 SGitHub地址:https://github.com/ipfs/go-ipfs
0 {$ D) T: E! W$ E将网页下载好的文件解压出来,下载的是"go-ipfs_v0.4.13_darwin-amd64.tar.gz",解压出来的是go-ipfs文件夹,
7 o" h' }7 g5 x) H$ V4 s& d然后打开终端,进入到go-ipfs文件夹根目录,复制ipfs文件到系统的bin目录,然后可以通过"ipfs version"来检查,操作如下:
4 H, L/ h) U* u$ P4 c' `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
" |% t/ x9 p4 s5 Y: n+ J3 I 3、IPFS节点的创建、查看和启动以下是安装官网的Go-IPFS步骤下实验的1 P6 M" \6 O7 {, t+ s0 ]+ W
- 创建节点
% |# I+ g' ~5 a# l, ~进入到当前用户的根目录,并使用"ipfs init"命令创建节点,可以用"open ./"打开创建节点生成的".ipfs"目录。3 `8 @9 d; u v) Q
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 ./
% K% Z6 L( I0 b' A 6 ]1 s" e9 ~4 y, e1 C
. k0 n1 [* t3 S8 L
1 a8 s- Z/ R% o5 K9 d* _# eIPFS节点的创建" Y4 U. ~6 I& S: x
" i! l) c! m8 f- R% L0 Z' x
- 查看节点id
3 ~; n: L( z; f1 I0 ZwenzildeiMac:.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默认存储空间
! X! J' w& P b! x' V) u! m/ i存储节点默认存储大小为10G,如果你想修改存储空间,可以修改config配置文件,找到StorageMax并修改& k5 {/ w( e4 o0 I7 V
wenzildeiMac:~ wenzil$ export EDITOR=/usr/bin/vimwenzildeiMac:~ wenzil$ ipfs config edit * w* i _7 ?1 R, l9 S
4 l5 f* P( M7 {3 R& C# M
9 Z' G6 \; u* I7 D+ N' ?修改IPFS默认存储空间2 |" Y4 }! Q3 Q% \* Z1 N
* X& e& l. ~1 l8 O - 启动和同步节点服务器3 a6 ^8 U& M" m1 @; ?+ K
执行"ipfs daemon"命令,可以同步节点数据到IPFS网络。" ]) ^/ s& Y; \4 x7 S# 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
, C$ u) u" D& J: e( ?( q; @% w, V5 d 4、IPFS运行体验- IPFS查看ReadMe# T# T4 t/ q/ ^6 N
可以回去查看执行"ipfs init"命令的时候,返回的内容。打开一个新的终端,操作如下:
/ M$ r; V1 M* X2 _" uwenzildeiMac:~ 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管理界面
$ k4 ?6 l! v9 r4 u& Z. D1 _IPFS节点服务器启动后,可以用浏览器访问:http://localhost:5001/webui! ~$ z# h6 \: p1 K( X1 |3 [
有本地配置、节点连接、本地节点文件等信息,如图:( K. v3 J9 M3 Q/ C2 v3 j8 U1 \
5 a1 X7 i1 d) V+ H
1 g( l% R3 F5 f5 q* Q
) e6 R, k$ U% q7 ~9 @4 H# L+ h. b: y0 C; F
IPFS的Web管理界面7 C7 j# p% K* v4 |8 P
, j& y) z" J! x7 b% h+ V" l% E. c3 z
( K& a% {2 c/ ~" E7 N
k- }* P8 B5 c; i$ [5 c7 ` 5、设置跨域资源共享当我们在前端通过js接口操作ipfs时,会遇到跨域资源访问问题,可以在终端执行以下配置来解决:& ^9 G# t' E# c' E. | {
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 `% b. t8 X# x6 d! W) IwenzildeiMac:ifps_test wenzil$ vi test.txtwenzildeiMac:ifps_test wenzil$ cat test.txt IPFS测试文件 - 添加文件到IPFS节点
" T4 v8 o' }* U w# Y' fwenzildeiMac:ifps_test wenzil$ ipfs add test.txt added QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab test.txt添加文件到IPFS节点后,返回了文件的哈希值
$ P5 P% H0 ]& z2 |& [! w - 查看IPFS节点的文件
& c, K. G" P0 G5 L7 u% z) k8 pwenzildeiMac:ifps_test wenzil$ ipfs cat QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbIPFS测试文件注意:此时的文件只是添加到了本地的IPFS节点,读取的是本地数据,可以通过如下网址查看。
! }* H' }" G3 J/ z9 l' mhttp://localhost:8080/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab5 {5 S& Y3 j$ z, g# M4 U- I( S7 k
通过"ipfs daemon"命令启动节点服务器,会将本地节点文件同步到外网,同步成功后,这时就可以访问如下网址来查看(如果访问失败,试着翻墙看看)。
, G. g$ X6 E0 ^3 ] _! o; r0 Phttps://ipfs.io/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab
3 Y0 n; q' ~7 r" R6 H; [: ]2 ?* v8 K
2 v* i, `% r( s: r
% \" U W6 V; b6 h; s9 p& V
查看IPFS文件内容" o/ {% s) S4 x- V% `
3 @1 _0 p- ^% s+ X9 ~
如果访问成功的话,说明已经存储到IPFS网络中。目前IPFS网络暂未加入代币Filecoin机制,所以存储读取文件免费,速度也比较慢。
+ Q" h% A8 s1 X5 g - 下载IPFS节点的文件
: r% V4 y6 M3 X y8 _/ twenzildeiMac:ifps_test wenzil$ ipfs get QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbSaving file(s) to QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab 25 B / 25 B [========================================================] 100.00% 0s查看当前目录,发现多了一个"QmSV..."的文件"; |7 Z9 G& n3 l9 k2 M8 a( Q% t
. D s" l. L) s( w) O
R& D3 l, b5 i. s' b8 Z$ {7 G9 V
' g4 D7 W+ ^& v B1 n% C7 E" c7 w+ S1 K
下载IPFS节点的文件
. ?" R4 ^ c$ ? I* p' K* Z3 Q+ R
" w. W3 c5 j; E2 E5 A# D3 _" c& U% F7 x: U
6.2 创建文件夹存储文件- ipfs命令新建文件夹+ e9 A' Q( J0 R9 C& n5 W* Q8 N
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 P# \$ h0 t: l u1 ?
D; h' f. o5 t# u$ c8 ] 6.3 IPFS上传文件夹- ipfs命令添加文件夹1 |/ D; i& p1 k* y
先在本地创建一个文件夹和对应文件,如图:
+ I7 n" A3 Z& M4 j8 A; @) ]! u+ n# u' A" m
6 E8 A: g* U2 h! C+ r
: k' g" ]" a( b- Y; d
/ ]/ G& w, U, N L( x8 c0 r本地创建文件夹及文件
, X. A! c) X7 C2 {+ _# @: S6 s9 Q4 Q8 W2 a
然后通过"ipfs add -r 文件夹"命令添加整个文件夹
9 x# g/ @( L/ C8 E' V; M! I, G3 I+ ^ 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$ - 查看文件夹的文件内容
$ ~" F9 z3 k) B+ N3 J+ @0 z6 EwenzildeiMac: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对应文件夹9 [4 {+ h0 O- B2 _, u* e( d q
访问文件夹对应的IPFS地址:: \ h/ T" Z$ z- {- Q
https://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj! M% ?! M# i1 [1 X N% P2 _. W! _
第一次访问的时候,需要同步数据到IPFS网络,等待时间有点久,慢到让你以为同步失败了。
" O0 ^/ Y. Y# _/ `. W9 H. k
- [$ K' i5 R; [7 p2 p1 A* y
2 e. ?0 T4 B, r) R. I
6 ^- P% o* h' b# v+ {0 L# D
查看IPFS对应文件夹) w" D+ R7 r$ ?) C, s
* v" |2 C+ V ` n5 g9 q) B访问文件夹对应的文件,如看到图片文件,访问ipfs网关:
5 j7 z9 B) Q/ a7 Y" ]https://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj/portrait.jpeg
, Y% E& U; ~, J7 f9 V; y8 e& r+ y- u$ K' J. H$ L! z, q5 m( w% ?9 M
1 }3 T. N7 v0 c4 g* n- q- _4 v/ X* }1 b; ^" i0 u& @' t) w
查看IPFS文件夹对应文件2 V4 ]3 X. v/ G5 D( A. m8 f
) P9 V' X$ A' _- ~4 l" l0 o, i8 n/ J
或者通过文件的Hash来访问,如访问txt文件的地址:7 i R+ q9 ~7 y# u
https://ipfs.io/ipfs/QmPEWgwQEHD6qxm5cUivTEZ252T123DvQ5L6HyUDgViQvT
0 R$ d" n7 s/ `3 Z& a5 x
( l) m1 u& g6 S! l3 U0 m
' k3 r- P6 L9 w8 H% f% u0 t3 K
% [# C& f+ S2 `
通过文件Hash访问查看
9 K& l7 ^8 R8 W# Z
( F; v( v. r" g: Y$ ~; \6 g( t$ |3 S& a& {- P; [$ x% u2 f/ u
6.4 添加简单网页到IPFS节点- 网页效果和项目结构
0 q w# S2 d$ [; _. Y5 ^: `) y1 e实现一个简单的实时显示系统当前时间的网页,效果如图:
; B$ f0 \& K. K3 ^: z* w, B
5 j3 R/ [, _) |+ |3 ^3 }
: O2 K$ _ u7 _, _ R% n
6 L3 i; A3 q( a; N ~4 A# U7 M4 e9 ]( f9 h" c
IPFS添加简单网页/ e) C9 m" b9 @4 W, }" Z) X0 ^$ h
3 m( k' ^! s1 b2 n( C' ^1 A
工程结构如图:; q; E! M% @+ s" D
: r- o' d) P! u f* }
' ?8 D6 i% {/ m5 q0 |
" v; ?' v) w" x0 N' d% `/ I
/ m* {" v: K2 {+ J/ Z- E网页工程结构
0 t" \# {2 h0 Q- P
! ^; Z$ c4 t/ X6 {1 s- q, z7 q# p' g- O2 V9 E' j
实现代码比较简单,这里就不贴代码了。
8 y0 l" ]! y$ W! D; q: N- ipfs命令添加文件夹
' K$ i- F1 U% i* }( h+ H0 ZwenzildeiMac: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"命令在新的终端窗口打开运行。
7 X, G9 `( H7 M& l7 q6 uwenzildeiMac:~ 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 z" d& B4 C& r/ W1 _1 i% \, P
浏览器访问ipfs网关:' {: @. i" E1 q7 `( P
https://ipfs.io/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD/
8 g' w. ^1 W0 E
' C4 @/ v$ @1 e3 z
" |1 Y: H v( ~ `
: x1 n1 c! ~" ~查看IPFS对应网页+ m+ ~- A7 r2 r- a5 ?( t
( r; l2 q/ l1 _9 N6 `" v$ A
$ S; \; D& L# @
6.5 IPNS绑定节点名- IPNS绑定节点操作" o- |: `# u) N& P
每次修改文件内容后,文件的哈希值就会发生变化。对于网站而言,发布后可能还需要做修改,这时需要IPNS绑定节点名。每次更新网站内容后,重新publish一次更新发布到IPNS即可。' l7 [. S. L- o1 i
刚才的html根目录的哈希值是QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD,操作如下:! U( E& d7 ?: s: d3 r. B
wenzildeiMac:study wenzil$ ipfs name publish QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDDPublished to QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz: /ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 查看当前节点
, t9 v. W1 y5 h) [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"
$ N! D8 c7 N0 Z' a - 验证节点4 G8 r$ O& Z6 c' l! D
命令为:"ipfs name resolve 节点ID“
# U4 [" ?( ~; t0 g1 v! twenzildeiMac:study wenzil$ ipfs name resolve QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 访问IPNS对应文件4 o% }$ t$ I' J. c$ }. H
浏览器访问ipfs网关:0 c, E8 o+ b6 B4 K1 S
https://ipfs.io/ipns/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/+ ^+ }, M) {# [2 t9 u4 _, t
0 s, ^1 _* W t. [% l7 J, u
( t, U; F: j2 z. E8 b
- P& e2 `1 S1 x# w5 ?9 _. p9 Y( a
: }8 Q- Y& _" J7 C" E0 ?( s8 W/ O
查看IPNS对应网页. L( x$ j t3 A# R; o$ T5 g% p2 W
+ \9 q6 x. h& N5 x1 T' F7、IPFS与以太坊DApp开发实战- IPFS与以太坊DApp结合的好处. n( z" h# J+ n* n0 R: R
在以太坊平台上,往区块链写入数据需要花费以太币,调用智能合约执行每一行代码的时候,都需要一定量的gas交易费。区块链存储大数据成本很高,而且不合理。. X) i' j+ L( S: p3 X
可以先将文件存储到IPFS,然后得到文件的Hash存储到以太坊区块链中。读取文件的时候,从以太坊区块链中获取文件的Hash,再通过Hash来读取IPFS网络上的文件。
8 m: K* Q D a使用官方提供的ipfs-api,可以很方便地在代码中操作节点将数据上传到IPFS,或者通过Hash从IPFS读取数据。7 S% q. O0 ]8 N
Truffle框架提供了快速搭建包含以太坊智能合约的React项目,可以通过"truffle unbox react"创建工程,然后安装ipfs-api依赖库。于是,可以在前端方便地调用IPFS的接口来读取、上传文件。
5 ?' X0 a2 R: w1 ~7 {. W3 { {truffle unbox react官网:; U; x8 Q6 Q$ p5 r3 R
http://truffleframework.com/boxes/react
% E1 E+ }% i l4 e - IPFS与DApp开发实战
! p0 X5 ]" B; W* M1 N* y话不多说,开始进入实战开发。
" c: f" X2 z8 a! J4 `2 ?8 ]7.1 安装Truffle unbox react新建一个空目录"ipfs_dapp",然后执行安装命令
4 o, a8 x, x$ P Struffle 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",修改后完整代码:
# A* ~9 q. Z, l8 ypragma 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"
+ l9 m3 t. @) _- [, [4 ofunction 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"进行智能合约的部署& p9 ]" l6 v9 D8 c2 V/ y4 f
+ z. V! d; n" U) H1 F
3 J5 H6 m8 r1 E* U: _' s
$ m! k/ }$ M5 O0 A7 [% b7 y! E. S9 RRemix-IDE部署智能合约
5 j( X1 U8 r- o/ C1 f: X6 L# j9 l2 w. }+ P/ Q9 u# R
! z- _, G4 \2 W7 w( J: V& L
8 m6 a, d7 D R# L
- j0 h6 M, p0 ^, ~7 G; H* }8 ?/ M4 GRemix-IDE部署智能合约-确认 Z. d# r* y: ^- J. m
0 p- C& E' Z4 z
然后复制智能合约地址,App.js文件中会用到合约地址为:"0xb177d6cf6916f128c9931e610c63208d9c5a40f3"
, f; U( v3 n3 d' s: 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"命令,结果如图:, Q- j. A' q! B/ G* a
5 T) `! G; Z7 Z0 a1 o* q& O* _% _+ U8 ^2 C
npm_start
% S! i8 T9 A) d1 j2 T+ O+ L- @& U4 d: m5 j8 x; Z
会自动打开网页,然后上传一张本地图片,之后点击"图片哈希写入区块链"按钮3 h6 P' M, m4 v$ H! L1 B
: ]6 {8 R; l3 {& i- L
G" {& ^! z( p3 H( N! [5 l9 b
* q6 y/ Q' f% Y. z C4 T运行结果11 z# X; [/ }1 g* r( ]% z+ v2 L
5 }2 w5 R8 E2 r( Z: e
最终效果如图:
4 C, T J6 V8 ^ j4 [: @$ N D
" Q' W- v! `' b! C% M# a! v
0 g5 d. F# W2 d1 o% o" K/ _: T" s
; ?1 e7 r0 W2 `/ f- `6 f" P( o& ~6 k运行结果& d" ?8 R9 z0 j. H* x: p8 `
8 e& D7 z" n/ @' o5 r
访问IPFS网关:: G" K+ F/ q# D0 E" i H2 {
https://ipfs.io/ipfs/QmbHptfJfyuGAZxstFYgAVfz33cytR1seTD3ZabBSDd8999 p$ ]6 Q- s9 [7 V3 \2 O* w
发现图片已经成功写入IPFS,如图:
; j" T k7 W( @2 n7 w( M$ z; _) a5 {9 p* O, R
1 G2 t. X) ], t
5 N0 p J2 u6 B, t! _, [1 d) k# h2 ]& d* Q* j$ r
运行结果3
, q' k* p" j; k: H$ T5 K% D+ p# I) R
备注:本地IPFS网关端口默认为8080,我的电脑上端口冲突了,系统自动修改为8082。
' }/ H; h; U7 P搞定,收工。7 C9 h! {: J! l- z S' f: k B
PS:刚入坑的小白,很多不懂,还请各位大佬多赐教,谢谢! B9 F8 h* V# Z6 ]
' y- {- J. {% @# Z. a) `% G1 @5 q' l
|
|