其他分享
首页 > 其他分享> > IPFS技术系列(二)-IPFS原理剖析

IPFS技术系列(二)-IPFS原理剖析

作者:互联网

前言

紧跟上文,今天我给大家介绍IPFS的相关原理


一、IPFS底层基础

  在这个部分,我主要向大家介绍IPFS的几个基础性的子系统和数据结构,包括DHT、BitTorrent、Git和自验证文件系统,以及Merkle结构。

1.分布式哈希表(DHT)

首先让我们来了解一下以前的文件网络系统的工作原理:
  第1代P2P文件网络主要依靠是一个中央数据库,这个数据库服务器接收所有的查询,服务器相应的向客户端返回其所需要的数据库地址列表。
缺点:这样的设计容易导致单点失效,更有甚者会导致整个网络瘫痪。
  第2代分布式文件系统中,Gnutella使用消息洪泛方法(message flooding) 来定位数据,查询消息会公布给全网所有的节点,直到找到这个消息,然后返回给查询者。
缺点:盲目的请求会导致网络快速耗尽,网络请求量非常大,容易造成拥堵。
  第3代分布式文件系统中,主要借助了 DHT(Distributed Hash Table),全网维护一个巨大的文件索引哈希表,形如<Key,Value>。这里的Key通常是文件中的某个哈希算法下的哈希值,Value则保存的是IP地址,通过提供Key就能从表中查询到存储节点的地址并返回给查询节点,极大的缩短了查询时间。
IPFS引用过有代表性的分区表类型有3种,分别是Kademlia DHT、 Coral DHT和S/Kademlia。

【Kademlia DHT】
KAD网络算法细节如下:
1.Kademlia 二叉状态树
首先Kademlia网络的节点ID是由一棵二叉树维护的。它具有以下特点:
1.每个网络节点从根节点出发,沿着它的最短唯一前缀到达。
2.每个网络节点都是叶子节点。
对于任意的一个树的节点,我们都可以沿着它的前缀作为路径,向下分解成一系列不包括自己的子树。
2.节点路由表K-Bucket
节点路由表用于保存每个节点与自己有一定距离范围内其他节点连接信息。每一条路由信息由如下3部分组成:IP Address、UDP port、Node ID。

【Coral DSHT】
  Coral DSHT是Coral CDN最核心的部件之一。Kademlia协议使用的是XOR距离,即信息永远是存储中XOR距离最近的节点。这样设计的特点很比较明显,它忽略了节点之间的延时及数据的位置等因素,浪费了大量的网络带宽和存储空间。Coral则采用不同的思想,它将所有的节点评估连接情况,然后根据循环时间划分几个等级,根据不同的等级查询键值对。
  Coral DSHT比较适用于软状态的键值对检索,也就是说同一个Key可能会保存多个Value。这种机制能把给定的Key映射到网络中的Coral服务器地址。
Coral DSHT 主要有以下几个特点:
1.索引机制和分层
2.基于键值对的路由层
3.Sloppy存储

【S/Kademlia DHT】
  Kademlia用于完全开放的P2P网络, 如果不提供任何安全措施, 它
很容易受到来自恶意节点发动的各类攻击。基于Kademlia协议,S/K协议在节点ID中加入隐式身份认证和兄弟广播。
S/K 能抵御常见的日蚀攻击(eclipse attack)和女巫攻击(Sybil attack)。

2.块交换协议(BitTorrent)

  BitTorrent 是一种内容分发协议,它采用内容分发和点对点技术,减少中心化服务器的负载。在BitTorrent网络里,每个用户需要同时上传和下载数据,用户之间相互转发自己所拥有的文件部分,直到每个用户的下载全部完成。

BitTorrent涉及的术语:
.torrent: 它是服务器接收的元数据文件(通常结尾是.Torrent),一般用来记录下载数据的信息
.tracker: 指互联网上负责协调BitTorrent客户端行动的服务器,用以帮助peers相互达成连接。
.peer: peer是互联网上的另一台可以连接并传输数据的服务器。peer之间相互下载、上传。
.seed:一个特定的torrent完整拷贝的计算机称为seedy。在初次发布时,实现初次共享。
.swarm:连接一个torrent的所有设备群组。
.Chocking:Chocking阻塞是一种临时拒绝上传策略,BitTorrent 需要每个peer相互上传,
对于不合作的peer,会采用临时阻断策略。
.Pareto效率:帕累托效率(Pareto efficiency) 指的是资源分配已经到了物尽其用的阶段。
.针锋相对:又叫一报还一报,在BitTorrent中表现为,Peer给自己贡献多少下载速度,那么也就相应贡献多少上传速度给他。
BitTorrent,是基于点对点的实现方式,它包括了内容发布,分块交换,片段选择算法等三个部分。

