〇、IPFS介绍
从HTTP到IPFS,星际文件系统能变革信息传播的方式吗?
戴嘉乐:详解IPFS的本质、技术架构以及应用
以下为实现相关摘要
1.存储
在IPFS中,信息可以存储进IPFS系统中的块(block)里,这些块可以存储至多256kb的数据,它们还可以链接其他IPFS块。也就是说,存储小于256kb的文件时,只需将这个文件放进一个块内就可以了。而大于256kb的文件会被分成多个256kb然后放进块中,之后IPFS将创建一个空块,该块将链接到文件的所有其他部分。这个空块就类似于一个大信封,里面会涵盖整个文件的所有部分。
系统会给同一个文件的每一个块计算一次哈希值a,所有块的哈希值a计算完毕之后,会将所有的哈希值a拼凑成一个数组b,再计算一次哈希值,从而得到最终的哈希值c。最后把最终的哈希值c和原文件捆绑起来,组成一个对象,从而形成一个索引结构d。把块和最终的索引结构d上传至IPFS节点,文件便同步到网络了。
此外,还有一种小于1kb的小文件,如果这些小文件也单独放进一个块里的话,也会造成一定的浪费。于是,IPFS把小于1kb的数据内容直接和哈希索引放在一起上传给IPFS节点,不会再额外的占用一个块。
可见IPFS的创作理念,是尽可能少的使用存储空间,尽量分散的存储文件。另外,对于相同的文件,IPFS只创建一个文件夹,系统也会自动删除重复的文件,并修改的版本历史记录,这样可以大大节省存储空间,保证整个系统的运行速度,并保证存储文件的安全,和使用的便捷。
2.读取
同样作为信息价值交换的基础,用户在IPFS上传或者使用文件时,不再是基于位置的寻址(Location based addressing),而是基于内容的寻址(Content based addressing)。也就是把“去哪找信息”的指令换成“想找什么内容”的指令。
在互联网内,下载文件或者浏览信息需要一个IP地址或者域名,而在IPFS内,每个文件都有自己的哈希值,并且一个哈希值只对应一个文件。不存在一个文件有多个哈希值,或者多个哈希值对应同一个文件的问题。因而,用户只需在IPFS内输入需要文件的哈希值,系统就会出现对应的文件。这些文件是分布存储的,所以只要有一个用户有对应的文件,就算部分节点罢工或者不在线,也不会影响文件的读取。
具体在IPFS系统种下载文件时,首先,需要矿工根据最终哈希数值搜索该哈希的索引结构,并下载下来。然后,用户就可以根据哈希索引搜索到文件所在的节点位置。用户将节点上的块下载下来之后,IPFS将根据哈希数组的顺序,把文件重新组合出来,用户就可以使用了。
可以看出,IPFS将文件细分,使上传略显复杂,其目的是使用户在下载时更加便捷。毕竟,小文件的下载比大文件来得更加简单方便。
缺点
1)信息不可撤销、不可篡改是IPFS的优点,但是,如果是一个需操作的文件,或者说是内容错误、信息需要更新的文件,那么不可撤销、不可更改将会成为一个很麻烦的事情。
对此,IPFS给出的对应措施是:可以将修改之后的文件上传至IPFS,IPFS也会对文件进行更新,在IPFS内可搜索到文件更新的所有历史纪录。
2)IPFS将大文件分别存放于不同的块中,也不可避免的有一个隐患,即:如果一部分存放文件的节点统统下线不可用了,并且该文件没有备份,那么整个文件都是不可用的。
对此,有两种解决方案,一是激励更多的节点去存储这个信息,二是积极分发文件,使得更多节点存储这个信息。
IPFS的架构
IPFS至少有八层子协议栈,从上至下为身份、网络、路由、交换、对象、文件、命名、应用,每个协议栈各司其职,又互相搭配。
身份层和路由层可以一起解释。对等节点身份信息的生成以及路由规则是通过Kademlia协议生成制定,KAD协议实质是构建了一个分布式松散Hash表,简称DHT,每个加入这个DHT网络的人都要生成自己的身份信息,然后才能通过这个身份信息去负责存储这个网络里的资源信息和其他成员的联系信息。如同微信名片分享,在无法通过直接搜索微信号的情况下,如果你要找一个人,可以通过有这个人联系方式的朋友分享名片来建立联系。
网络层比较核心,使用的LibP2P可以支持任意传输层协议。NAT技术能让内网中的设备共用同一个外网IP,我们都体验过的家庭路由器就是这个原理。
交换层,是类似迅雷这样的BT工具。迅雷其实是模拟了P2P网络,并创建中心服务器,当服务器登记用户请求资源时,让请求同样资源的用户形成一个小集群swarm,在这里分享数据。这种方式有弊端,一位服务器是由迅雷统一维护,如果出现了故障、宕机时,下载操作无法进行。
中心化服务还可以限制一些下载请求,人们发明了一种更聪明的方式就是Bittorrent,让每一个种子节点所要存储的数据,通过哈希表存储在里面,BT工具相对不太受监管,服务更加稳定。
IPFS团队把BitTorrent进行了创新,叫作Bitswap,它增加了信用和帐单体系来激励节点去分享,我推断FileCoin有很大概率是基于Bitswap,用户在Bitswap里增加数据会增加信用分,分享得越多信用分越高。如果用户只去检索数据而不存数据,信用分会越来越低,其它节点会在嵌入连接时优先选择信用分高的。
这一设计可以解决女巫攻击,信用分不可能靠机器刷去提高,一直刷检索请求,信用分越刷越低。请求次数和存储量的变量之间有一个比较精妙的算法,类似一个抛物线,前期可以容忍很多东西,达到一定次数后不再信任。
对象层和文件层适合结合来谈,它们管理的是IPFS上80%的数据结构,大部分数据对象都是以MerkleDag的结构存在,这为内容寻址和去重提供了便利。文件层是一个新的数据结构,和DAG并列,采用Git一样的数据结构来支持版本快照。
命名层具有自我验证的特性(当其他用户获取该对象时,使用指纹公钥进行验签,即验证所用的公钥是否与NodeId匹配,这验证了用户发布对象的真实性,同时也获取到了可变状态),并且加入了IPNS这个巧妙的设计来使得加密后的DAG对象名可定义,增强可阅读性。
最后是应用层,IPFS核心价值就在于上面运行的应用程序,我们可以利用它类似CDN的功能,在成本很低的带宽下,去获得想要的数据,从而提升整个应用程序的效率。
新的技术取代老的技术,无非就两点:第一,能提高系统效率;第二,能够降低系统成本。IPFS把这两点都做到了。
我整理了一个IPFS族谱关系图,同时也是一个纵向数据流图。刚才所说的八层协议,其实每一层的实现都绑定在对应的模块下,进行了一个直观的图表设计。
IPFS的团队在开发时,采用高度模块集成化的方式,像搭积木一样去开发整个项目。协议实验室团队2015年创立,到17年的时间里都在做IPLD、LibP2P、Multiformats这三个模块的开发,它们服务于IPFS底层。
Mutiformats是一系列hash加密算法和自描述方式(从值上就可以知道值是如何生成)的集合,它具有SHA1\SHA256 \SHA512\Blake3B等6种主流的加密方式,用以加密和描述nodeID以及指纹数据的生成。
LibP2P是IPFS核心中的核心,面对各式各样的传输层协议以及复杂的网络设备,它可以帮助开发者迅速建立一个可用P2P网络层,快速且节约成本,这也是为什么IPFS技术被众多区块链项目青睐的缘由。
IPLD其实是一个转换中间件,将现有的异构数据结构统一成一种格式,方便不同系统之间的数据交换和互操作。现在IPLD支持的数据结构,是比特币、以太坊的区块数据,也支持IPFS和IPLD。这也是IPFS为什么受到区块链系统欢迎的原因之二,它的IPLD中间件可以把不同的区块结构统一成一个标准进行传递,为开发者提供了成功性比较高的标准,不用担心性能、稳定和bug。
IPFS应用了这几个模块的功能,集成为一种容器化的应用程序,运行在独立节点上,以Web服务的形式,供大家使用访问。
最后是Filecoin, 作为去年7月才宣布的项目,它的开发进度至今保密。Filecoin把这些应用的数据价值化,通过类似比特币的激励政策和经济模型,让更多的人去创建节点,去让更多的人使用IPFS。
我更希望大家把IPFS和FileCoin分开来看,如果IPFS玩得好,可以创建很多FileCoin项目出来,它本身的价值和意义没有IPFS这么大。
IPFS的应用意义
第一,可以为内容创作带来一定的自由。Akasha是一个典型的应用,它是一个基于以太坊和IPFS的社交博客创作平台,用户创作的博客内容通过一个IPFS网络进行发布,而非中心服务器。
同时,用户和以太坊钱包账户进行绑定,用户可以对优质内容进行ETH打赏,内容创作者能以此赚取ETH,如同人脑挖矿一样。它没有太多监管的限制,也没有中间商抽成,内容收益直接归创作者所有。
第二,可以降低存储和带宽成本。我之前也举过爱奇艺的例子,而做视频比较成功的项目叫「Dtube」。它是一个搭建在Steemit上的去中心化视频播放平台,其用户上传的视频文件都经过IPFS协议进行存储,具有唯一标识。相较于传统视频网站,它降低了同资源冗余程度,同时大大节约了海量用户在播放视频时所产生的带宽成本。
第三个,可以与区块链完美结合。区块链的本质是分布式账本,本身的瓶颈之一就是账本的存储能力,目前大部分公链的最大问题是没法存储大量的超媒体数据在自己的链上。比特币至今全部的区块数据也才30-40G左右,以太坊这样可编程的区块链项目也只能执行和存储小段合约代码,DApp想发展成超级App,受到了极大的限制。
运用IPFS技术解决存储瓶颈是目前来看的过渡方案,最典型的应用就是EOS。EOS引以为傲的是可以支持百万级别TPS的并发量,其中除了DPOS共识机制的功劳之外,还归功于其底层存储设计是采取IPFS来解决大型数据的传输效率。
EOS将自己打包好的区块数据通过IPLD进行异构处理,统一成一种便于内容寻址的数据结构类型,并挂载到IPFS的link上,让IPFS网络承担存储和P2P检索的逻辑,而不消耗EOS区块链系统本身太多的计算资源。
第四,可以为传统应用提供分布式缓存方案。 IPFS-GEO 是我自己之前写的,它是一个为传统LBS应用提供分布式缓存的项目,可以将地理位置坐标数据通过GeoHash算法转化成一维字符串,并将与之相关联的具有检索价值的数据存入IPFS网络,由IPFS网络标识唯一性,并分布在各个邻近节点上。
当检索请求到来时,系统先通过字符串近似度范围比较,缩小检索范围,加快检索效率,通过NodeID从附近节点拿到超媒体数据,达到类似分布式缓存的效果,大大提高了LBS应用整个检索动作的效率。
IPFS的明星应用
OpenBazaar是IPFS上的一个明星应用,我给它取了一个中文名叫开放集市,前一段时间刚拿到比特大陆500万美元的投资。
在之前的1.0版本,OpenBazaar被称之为黑市,那时没有应用IPFS,利用ZeroMQ来实现P2P交易,一定程度也绕过了中心化的检查,把交易的手续费作为红利给到用户。同时它整合了比特币作为支付渠道,轰动一时,用户数量在短时间内迅速提升。
开放集市在2.0版本发布之后,考虑到法律等因素,官方加入了一层审查机制,同时支持了比特币之外的BCH等数字货币,并且整合和重构IPFS,取代了之前的ZeroMQ。
现在,众多开放集市上的商店在没有用户上线的情况下,也可以在主机上就被运行。以前必须同时登陆才可以交易,现在利用IPFS相当于实现了离线店铺。这同时意味着,访问你的店铺的人越多,店铺数据被复制越多,有利于优质的店铺宣传和推广,这是一定意义上的价值回归。
我把它称为明星项目,不光因为它是基于IPFS而且做得不错,还因为它对IPFS全部的重构,它把IPFS所有的源码、协议和各种配套设施都重新开,不仅重构了IPFS的分支,改了协议名,同时也更改了协议头,一定意义上把OB的网络和主的IPFS网络隔离开。
OpenBazaar希望有更集中化的控制,想建立自己的矿场和机房来保证服务的稳定,在去中心和中心化之间选择了一个中间点。我觉得目前大部分的传统应用和公司,也可以这样去考虑。完全去中心化不太可能,所以可以取其精华、去其糟粕。
一、源码安装
go语言版本1.10以上进行编译
$go get -u -d github.com/ipfs/go-ipfs $cd github.com/ipfs/go-ipfs $ping ipfs.io #如果ping不通,执行下行代码 $echo "209.94.78.78 ipfs.io" >>/etc/hosts $make install
本人在docker环境下进行编译,生成的可执行文件ipfs在go/bin目录下,拷贝到其他镜像下同样可以使用。
二、使用-webui
初始化
$ipfs init 进行初始化
输出的信息
initializing IPFS node at /root/.ipfs #节点文件存放位置 generating 2048-bit RSA keypair...done #使用RSA生成信息 peer identity: QmTuHMnBv4c3iisH1BGyyuDwxxnF9Ce6X4CuDdXQsTKGc8 #节点id to get started, enter: ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme
启动文件服务
$ipfs daemon
输出信息
Initializing daemon... go-ipfs version: 0.4.18-dev-c96373e Repo version: 7 System version: amd64/linux Golang version: go1.10.1 Swarm listening on /ip4/127.0.0.1/tcp/4001 #默认 Swarm listening on /ip4/172.17.0.7/tcp/4001 #默认 Swarm listening on /ip6/::1/tcp/4001 #默认 Swarm listening on /p2p-circuit #默认 Swarm announcing /ip4/127.0.0.1/tcp/4001 #默认 Swarm announcing /ip4/172.17.0.7/tcp/4001 #默认 Swarm announcing /ip6/::1/tcp/4001 #默认 API server listening on /ip4/127.0.0.1/tcp/5001 #默认 可以通过ipfs config Addresses.API /ip4/127.0.0.1/tcp/5002修改,还有其他多种参数,ipfs daemon --help查看 Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080 #默认 Daemon is ready
chrome浏览输入http://172.17.0.8:5002/webui 可以登录查看,IP和端口根据自己配置,默认为172.0.0.1:5001 只能本地访问
可以使用如下命令进行配置
$ipfs config Addresses.API /ip4/127.0.0.1/tcp/5002