|
|
本帖最后由 赤膊医数 于 2021-4-22 23:41 编辑
: K) b S% @$ C; s6 n/ C1 h# L. @; b" W( e; Y# G3 F
2018年,最火爆且值得期待的区块链项目莫过于EOS和IPFS。1、IPFS简介- IPFS是什么& x) ~2 F r8 e* N- j0 B) x* F: m
星际文件系统IPFS(InterPlanetary File System)是一个面向全球的、点对点的分布式版本文件系统,目标是为了补充(甚至是取代)目前统治互联网的超文本传输协议(HTTP),将所有具有相同文件系统的计算设备连接在一起。原理用基于内容的地址替代基于域名的地址,也就是用户寻找的不是某个地址而是储存在某个地方的内容,不需要验证发送者的身份,而只需要验证内容的哈希,通过这样可以让网页的速度更快、更安全、更健壮、更持久。
) ~3 S( j1 `& {/ ]以上内容来自巴比特官网介绍* U( Z6 f& d, C. c% z. \
IPFS是基于区块链技术的去中心化存储网络,实现了永久性存储。
1 {/ Y8 E4 Z2 j3 l - IPFS的火热5 N8 I6 N9 R) g$ `* R" ^5 L
Filecoin ICO是迄今为止涉及金额最大的ICO,仅一小时就募集了接近2亿美元,打破ICO记录,成为2017年最火爆的区块链项目。IPFS项目吸引了世界各地数字货币投资者和互联网从业者的密切关注,2018年比较值得期待的是IPFS主网的上线。然而就在前段时间,官方公布说上线时间延期到年底。
! r1 d. a# r5 B* a注:Filecoin是IPFS激励层的加密数字货币(即代币),有点类似于以太坊平台上的以太币。4 f6 f/ e. S6 [$ p' k; T
IPFS官网:https://ipfs.io/0 `/ M3 o8 G u, p
Filecoin官网:https://filecoin.io/
% v$ }/ O9 E9 m [8 M- ^ - IPFS的应用案例
2 s5 O, ]; T8 Z6 [" \( z! g- PGitHub有两款开源项目,且有对应网址,分别是音乐播放器和视频播放器。
6 U3 n( \7 L. n3 A- g6 K+ U4 E; u* R, j
- IPFS音乐播放器& c1 G0 E4 G# K
4 q [1 t3 i) ^6 {: _- [
2 E! N5 X7 j; |
. @3 E, \ Q9 ^# t
, }7 ?: s4 _$ V: W5 G QIPFS音乐播放器
4 c* A+ P6 U& x1 n
2 v! ?8 t; L3 _' G; Q( ?/ BIPFS音乐播放器网址:https://diffuse.sh/
! W1 {7 R" c: G. o( uGitHub地址:https://github.com/icidasset/diffuse4 F& B7 Z4 W# s6 z$ Q$ w/ K1 P
- IPFS视频在线播放器
6 w& y0 T z8 C. M
: ]( D8 `3 {2 |/ O; s, |
) P1 Q% b" X& e2 y! A d
0 [1 g |9 b1 b% e0 ^/ ?. }
0 Y% Q( d- U3 T7 m9 [5 p# y
IPFS视频在线播放器首页5 r2 f/ V3 W' ?8 b* ]3 b7 e- A
0 ^4 O$ K/ \8 m# [9 N" f0 b2 Y' T% l( Y2 ]! N6 b
, |' J' c. A8 V0 Z+ d
h, E, f% F: F) G) {
! k+ l+ ~5 A$ b. J1 M/ |- j9 CIPFS视频在线播放器播放电影
7 F) a# m" N5 o( z5 k( z- e" @) Z* |' h: u
号称是国内第一个IPFS应用
2 M9 w' O$ j3 ?7 ^- F4 KIPFS视频在线播放器网址:http://www.ipfs.guide/! s" _6 B$ J6 A2 L/ Q1 K
GitHub地址:https://github.com/download13/ipfstube
( d6 b/ M3 I" c7 a! g可用于测试的电影视频Hash(这里只列举两部):
% Q F, x/ \, y6 _: H5 t$ c神秘巨星:QmWBbKvLhVnkryKG6F5YdkcnoVahwD7Qi3CeJeZgM6Tq68
7 h1 n" l Z; z$ w9 h+ r盗梦空间:QmQATmpxXvSiQgt9c9idz9k3S3gQnh7wYj4DbdMQ9VGyLh9 @3 R6 p$ D$ Q
2、IPFS的安装既然IPFS这么牛,有必要了解一下IPFS的开发,先从IPFS的安装开始。, M: I7 O8 q5 M
- IPFS Desktop% \2 |* C0 e/ U- {, N o( R+ k0 d
当然,可以直接安装IPFS节点桌面管理软件来体验一下。该软件可以方便地运行和管理自己的节点,查看IPFS节点资源信息,支持二次开发。该项目是Node.js编写的,已开源。
- }8 i" k% `5 ^9 L* A* O6 k& L# z9 Z9 W+ a( Q. `6 |3 O
, O6 B9 j5 r, ]& \; I# t# @+ p
0 T' D) d8 f6 m: l [
3 R1 K3 u7 |1 o& c fIPFS节点桌面管理软件- e2 W) t6 ~5 p8 C
' A( [5 ^- O* o+ K0 K2 b2 ]
GitHub地址:
. m+ b5 z N4 ]2 u3 Nhttps://github.com/ipfs-shipyard/ipfs-desktop
( ?4 @4 k f$ F1 m: v$ I; v: f - Go-IPFS: C0 m; `3 C/ \4 K
进入IPFS的官网,找到并切换到"Install"页面,点击"Download IPFS for your platform",会跳转到如下网址(需要翻墙): x9 U. l: v! K3 c `. R- @) b
https://dist.ipfs.io/#go-ipfs
3 g$ S" n8 ]. h7 D6 B; |) i$ D) k4 ]
* i6 D- G! {9 [" I! o/ W
v3 P& U' V4 s8 p
下载Go-IPFS7 @, U9 S; g2 \* t3 ~" i6 J& z
" r. S, j* y% E7 A如果打不开,可以试着去Github查看安装方法5 z$ l6 D# k; O Q- b) L
GitHub地址:https://github.com/ipfs/go-ipfs1 \' Y' _2 @. s; l' H, d
将网页下载好的文件解压出来,下载的是"go-ipfs_v0.4.13_darwin-amd64.tar.gz",解压出来的是go-ipfs文件夹,, o6 W+ }2 a! o% L o
然后打开终端,进入到go-ipfs文件夹根目录,复制ipfs文件到系统的bin目录,然后可以通过"ipfs version"来检查,操作如下:, \- V& @& J# u2 G. x3 d9 s4 s7 i
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- I3 a& J. T5 o
3、IPFS节点的创建、查看和启动以下是安装官网的Go-IPFS步骤下实验的
. W& c5 |' u% p5 v- 创建节点3 h: [. h7 N. a( q2 J, j$ Y y
进入到当前用户的根目录,并使用"ipfs init"命令创建节点,可以用"open ./"打开创建节点生成的".ipfs"目录。
/ w8 K- R: n$ t% I$ } ^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 ./
! b9 m6 i+ w; ?( A% t8 ^7 u1 {3 d : v6 v" G+ X$ J4 q) H5 ?$ B) t s- i
. S5 ?+ P6 `/ Y% P+ c
& }/ n" q+ T. uIPFS节点的创建 @( O5 d0 G( ?& {
' s1 N2 ]+ m% m& k
- 查看节点id
- V. k7 L; z, O) w- P9 }# 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默认存储空间5 ]2 c; Q- c, u* L1 |( e0 B
存储节点默认存储大小为10G,如果你想修改存储空间,可以修改config配置文件,找到StorageMax并修改" i; y* A9 x1 f: M# c# e" A
wenzildeiMac:~ wenzil$ export EDITOR=/usr/bin/vimwenzildeiMac:~ wenzil$ ipfs config edit 4 g) i1 x" ?4 V. q/ }# M
/ _4 b9 ?! y a7 o: X
/ W: {( C6 u3 I0 Q4 K5 ]7 z% Z* p X i修改IPFS默认存储空间/ }) ?7 |+ ?$ X; }, q
% w/ q1 ^$ A, \2 D% D) a - 启动和同步节点服务器
( h7 x- I2 P6 k执行"ipfs daemon"命令,可以同步节点数据到IPFS网络。# g, E. ?; R$ l; T
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 ready6 R7 f6 z. h+ W, D2 C+ S. O
4、IPFS运行体验- IPFS查看ReadMe
( B9 }4 m. R0 `! A可以回去查看执行"ipfs init"命令的时候,返回的内容。打开一个新的终端,操作如下:
. a* N+ K5 x9 [8 owenzildeiMac:~ 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管理界面
: r! |3 S4 u9 p0 u5 q% b( ^ LIPFS节点服务器启动后,可以用浏览器访问:http://localhost:5001/webui
& f' l; K3 \! F I有本地配置、节点连接、本地节点文件等信息,如图:
+ e5 z! J5 z& e! i( D
" \* q& K# H) Q. b* d4 R7 W
% d8 ?* u2 A& j' m s/ G1 e j
, |/ j% I1 H6 C+ }
8 l3 T/ G8 [5 ~* Z) B6 `- q4 Z6 o, ZIPFS的Web管理界面
, s: J$ T& w! G5 f& v$ ]) Z/ r( ?1 q2 ~9 T
8 ]& i' W* B; s$ A0 b) |# S1 Y( O( ~( N3 m; }, B: j4 r
5、设置跨域资源共享当我们在前端通过js接口操作ipfs时,会遇到跨域资源访问问题,可以在终端执行以下配置来解决:
( O" R3 {; a* Z, A7 m8 V6 M! xipfs 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节点- 新建文件
7 d; X5 @1 j# a- O9 lwenzildeiMac:ifps_test wenzil$ vi test.txtwenzildeiMac:ifps_test wenzil$ cat test.txt IPFS测试文件 - 添加文件到IPFS节点: k+ B. @6 r- t% I4 Y9 W p* L- E
wenzildeiMac:ifps_test wenzil$ ipfs add test.txt added QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab test.txt添加文件到IPFS节点后,返回了文件的哈希值
/ ~! L, s( m) R n; ]7 A* L - 查看IPFS节点的文件 x0 Z1 R! V6 p( e6 r3 o2 g: f6 E
wenzildeiMac:ifps_test wenzil$ ipfs cat QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbIPFS测试文件注意:此时的文件只是添加到了本地的IPFS节点,读取的是本地数据,可以通过如下网址查看。
! j: ?& d' F" k o( K1 F; vhttp://localhost:8080/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab4 q5 F- I. v2 Z; c& L
通过"ipfs daemon"命令启动节点服务器,会将本地节点文件同步到外网,同步成功后,这时就可以访问如下网址来查看(如果访问失败,试着翻墙看看)。 B z& f$ b8 ^2 s2 n
https://ipfs.io/ipfs/QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab
4 a9 y* D5 P7 Y9 z
1 G5 I0 g* C0 F7 H9 \- o( M# ~
& F! a& r: o$ d( c! D. s% v8 _3 c( Z& c5 w6 \5 H; K4 A
查看IPFS文件内容
3 o! U+ v$ _3 @
' M7 @# Z- T9 `- L如果访问成功的话,说明已经存储到IPFS网络中。目前IPFS网络暂未加入代币Filecoin机制,所以存储读取文件免费,速度也比较慢。+ U; C8 u0 `7 s
- 下载IPFS节点的文件
$ d6 |: e- w4 M0 y5 b3 a2 C& mwenzildeiMac:ifps_test wenzil$ ipfs get QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2AbSaving file(s) to QmSVKEwPBTzw5QLzGUE8oN8J1r4cadMeieSw4Co1ozm2Ab 25 B / 25 B [========================================================] 100.00% 0s查看当前目录,发现多了一个"QmSV..."的文件"! `& l, ~, R ~! g+ |0 |1 g
# l2 Y; Y3 e& o+ @8 j4 Q& S3 M7 N4 z+ S$ B
8 |3 K' S8 M/ ?5 Y4 D0 T
: E/ [& ]4 w/ S$ `9 n. K下载IPFS节点的文件
, v* D5 h4 U& g! G9 t% }" r! R5 \# W7 v) p
2 {5 P% t2 a+ ~1 Y/ F! ^ o/ S 6.2 创建文件夹存储文件- ipfs命令新建文件夹" |1 Y' U0 U5 V
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 /文件夹名"可以删除文件夹。4 x( U/ j2 B* Y+ T9 ~: c
& F. J9 `+ V1 N; c& `+ K7 J 6.3 IPFS上传文件夹- ipfs命令添加文件夹% s4 G5 U# [0 [' G. Z" t u/ ^* O2 s
先在本地创建一个文件夹和对应文件,如图:; a4 G( u6 }' [& ?
" ?; y, N1 f! `+ R. A6 B+ z
4 z& S$ @* K I; P: @; u
* |$ v- [) S3 U/ k3 t+ y
, ], W+ H b1 f5 k& u0 G本地创建文件夹及文件8 z/ w+ Y" | D: r: \9 ]. t7 N
s& s5 O# ~0 k
然后通过"ipfs add -r 文件夹"命令添加整个文件夹
d0 }5 D0 \3 R) ~" J4 k 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$ - 查看文件夹的文件内容
4 k4 K7 {) L" A: h; M8 ~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 p& J7 D0 V* b访问文件夹对应的IPFS地址:4 A+ K' C0 y$ I' Q: S6 r- @* g+ k
https://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj: B! i# r9 |* Q! E* Q
第一次访问的时候,需要同步数据到IPFS网络,等待时间有点久,慢到让你以为同步失败了。6 {( i ~ _! Z! I1 T9 R9 Q
" P1 Z6 R; w: C2 H" {4 E* C$ P5 L! z
/ G# l5 D" z6 M5 K" ?& j( c) `! t
5 S6 S* X+ p" o- M' c查看IPFS对应文件夹2 L b* v& Y1 P8 J# D* i/ I; s" I0 u
+ U* T" b7 \4 ]. j! _3 b+ x1 f访问文件夹对应的文件,如看到图片文件,访问ipfs网关:
7 n c: K: G5 J: uhttps://ipfs.io/ipfs/QmdSd3xxKcwuMugyLCiLWzaeZKDkuM39R2tzyF3kBFDoaj/portrait.jpeg" }: K G, ]# Q5 ^$ @ [5 }, b
, F: B( e6 g( U$ f/ h' x- A% m
) I; O7 ?: o* r1 ^! ?5 H- x! r4 s! V, K2 @5 I2 S
查看IPFS文件夹对应文件
+ C( q8 L/ `3 x6 B% }* O7 l' U- _+ {2 h: b
或者通过文件的Hash来访问,如访问txt文件的地址:! [5 ~% h0 Z6 ]5 O
https://ipfs.io/ipfs/QmPEWgwQEHD6qxm5cUivTEZ252T123DvQ5L6HyUDgViQvT
$ b) q# q+ M( z0 Y/ A; J. L2 c5 \0 m" H9 T
' t3 h# V e9 O2 x w$ Z" d6 r
; x7 o+ r" Q" [$ h0 F1 D1 o. l3 x+ x
通过文件Hash访问查看
$ D8 Z, K( t4 t) R2 j, [! d5 G; w5 l8 o5 a: g
$ W8 q* \/ Y _2 Q0 z
6.4 添加简单网页到IPFS节点- 网页效果和项目结构
& L8 [+ H3 I% ?% K5 T0 L实现一个简单的实时显示系统当前时间的网页,效果如图:+ [5 h4 P+ F1 t, y; K- E
+ H+ e; v1 [3 A5 l" }
S: W# c6 ^4 h
+ j/ p; K# z4 B8 S' e7 X
( i; b! Q v5 SIPFS添加简单网页
" U7 {! {" ]* x. V& l: B0 `5 Z
( x, X! m K. z# ?" p0 s4 w* N% A7 @工程结构如图:
" K6 o) y" ^% B: W4 H% K* H. m
9 I. K1 r. P5 Z
# Q- E# u* i& T1 z* A) {$ @+ F
! o# [2 \$ K, @& F+ y0 k/ U, a/ ^! U6 d; N, B% X: ?3 g
网页工程结构
. m; R* a! S3 c. B8 U8 B z; z1 S$ L: F0 l
2 b) d& M( ?9 u8 D, a; V% J
实现代码比较简单,这里就不贴代码了。% w9 z+ o! M0 t; X2 `
- ipfs命令添加文件夹$ y. Q* H: \! s1 Z1 K6 @% p
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"命令在新的终端窗口打开运行。
B; o% H, a' S; M$ xwenzildeiMac:~ 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对应文件
% _6 |7 |3 _6 U C浏览器访问ipfs网关:# M1 R9 Z7 V4 Z! y
https://ipfs.io/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD/5 s& Y$ K2 [% D, h- y" L' _
8 ^9 o$ a* @, Q M! H- ~! R1 r* C1 b
9 q2 l3 i5 s" ?+ L
4 I/ a% e( z1 W1 g& }1 P. V# w0 a9 W查看IPFS对应网页
2 e9 e7 ?7 u$ W& r1 l6 l3 Z9 B# Z
/ ^+ v7 N" g* s8 V7 w, H F3 m8 E( Y/ j" ~2 e h
6.5 IPNS绑定节点名- IPNS绑定节点操作& [ T0 b7 F- A+ K; N2 o
每次修改文件内容后,文件的哈希值就会发生变化。对于网站而言,发布后可能还需要做修改,这时需要IPNS绑定节点名。每次更新网站内容后,重新publish一次更新发布到IPNS即可。
$ H& Z! z \' p刚才的html根目录的哈希值是QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD,操作如下:0 T! U* X" r! U& I
wenzildeiMac:study wenzil$ ipfs name publish QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDDPublished to QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz: /ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 查看当前节点
7 ~5 w4 d8 B$ e( |+ t9 ~2 Q: [3 kwenzildeiMac: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"6 M9 v# |& x' ~( c
- 验证节点
8 y$ I) X! N: v$ |0 [1 r命令为:"ipfs name resolve 节点ID“
6 h9 d& d. x1 IwenzildeiMac:study wenzil$ ipfs name resolve QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/ipfs/QmeG6LKmEfF5s62cySE9ZnU8EifmU46CQTixipfzsZspDD - 访问IPNS对应文件
4 m: ^0 M& Y$ d8 o6 j8 ]( U0 _浏览器访问ipfs网关:/ q; o L$ [4 |! m+ ^7 j7 q# V7 a
https://ipfs.io/ipns/QmcXWJqPjCgr1wrReWu2zUT41E5FrrXp2uyyNZRr7jXXrz/8 u. F$ L9 y! A+ K$ O
8 g- T: ?% w) S+ {- O: H: L$ l
o6 J9 E+ B3 L" X6 y+ Z/ ~
5 b% S2 n2 w& r5 h! I/ r- x0 x' o J. t0 M1 v. v3 p% x
查看IPNS对应网页8 i- L# a3 \6 `7 Q$ [9 ?& K
0 @4 `! E- h& P f6 g
7、IPFS与以太坊DApp开发实战- IPFS与以太坊DApp结合的好处
- E" t) i. ~, J在以太坊平台上,往区块链写入数据需要花费以太币,调用智能合约执行每一行代码的时候,都需要一定量的gas交易费。区块链存储大数据成本很高,而且不合理。; I* D% Q' R1 B; P
可以先将文件存储到IPFS,然后得到文件的Hash存储到以太坊区块链中。读取文件的时候,从以太坊区块链中获取文件的Hash,再通过Hash来读取IPFS网络上的文件。
( i: M Q/ n% u. U7 R8 {! _$ |使用官方提供的ipfs-api,可以很方便地在代码中操作节点将数据上传到IPFS,或者通过Hash从IPFS读取数据。' Z/ F/ ?/ s" @* s
Truffle框架提供了快速搭建包含以太坊智能合约的React项目,可以通过"truffle unbox react"创建工程,然后安装ipfs-api依赖库。于是,可以在前端方便地调用IPFS的接口来读取、上传文件。. {% x6 n% E4 i# ~) S; h
truffle unbox react官网:
" M& c4 o$ Y0 H( ~. G0 ~- q: l$ \0 [, X4 ahttp://truffleframework.com/boxes/react4 }; ^' J$ j! t! \/ P
- IPFS与DApp开发实战
`& _8 w( e9 @8 ]6 E话不多说,开始进入实战开发。
* \4 O( a1 l# N% L. @$ k+ g7.1 安装Truffle unbox react新建一个空目录"ipfs_dapp",然后执行安装命令
N7 b: T7 n( L. _' K3 O+ Xtruffle 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",修改后完整代码:
- F/ u) T9 N1 G* d2 k5 h! xpragma 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"; y' J6 l6 |. n/ v$ e B& z' N
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"进行智能合约的部署
/ H( f+ Z# F- [3 ?! {; D9 }0 Q* A
% }7 x; Q6 r4 Y- Z a- v0 }0 f8 W# e
Remix-IDE部署智能合约
' G F/ }' R( f- {1 [6 t& E& O# h& s$ q, T, n! k2 e% N
* r# |0 T- d0 t) i
* e8 l) e1 `4 h7 y7 y& B0 w- h0 ~8 i+ k
Remix-IDE部署智能合约-确认 ~3 H* |; @! U1 S* M
7 [4 a, }3 A T: [0 N& H* H
然后复制智能合约地址,App.js文件中会用到合约地址为:"0xb177d6cf6916f128c9931e610c63208d9c5a40f3"
) {3 z4 q( L2 @! 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"命令,结果如图:
/ [" ^2 W) C/ k
5 | a8 m: t1 G2 | I/ g
$ d9 y7 Q0 [ n# q, jnpm_start1 n! V) S9 Z9 N8 X) g
5 u& `1 m3 f! h# j0 [+ e6 @
会自动打开网页,然后上传一张本地图片,之后点击"图片哈希写入区块链"按钮) B8 c9 H; X9 I; |5 }. w
) P) ~! M" ?8 l1 h
1 G- Z5 {& v4 p$ E* ?5 P
u3 O; t7 y; k6 U h& L运行结果1
: k8 s) ?* v/ t6 \ ^5 T
# U* k& n n: g: Q: `7 O& L* X最终效果如图:8 C9 v4 i/ ^8 o$ m' z$ \ Z7 b* F' s
1 A$ y; E: l) }
5 H) \4 D' @1 S! Q& }) D* t
% A6 @) d, V# h: @4 C, @( K. [: u' G. \ v2 H5 W' E9 M: f
运行结果0 E( y2 ^: T! l u: r3 ^2 ]4 R1 I% Q
6 o. g2 L' t, c0 ^- c
访问IPFS网关:( u( _/ Z$ S/ X+ |( L+ E9 W5 T
https://ipfs.io/ipfs/QmbHptfJfyuGAZxstFYgAVfz33cytR1seTD3ZabBSDd8997 @+ l6 @7 Y) Y- e
发现图片已经成功写入IPFS,如图:
. @, n/ C# X; m2 f: c7 N* ?4 @/ A. p4 P
9 V& Z, P7 f" Y0 ^ L* M) O
" ?0 g4 W, U$ k; y
/ A7 J# C( B K9 @8 ~6 n
运行结果34 [( }1 P9 J$ l* [' l2 ^" L
/ D! P8 {7 f J# G$ i' P) O
备注:本地IPFS网关端口默认为8080,我的电脑上端口冲突了,系统自动修改为8082。
`9 L2 l5 C9 v! p搞定,收工。3 u# o. \: J4 l4 I+ d. q* v/ \: V
PS:刚入坑的小白,很多不懂,还请各位大佬多赐教,谢谢!
$ C6 V w# G9 p" M H7 s1 D: ]2 T
- c& v4 b. V$ j3 g" T
|
|