3.版本控制(Git)

  版本控制系统是用于记录一个或若干个文件内容变化,以便将来查阅特定版本修订情况的系统。实现版本控制的软件有很多,不过也大致也可以分为三类:本地版本控制系统,中心化版本控制系统,分布式版本控制系统。

【本地版本控制系统】
  这种方式就是我们常用的复制整个目录作为备份,有时也会加上备份时间或其他标识作为区分。后来有人开发了很多本地版本控制系统,采用某种简单的数据库来记录文件的历次更新差异。本地版本控制系统的缺点也比较明显,不能让不同系统上的开发者协同工作。

【中心化版本控制系统】
  这类系统,比较常见的有CVS、Subversion,他们都有一个单一的集中管理服务器,保存所有文件的修订版本,所有协同工作的人们都可以通过客户端连到这台服务器,取出最新的文件或提交更新。

【分布式版本控制系统】
  分布式版本控制系统避免了中心化版本控制系统单点故障的风险,比较常见的有Git、Mercurial等,它不只是提取最新版本的文件快照,而是把代码仓库完整镜像下来。任何一处协同工作服务器出现故障,都能用任何一个镜像出来的本地仓库恢复。

Git通常具有以下几个特点:

快照流: Git存储的是随时间改变的快照,也就是说每个人获取到的快照可能不一样。
本地执行操作: Git绝大多数操作只需要访问本地文件和资源。
只添加数据: 我们所有执行的Git操作,本质上在Git数据库中都是增加操作,并且所有的操作都是可逆的。
完整性校验: Git中所有数据在存储前都会计算校验和,然后以校验和来引用。
工作区与工作状态: Git的工作区包括工作目录、Git仓库及暂存区域。Git仓库又包括本地仓库和远程仓库。Git的工作状态包括已提交 (committed)、已修改(modified)和已暂存(staged)。
基本的Git工作流程 如下:
1.在工作目录中修改文件。
2.暂存文件,将文件的快照放入暂存区域。
3.提交更新,找到暂存区域的文件,将快照永久性存储到Git仓库。
分支: Git中的分支本质上仅是个指向commit对象的可变 指针。Git使用master作为分支的默认名字。主干可被克隆为其他分支,每条分支的可变指针在每次提交时都会自动向前移动。如下图:

4.自验证文件系统(SFS)

  自验证文件系统(Self-Certifying File System, SFS) 是为了设计一套整个互联网共用的文件系统,全球的SFS系统都在同一个命名空间下。
实现全球共享的文件系统,最大的问题在于如果让服务端为客户端提供认证。对于这个问题,SFS采用的是将公钥信息嵌入文件名中,这样做的好处在于不再需要文件系统内部实现秘钥管理,并且用户可以根据需求,自行选择需要的加密方式。

SFS核心思想有如下几点:
1.SFS文件系统具备自验证路径名称, 不需要在文件系统内部实现密
钥管理。
2.在SFS上易于架设各种密钥管理机制, 包括各类组合机制。
3.SFS将密钥管理与密钥分发解耦。
4.实现全球范围的文件系统。

5. Merkle DAG和Merkle Tree

【Merkle Tree】
Merkle Tree(默克尔树) 是一种树,大多数是二叉树,也可以是多叉树。它具有以下特点:
1.Merkle Tree的叶子节点的value是数据集合的单元数据或者单元数据Hash.
2.非叶子节点的value是根据它的下面所有的叶子节点值,按照哈希算法计算而得出的。

Merkle Tree的应用

数字签名: 最初默克尔树在于高效处理Lamport单次签名。在此之前每一个Lamport秘钥只能被用来签名一个消息,然而与默克尔树结合起来之后可以签名多个消息。

P2P: 在P2P网络中,默克尔树用来确保从其他节点接收的数据块没有损坏并且没有被替换,甚至检查其他节点不会欺骗或者发布虚假的块。
比特币: Merkle Proof最早的应用是Bitcoin(比特币),由中本聪创建。Bitcoin的BlcokChain利用Merkle proofs来存储每个区块的交易。这样的好处的在于简化支付验证。

