IPFS介绍
IPFS(InterPlanetary File System,翻译为“星际文件系统”)是一个面向全球的、点对点的分布式文件系统。其目标是为了补充(甚至是取代)目前统治互联网的超文本传输协议(HTTP),将所有具有相同文件系统的计算设备连接在一起,使数据的访问速度更快、更安全、更健壮、更持久。该开源项目由Juan Benet在2014年5月份发起。
IPFS网络特点:
1)互联网信息永久存储,不会发生404错误;
IPFS可以存储任何类型的文件。即使某一个节点把文件删除了,只要存储文件的网络依然存在,那么该网页就可以被正常访问。
2)解决资源冗余问题;
IPFS会把存储文件,做一次哈希计算,只有文件内容相同,它们的哈希才一样。因此,在IPFS网络上极大地减少资源冗余的问题,提高网络空间的利用率。
3)基于内容寻址;
IPFS的网络上运行着一条区块链,即用来存储互联网文件的哈希值表。一个文件上传到IPFS的网络中,IPFS系统就会对文件内容生成一个唯一的哈希值。如果要访问资源,直接通过该哈希值进行访问。
为了鼓励其他节点存储数据,IPFS使用代币(FileCoin)对存储数据的节点进行奖励。矿工为网络提供开放的硬盘空间获得了FileCoin,而用户则使用FileCoin支付在去中心化网络中储存加密文件的费用。
以太坊协议栈
与HTTP类似,IPFS也是基于TCP/IP的应用层协议。IPFS有八层子协议栈,从低往高分别为身份、网络、路由、交换、对象、文件、命名、应用,每个协议栈各司其职,又互相搭配。
身份层和路由层,对等节点身份信息的生成以及路由规则是通过Kademlia协议生成制定(后面简称KAD协议),KAD协议实质是构建了一个分布式的松散Hash表,简称DHT,每个加入这个DHT网络的人都要生成自己的身份信息,然后才能通过这个身份信息去负责存储这个网络里的资源信息和其他成员的联系信息。按照我自己的理解,这就是一个入网的令牌,拿着这个令牌就可以在DHT网络中确定自己的ID。
网络层,这个比较核心,使用的LibP2P可以支持任意传输层协议。NAT技术能让内网中的设备共用同一个外网IP,我们都体验过的家庭路由器就是这个原理。
交换层,是类似迅雷这样的BT工具。迅雷其实是模拟了P2P网络,并创建中心服务器,当服务器登记用户请求资源时,让请求同样资源的用户形成一个小集群swarm,在这里分享数据。这种方式有弊端,因为服务器是由迅雷统一维护,如果出现了故障、宕机时,下载操作无法进行。
对象层和文件层,它们管理的是IPFS上80%的数据结构,大部分数据对象都是以MerkleDag的结构存在,这为内容寻址和去重提供了便利。文件层是一个新的数据结构,和DAG并列,采用Git一样的数据结构来支持版本快照。
命名层,具有自我验证的特性(当其他用户获取该对象时,使用指纹公钥进行验签,即验证所用的公钥是否与NodeId匹配,这验证了用户发布对象的真实性,同时也获取到了可变状态),并且加入了IPNS这个巧妙的设计来使得加密后的DAG对象名可定义,增强可阅读性。
应用层,IPFS核心价值就在于上面运行的应用程序,我们可以利用它类似CDN的功能,在成本很低的带宽下,去获得想要的数据,从而提升整个应用程序的效率。
【资料来源:https://www.jianshu.com/p/04a48d9a3e35】
IPFS安装和初始化
官方下载地址:https://dist.ipfs.io/#go-ipfs
官方文档:https://ipfs.io/docs/getting-started/
如果官方地址打不开,可以在hosts文件中添加:
209.94.78.78 ipfs.io
209.94.90.1 ipfs.io
下载并安装完成后,执行初始化操作。初始化操作很简单,就是在命令行中执行init命令即可。
>> ipfs init
执行效果如下图所示:
初始化完成后,在C:\Users\zhongliwen路径下生成.ipfs目录。目录结果如下图所示:
其中,blocks目录存放区块相关的信息;config是ipfs的配置文件;keystore存放了账户相关的信息。
继续在控制台上输入命令查看ipfs帮助信息。
>> ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme
如果可以看到下面界面,代表您的ipfs已经安装成功了!!!
如果要查看ipfs的具体用法,可以执行./quickstart命令查看具体用法。
>> ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/quick-start
IPFS网络交互图示
在本地执行ipfs操作时候,所有数据都会存放在本地.ipfs目录下。
如果要让本地节点与ipfs网络交互,需要在本地启用ipfs服务。
>> ipfs daemon
启动服务后,可以在浏览器上(http://localhost:5001/webui)查看添加到文件数据。
如果只是使用api服务,那么可以执行ipfs daemon命令的时候指定offline参数。
>> ipfs daemon --offline
如果要使用web服务,由于web ui会自动与远程服务进行交互,所以,不能够指定–offline参数。
ipfs默认最大上传文件为10G,如果要改变存储容量,那么修改.ipfs目录下的config文件。
IPFS基本命令
(1)查看所有的IPFS命令
>> ipfs --help
(2)添加文件或文件夹到ipfs中
>> ipfs add 文件路径
添加完成后会返回该文件的哈希地址。如果两次添加的文件是一样,那么返回相同的哈希。如果是添加文件加,那么需要指定-r参数
>> ipfs add -r 文件夹
(3)查看文件
>> ipfs cat 文件的哈希
(4)查看文件夹
>> ipfs ls 文件夹哈希
>> ipfs refs 文件夹哈希
>> ipfs cat 文件夹哈希/文件名
(5)下载数据
>> ipfs get 文件哈希 -o 文件名
参数说明:
-o 指定下载的文件名
-a 下载后自动打包(tar格式)
-C 下载后自动打包(gz格式)
使用Web查看ipfs数据
首先启动ipfs服务
>> ipfs daemon --offline
打开浏览器,输入:http://localhost:8080/ipfs/文件哈希
浏览器显示效果如下图所示:
注意:如果访问web页面,启动ipfs服务的时候,不能够指定offline参数。
文件交互
指定files命令之后,可以使得ipfs上的操作如同unix文件系统一样,具体如下:
ipfs files mkdir - Make directories.
ipfs files cp - Copy files into mfs.
ipfs files flush [] - Flush a given path's data to disk.
ipfs files ls [] - List directories in the local mutable namespace.
ipfs files mv - Move files.
ipfs files read - Read a file in a given mfs.
ipfs files rm ... - Remove a file.
ipfs files stat - Display file status.
ipfs files write - Write to a mutable file in a given filesystem.
(1)创建文件目录
>> ipfs files mkdir /目录名
例如:
D:\code\go_workspace\src\ipfs-test>ipfs files mkdir /aabb
ipfs有一个虚拟的根目录 ‘/’。文件和目录的路径都必须要以“/”开头。创建成功后,可以在web ui上查看。
(2)查看web ui
启动daemon,然后在浏览器中输入如下url:http://localhost:5001/webui
这是一个ipfs浏览器,可以查看当前与自己链接的所有节点,添加文件,搜索文件,自己节点的状态等等,这些功能在命令行也可以实现,这里只是一个可视化的展示,方便不同人群使用。
(3)显示目录下的文件
>> ipfs files ls /目录名
例如:
D:\code\go_workspace\src\ipfs-test>ipfs files ls /aabb
1.txt
123.txt
(4)复制文件
>> ipfs files cp /ipfs/文件哈希 /目录名
例如:
D:\code\go_workspace\src\ipfs-test>ipfs add bb.txt
10 B / ? [------------------------------------------------------------------------------------------------=---------]
added QmZ6bkVgxPaGS49bpoKuwESaZAuj7f7SF3iAuqY3TfvxD5 bb.txt
D:\code\go_workspace\src\ipfs-test>ipfs files cp /ipfs/QmZ6bkVgxPaGS49bpoKuwESaZAuj7f7SF3iAuqY3TfvxD5 /aabb/bb.txt
(5)写文件
>> ipfs files write [-e] /文件路径 数据
例如:
#将当前目录下的1.txt文件中的数据写入到/aabb/444.txt文件中
D:\code\go_workspace\src\ipfs-test>ipfs files write -e /aabb/444.txt 1.txt
D:\code\go_workspace\src\ipfs-test>ipfs files write /aabb/555.txt 1.txt
Error: file does not exist
如果不加create参数,那么如果文件已经存在,那么就会覆盖文件内容。如果文件不存在则报错。
(6)读文件
>> ipfs files read /文件路径
例如:
D:\code\go_workspace\src\ipfs-test>ipfs files read /aabb/123.txt
hello aa
(7)查看文件状态
>> ipfs files stat /文件路径
例如:
D:\code\go_workspace\src\ipfs-test>ipfs files stat /aabb/123.txt
QmXSwJG6rS1n1XsVKfimuC6VQtARPxpYBnWEusmxfq7p6g
Size: 11
CumulativeSize: 69
ChildBlocks: 1
Type: file
(7)删除文件或目录
>> ipfs files rm /文件路径
>> ipfs files rm -r /目录路径
例如:
D:\code\go_workspace\src\ipfs-test>ipfs files rm /aabb/123.txt
D:\code\go_workspace\src\ipfs-test>ipfs files rm -r /aabb
发布和解析
在实际应用中,ipfs也应该把网页发布出去,用户可以网页的哈希进行访问。但是如果使用ipfs发布网页会存在一个问题:如果网页内容发生改变,那么网页的哈希也会随之发生变化。这时候,用户没有办法每次都使用新的哈希访问 。因此,ipfs使用ipns系统来发布和解析发布的文件。IPNS就好像网站的域名,无论网页内容发生任何变化,都不影响用户访问网站。
使用IPNS发布网页的步骤:
第一步:启动ipfs daemon服务,然后创建一个site文件夹和index.html文件;
>> ipfs daemon --offline
>> mkdir site
>> cd site
>> echo "<h1>Welcome to IPFS</h1>" > index.html
第二步:把site文件夹发布到ipfs,这里会生成一个哈希值;
>> ipfs add -r site
第三步:把当前ipfs节点的id与要发布网站的哈希进行绑定;
>> ipfs name publish 发布网站的哈希
>> ipfs id
例如:
D:\code\go_workspace\src\ipfs-test>ipfs name publish QmSeqXuyGEVZmFGfopAD4ugUFrkn8kjhX6YBAxRx5cA3nU
Published to Qmej6LkYiQVPxUD65gP4eaqyZoMjfF1r1FAjQZcw2kAUbG: /ipfs/QmSeqXuyGEVZmFGfopAD4ugUFrkn8kjhX6YBAxRx5cA3nU
第四步:用户使用节点id访问网站;
之前:http://localhost:8080/ipfs/发布网站的哈希
改为:http://localhost:8080/ipns/节点id
例如:
http://localhost:8080/ipns/Qmej6LkYiQVPxUD65gP4eaqyZoMjfF1r1FAjQZcw2kAUbG/
这样无论网站内容发生什么改变,由于节点id不会发生改变,所以不会影响到用户访问网站。
除此以外,我们还可以进行反向解析。就是查看当前节点绑定的网站哈希。
>> ipfs name resolve