【Merkle DAG】
Merkle DAG(默克尔有向无环图),它是在默克尔树的基础上的构建的。
Merkle DAG在功能上也和Merkle Tree有很不同。Merkle DAG主要有以下3个功能:
内容寻址: 使用多重Hash来唯一识别一个数据块的内容。
防篡改: 可以方便的检查Hash值来确认数据是否被篡改。
去重: 内容相同的数据库块的Hash值是相同的,很容易去掉重复的数据。

二、IPFS协议栈

  和HTTP类似,IPFS是基于TCP/IP的应用层协议。IPFS协议栈也是由七层负责不同功能的子协议构成。如下图所示:

1.身份层:管理节点身份生成和验证。
2.网络层:管理与其他节点的连接。
3.路由层:以DHT维护路由信息以定位特定的对等节点和对象,用以响应本地和远端节点发出的查询请求。
4.交换层:基于BitSwap(比特交换协议),模拟可信市场,弱化数据复制,防止作弊。
5.对象层:基于Merkle DAG ,具有内容寻址,防冗余等特性。
6.文件层:类似于Git的版本文件系统,支持blob,list,tree 等结构体。
7.命名层:具有自验特性的可变名称系统。
那么,下面我将对七层结构一一作介绍:

【身份层】
  在IPFS网络中,所有的节点通过唯一的NodeId进行标识,与比特币的地址类似,NodeId也是一个公钥的哈希。每个节点在IPFS代码中都由Node结构体来表示,其中只包含NodeId及一组公私钥对。

type NodeId Multihash
type Multihash []byte // 自描述加密哈希摘要
type PublicKey []byte
type PrivateKey []byte // 自描述的私钥
type Node struct {
NodeId NodeID
PubKey PublicKey
PriKey PrivateKey
}

身份系统的主要功能是标识IPFS网络中的节点。类似于用户信息的生成。在节点首次建立连接时,节点之间首先交换公钥,并且进行身份验证。

【网络层】
IPFS网络堆栈具有以下特点:
1.传输:IPFS兼容现有的主流传输协议,包含WebRTC DataChannels,uTP等传输协议。
2.可靠性:使用uTP和sctp来保障,用以动态调整网络状态。
3.可连接性:使用ICE来实现广域网的可连接性。
4.完整性:使用哈希校验检查数据完整性。IPFS网络中所有数据块都具有唯一的哈希值。
5.可验证性:使用数据发送者的公钥及HMAC消息认证码来检查消息的真实性。

【路由层】
IPFS路由层数据结构使用基于S/Kademlia和Coral技术的分布式松散
哈希表(DSHT),主要用于实现内容路由、节点路由及数据存储等三种基本功能。IPFS的DHT结构会根据所存储数据的大小进行区分:小的值直接存储在DHT上,一般不过1KB;更大的值,DHT只存储值索引,这个索引是一个NodeId。

【交换层】
  IPFS的交换层借助BitSwap协议,主要功能是利用信用机制在节点之间进行数据交换,并且每个节点在下载的同时不断向其他节点上传已下载的数据。在IPFS中,数据的分发和交换都是使用的BitSwap协议。
BitSwap协议主要负责两件事情:
1.向其他节点请求需要的数据块列表
2.为其他节点提供已有的数据块列表。

BitSwap数据交换的生命周期经历4个状态:
1.状态开发(Open):对等节点间开发待发送BitSwap账单状态,直到建立连接。
2.数据发送(Sending):节点间发送want_list和数据块。
3.连接关闭(Close):节点发送完数据后断开连接。
4.节点忽略:节点因为超时、自定义、信用分过低等因素被忽略。

【对象层】
  IPFS对象层主要是使用Merkle DAG技术构建了一个有向无环图数据结构,用来存储对象数据。
Merkle DAG 为 IPFS提供了一些比较有用的属性,包括:
1.内容寻址:所有内容由多重哈希校验并唯一标识。
2.防止篡改:在IPFS网络中如果数据被篡改或损坏,可以通过哈希验证检测到。
3.重复数据删除:保存完全相同内容的所有对象都是相同的,并且只存储一次。

【文件层】
   IPFS还定义了一组对象,用于在Merkle DAG之上对版本文件系统进行建模。
1.块(block):一个可变大小的数据块。
2.列表(list):一个块或者其他列表的集合。
3.树(tree):块、列表或其他树的集合
4.提交(commit):树版本历史记录中的快照。

【命名层】
  在命名层,协议实验室团队为IPFS设计了IPNS星际文件命令系统模块。
在其中采用的是自验证命名的方式。该模式如下:
1.通过NodeId =hash(node.Pubkey),生成IPFS节点信息
2.给每个用户分配一个可变的命名空间,由之前的生成的节点ID信息作为地址名称,在此路径下:/ipns/。
3.一个用户可以在此路径下发布一个用自己私钥签名的对象。
比如:/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/
4.当其他用户获取对象时,可以检测签名是否与公钥和节点信息相匹配,从而验证用户发布对象的真实性。

另外,IPFS还使用了一些技术,用来增加IPNS的用户友好度。
1.对等节点链接
用户可以将其他用户节点的对象直接链接到自己的命名空间下。
2.DNS TXT IPNS记录
用户可以在现有的DNS系统中添加TXT记录,这样能通过域名访问IPFS网络中的文件对象。

#DNS TXT 记录
ipfs.benet.ai. TXT “ipfs=XLF2ipQ4jD3U …”
#表现为符号链接
ln -s /ipns/XLF2ipQ4jD3U /ipns/fs.benet.ai

IPFS也支持可读标识符Proquint, 可以将二进制编码翻译成可读文
件的方法

#proquint语句
/ipns/dahih-dolij-sozuk-vosah-luvar-fuluh
#分解为相应的形式
/ipns/KhAwNprxYVxKqpDZ

除此之外, IPFS还提供短地址的命名服务

#用户可以从下面获取一个link
/ipns/shorten.er/foobar
#然后放到自己的命名空间
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm

三、IPFS模块解析

  IPFS很多重要特性都是由3个工程模块库集成而来。这3个组件分别Multiformat(自描述格式协议库) 、libp2p(P2P网络协议模块库) 和IPLD(数据结构模型库),它们之间相互协同,同时也保持一定的独立性。

1. Multiformat

Multiformat 是IPFS中的自描述格式协议组件,它用以解决各种编程语言或数据类型难以详细区分的问题。它采用的方式是在数据上添加自描述的字段,只需要在字段上判断数据的属性即可。
Multi-Format目前支持以下5种协议:

1.Multi-hash

Multi-Hash具有一下特点:
1.Multi-Hash会提示用户,比如一些哈希值可能不再安全,有被破译的风险。
2.让更新哈希算法变得更加简单,更容易规范化哈希算法的类型和哈希值的长度。
3.绝大多数工具不再需要对哈希做任何检查。
Multi-Hash格式
Multi-Hash的格式保存了3类信息,分别是类型type、长度length和哈希值。命名格式为(type-length-value)

<Multi-Hash> ::= <type-哈希类型><长度><哈希值>

从Multi-Hash的格式可以看出,它为我们的使用带来了诸多好处。
1.拿到一个哈希值,可以通过这个值都前两字节判断出它得加密方式。
2.为以后更新系统的加密算法提供了便利。
3.不占用太多额外都空间。
Multi-Hash记录了100余中常见都哈希类型,这些哈希算法名称和十六进制编号可以通过表格查询

2.Multi-Base

  Multi-Base 是自描述基础编码协议,用来保存数据并描述该数据是如何编码的,它可以自由选择输入和输出的编码类型,其他程序也能通过该值获取到其编码类型。
Multi-Base的格式存有两类信息,分别是编码代号type和编码数据value,在这里它不需要定义长度,只需要1字节类区分各种类型。

<Multi-Base> ::= <type编码类型><编码内容>

Multi-Base的好处在于,使用者可以快速分辨出各类编码方式,并且能通过调用Multi-Base在各类编码方式中转换。
Multi-Base 也拥有自己的映射检索表。如下图:

3.Multi-Addr

  Multi-Addr 组建的目的在于把自描述的信息添加到地址数据中。Multi-Addr分为两个版本,一类是具有可读性的UTF-8编码的版本,用来向用户展示;另一类是十六进制版本,方便网络传输。
  Multi-Addr的格式也有两类信息,分别是地址类型代号type和编 码数据value,每个Multi-Addr都由type/value形式循环表示,形如:/地 址类型代号/地址/地址类型代号/地址

<UTF-8 Multi-Address> ::= /<UTF-8 type-地址类型>/<UTF-8地址>

Multi-Addr拥有如下的函数类型表,已经整合到Multi-Formasts中。

4.Multi-Codec

Multi-Codec是为了使得数据更加紧凑地自描述都编码解码器。
除了定义了Multi-Hash、 Multi-Addr、Multi-Base等数据类型以外,Multi-Codec还定义了JSON文 件类型、压缩类型、图片类型及IPLD。
Multi-Code的格式如下:

<Multi-Codec> ::= /<十六进制 type >/<数据内容>

Multi-Codec与前面几类Multi-Formats是相互兼容的,因为在设计Multi-Codec表格时,已经考虑避开了前面已经 占用的代码。
正如前面所说,Multi-Codec定义了多种类型的数据,包括原始数据、IPLD数据、区块链数据、序列化数据和其他一些Multi-Formats。
如下图:

5.Multi-Stream

Multi-Stream是自描述编码流协议,用于实现自描述的位串,其主要场景主要是在网络中传输。
Multi-Stream包含3个字段,分别为流长度、Multi-Codec类型和编码 数据本身,之间使用两个分隔符分隔开。
Multi-Stream格式如下:

<Multi-Codec> ::= <流长度length>/<Multi-Codec type>\n<编码数据>

2.libp2p

libp2p是IPFS协议栈工程实现中最为重要的模块
libp2p负责IPFS数据的网络通信、路由、交换等功能
  libp2p抽象集成了所有开发者基本都需要的一些工具属性功能。包括节点之间的链接复用; 节点信息之间的互相交换;指定中继节点;网络地址转换(NAT);分 布式哈希表(dht)寻址;消息往返时延(RTT)统计等。如下图:

在如图的属性功能中,协议实验室和开源社区的贡献者都做了一定的实现,并且规划了长远的目标。
如下图:

用途:
libp2p是一个专门为P2P应用而 设计的多模块、易扩展网络堆栈库,其应用场景主要集中于物联网、区 块链、分布式消息以及文件传输这几个方面。
1.物联网:如我们的熟知都安防场景,安防摄像头与手机之间建立直连连接,从而减轻中央服务器的带宽压力。
2.区块链:在区块链领域也有一些项目利用libp2p作为自己的底层服务。比如Filecoin和Polkadot(波卡链)项目。
在Filecoin的“区块数据同步”“文件传输”“节点查找”等方面都用到了libp2p。
3.分布式消息:分布式消息系统,可以不通过中心服务器的中转功能,直接在节点之间建立连接,用于消息的发送和接收。
4.传输文件:Filecoin和IPFS都是基于libp2p来进行数据传输的。

3.IPLD

IPLD是基于内容寻址的数据模型的抽象层,IPLD能够连接起各类 以内容寻址为主的数据结构,比如区块链数据、Git、BitTorrent等
【IPLD数据模型】
IPLD定义了3种数据类型:默克尔链接(Merkle-Links)、默克尔有向无环图(Merkle-DAG)和默克尔路径(Merkle-Paths)。
默克尔链接
默克尔链接主要有两个功能:
1.加密完整性验证 :用户可以通过对目标对象的哈希来测试数据 的完整性。
2.数据结构不可改变 :带有默克尔链接的数据结构在引用后不可 以改变。

【内容识别符(CID)】
CID是一种自描述的内容寻址标识符,它使用哈希来实现内容寻址。
CID目前有 两个版本,分别为CIDv0和CIDv1。CIDv0只适用于IPFS 默认的编码规则和加密算法。而CIDv1适应算法和编码规则大大增加。
1.CIDv1
CIDv1包含4个字段,分别为multibase类型前缀代码,cid版本号, multi-codec内容识别符,完整的multihash。
CIDv1格式如下:

<cidv1> ::= <multibase type><cid-版本号><multicodec><multihash>

2.CIDv0
CIDv0的定义方式和CIDv1是一样的。只不过CIDv0中,Multi-Base类型代号默认为Base58,CID版本 号默认为0,Multi-Codec默认Protobuf。

总结

以上就是对IPFS相关原理的介绍,包括IPFS的底层基础、IPFS相关协议栈以及IPFS的工程模块组成。

标签:IPFS,Git,系列,Multi,剖析,哈希,Merkle,节点
来源: https://blog.csdn.net/ggj89/article/details/122536383