IPFS - 内容寻址、版本化、P2P 文件系统

由于最近在工作中经常遇到一些技术点,因此本周的文章是一篇技术性比较强的科普文章,仅供大家参考。
摘要
星际文件系统 (IPFS) 是一个点对点分布式文件系统,旨在将所有计算设备与相同的文件系统连接起来。 在某些方面,IPFS 类似于 Web,但 IPFS 可以被视为单个 BitTorrent 群,在一个 Git 存储库中交换对象。 换句话说,IPFS 提供了一个高吞吐量的内容寻址块存储模型,具有内容寻址的超链接。 这形成了一个通用的默克尔DAG,这是一种数据结构,可以在其上构建版本化文件系统、区块链,甚至是永久网络。 IPFS 结合了分布式哈希表、激励区块交换和自认证命名空间。 IPFS 没有单点故障,节点之间不需要相互信任。
1、介绍
目前已经有许多尝试构建一个全球分布式文件系统。 一些系统取得了显着的成功,而另一些则完全失败了。
2、IPFS设计
IPFS包含七个在组成部分:
1、认证:管理节点身份生成和验证
2、网络:管理与其他对等点的连接,使用各种底层网络协议。 可配置。
3、路由:维护用于定位特定对等点和对象的信息。 响应本地和远程查询。 默认为 DHT,但可交换。
4、交换:一种管理高效区块分配的新型区块交换协议 (BitSwap)。 以市场为模型,弱激励数据复制。 贸易策略可互换。
5、对象:带有链接的内容寻址的不可变对象的 Merkle DAG。 用于表示任意数据结构,例如文件层次结构和通信系统。
6、文件:受 Git 启发的版本化文件系统层次结构。
7、命名:一个自我证明的可变名称系统。
2.1 认证
节点由 NodeId 标识,NodeId 是公钥的加密哈希,由 S/Kademlia 的静态加密拼凑创建。 节点存储它们的公钥和私钥(用密码加密)。 用户可以在每次启动时自由地建立一个“新”节点身份,尽管这会失去明显的网络收益。节点被激励保持不变。
在本文档中,散列和校验和特指数据的加密散列校验和。
在第一次连接时,对等方交换公钥,并检查:hash(other.Public Key) 是否等于 another.Node Id。 如果不是,则连接终止。
关于加密函数的注释。
IPFS 没有将系统锁定到一组特定的功能选择,而是倾向于自我描述的值。 散列摘要值以多散列格式存储,其中包括指定使用的散列函数的短标头和以字节为单位的摘要长度。 例子:
这允许系统 (a) 为用例选择最佳功能(例如,更强的安全性与更快的性能),以及 (b) 随着功能选择的变化而发展。 自描述值允许兼容地使用不同的参数选择。
2.2 网络
IPFS 节点定期与网络中的数百个其他节点通信,可能是通过互联网。 IPFS 网络堆栈特点:
- 传输:IPFS 可以使用任何传输协议,最适合 WebRTC DataChannels(用于浏览器连接)或 uTP(LEDBAT)。
- 可靠性:IPFS 可以在底层网络不提供的情况下提供可靠性,使用 uTP(LEDBAT)或 SCTP。
- 连通性:IPFS 还使用了 ICE NAT 穿越技术。
- 完整性:可选地使用哈希校验和检查消息的完整性。
- 真实性:可选择使用 HMAC 和发件人的公钥检查消息的真实性。
2.2.1 对等寻址注意事项
IPFS 可以使用任何网络; 它不依赖或假定对 IP 的访问。 这允许在覆盖网络中使用 IPFS。 IPFS 将地址存储为 multiaddr 格式的字节字符串,供底层网络使用。 multiaddr 提供了一种表达地址及其协议的方法,包括对封装的支持。 例如:
an SCTP/IPv4 connection
/ip4/10.20.30.40/sctp/1234/
an SCTP/IPv4 connection proxied over TCP/IPv4
/ip4/5.6.7.8/tcp/5678/ip4/1.2.3.4/sctp/1234/
2.3 路由
IPFS 节点需要一个路由系统,该系统可以找到 (a) 其他节点的网络地址和 (b) 可以为特定对象提供服务的节点。 IPFS 使用基于 S/Kademlia 和 Coral 的 DSHT 实现了这一点,并使用了之前讨论的属性。 IPFS 的对象大小和使用模式与 Coral 和 Mainline 类似,因此 IPFS DHT 根据大小区分存储的值。 小值(等于或小于 1KB)直接存储在 DHT 上。 对于较大的值,DHT 存储引用,即可以为块提供服务的节点的 NodeId。
type IPFSRouting interface {
FindPeer(node NodeId)
// gets a particular peer's network address
SetValue(key []bytes, value []bytes)
// stores a small metadata value in DHT
GetValue(key []bytes)
// retrieves small metadata value from DHT
ProvideValue(key Multihash)
// announces this node can serve a large value
FindValuePeers(key Multihash, min int)
// gets a number of peers serving a large value
}
注意:不同的用例将需要完全不同的路由系统(例如,宽网络中的 DHT,本地网络中的静态 HT)。 因此,IPFS 路由系统可以换成满足用户需求的系统。 只要满足上述界面,系统的其余部分将继续运行。
2.4 区块交换-BitSwap协议
在 IPFS 中,数据分发是通过使用受 BitTorrent 启发的协议 BitSwap 与对等方交换块来实现的。 与 BitTorrent 一样,BitSwap 对等方也在寻求获取一组区块 (want_list),并提供另一组区块作为交换提供 (have_list)。 与 BitTorrent 不同,BitSwap 不限于一个 Torrent 中的块。 BitSwap 作为一个持久的市场运行,节点可以在其中获取他们需要的块,而不管这些块属于什么部分。 这些块可能来自文件系统中完全不相关的文件。 节点聚集在一起在市场上进行易货交易。
虽然易货系统的概念意味着可以创建虚拟货币,但这将需要一个全球分类账来跟踪货币的所有权和转移。 这可以作为 BitSwap 策略来实现,并将在未来的论文中进行探讨。
在基本情况下,BitSwap 节点必须以块的形式相互提供直接价值。 当跨节点的块分布是互补的时,这很有效,这意味着它们拥有对方想要的东西。 通常,情况并非如此。 在某些情况下,节点必须为它们的块工作。 如果一个节点没有它的对等点想要的东西(或根本没有),它会寻找它的对等点想要的存储片,优先级低于节点想要的片。这激励节点缓存和传播稀有存储片,即使它们 对他们不直接感兴趣。
2.4.1 BitSwap信用
该协议还必须激励节点在不需要任何特别东西时进行播种,因为他们可能拥有其他人想要的区块。 因此,BitSwap 节点乐观地向其对等节点发送块,期望债务得到偿还。 但是必须防止水军(从不共享的免费加载节点)。 一个简单的类信用系统解决了这个问题:
- Peers 跟踪他们与其他节点的余额(以字节为单位)。
- 根据随着债务增加而下降的函数,对等方有概率地向债务人对等方发送区块。
请注意,如果节点决定不向对等方发送数据,则该节点随后会在 ignore_cooldown 超时时间内忽略对等方。 这可以防止发件人试图通过引发更多掷骰子来玩弄概率。 (默认 BitSwap 为 10 秒)。
2.4.2 BitSwap策略
BitSwap 对等方可能采用的不同策略对整个交易所的性能产生截然不同的影响。 在 BitTorrent 中,虽然指定了标准策略(tit-for-tat),但已经实施了其他各种策略,从 BitTyrant [8](尽可能少地共享)到 BitThief(利用漏洞并且从不共享), 到 PropShare(按比例分享)。 BitSwap 节点可以类似地实施一系列策略(好的和恶意的)。 那么,功能的选择应该旨在:
- 最大化节点和整个交易所的交易性能
- 防止贪心的人利用和破坏交易所
- 对其他未知策略有效并具有抵抗力
- 对信任的peers要宽容
对此类策略空间的探索是未来的工作。 一种在实践中起作用的函数选择是S型,由 债务值 控制:

给定 r,让发送给债务人的概率为:

正如您在图 1 中看到的那样,当节点的债务比率超过既定信用的两倍时,该函数会迅速下降。

负债率是衡量信任度的指标:对先前成功交换大量数据的节点之间的债务宽容,对未知、不受信任的节点无情。 这 (a) 为会创建大量新节点的攻击者提供了抵抗力(sybill 攻击),(b) 保护以前成功的贸易关系,即使其中一个节点暂时无法提供价值,以及 (c) 最终扼杀关系 已经恶化,直到他们好转。
节点可以自由地保留分类帐历史记录,尽管它不是正确操作所必需的。 只有当前的分类帐条目才有用。 节点也可以根据需要自由地垃圾收集分类帐,从不太有用的分类帐开始:旧的(对等点可能不再存在)和小的分类帐。
2.4.3 BitSwap账本
BitSwap 节点保持分类账记账与其他节点的转移。 这允许节点跟踪历史并避免篡改。 激活连接时,BitSwap 节点交换其分类帐信息。 如果不完全匹配,分类帐会从头开始重新初始化,从而失去应计的信用或债务。 恶意节点有可能故意“丢失”账本,希望清除债务。节点不太可能累积足够的债务以保证也失去累积的信任;但是伙伴节点可以自由地将其视为不当行为,并拒绝 交易。
2.4.4 BitSwap规格
BitSwap 节点遵循一个简单的协议。
对等连接的生命周期示意图:
- 开放:节点发送账本,直到他们同意。
2.发送:peers交换want_lists和blocks。 - 关闭:对等方停用连接。
- 忽略:(特殊)如果节点的策略避免发送,则忽略对等点(在超时期间)
2.5 对象默克尔 DAG
DHT 和 BitSwap 允许 IPFS 形成一个庞大的点对点系统,用于快速、稳健地存储和分发块。 在这些之上,IPFS 构建了一个 Merkle DAG,一个有向无环图,其中对象之间的链接是嵌入在源中的目标的加密哈希。这是 Git 数据结构的概括。 Merkle DAG 为 IPFS 提供了许多有用的属性,包括:
- 内容寻址:所有内容都由其多哈希校验和唯一标识,包括链接。
- 防篡改:所有内容都通过其校验和进行验证。 如果数据被篡改或损坏,IPFS 会检测到它。
- 去重:所有持有完全相同内容的对象都是相等的,并且只存储一次。 这对于索引对象(例如 git 树和提交)或数据的公共部分特别有用。
IPFS Merkle DAG 是一种极其灵活的数据存储方式。 唯一的要求是对象引用是 (a) 内容寻址,和 (b) 以上述格式编码。 IPFS 授予应用程序对数据领域的完全控制权; 应用程序可以使用他们选择的任何自定义数据格式,IPFS 可能无法理解。 单独的对象内链接表允许 IPFS:
- 列出对象中的所有对象引用。
- 解析字符串路径查找,例如 foo/bar/baz。 给定一个对象,IPFS 将第一个路径组件解析为对象链接表中的散列,获取第二个对象,并与下一个组件重复。 因此,无论数据格式如何,字符串路径都可以遍历 Merkle DAG。
- 递归解析所有引用的对象
原始数据字段和公共链接结构是在 IPFS 之上构建任意数据结构的必要组件。 虽然很容易看出 Git 对象模型是如何建立在这个 DAG 之上的,但请考虑以下其他潜在的数据结构:(a) 键值存储 (b) 传统关系数据库 (c) 关联数据三元组存储 (d) 关联文档 发布系统 (e) 链接通信平台 (f) 加密货币区块链。 这些都可以在 IPFS Merkle DAG 之上建模,这允许这些系统中的任何一个使用 IPFS 作为更复杂应用程序的传输协议。
2.6 文件
IPFS 还定义了一组对象,用于在 Merkle DAG 之上对版本化文件系统进行建模。这个对象模型类似于 Git 的:
- 块:一个可变大小的数据块。
- 列表:块或其他列表的集合。
- 树:块、列表或其他树的集合。
- commit:树的版本历史中的快照。
希望准确地使用 Git 对象格式,但不得不离开以介绍某些在分布式文件系统中有用的功能,即 (a) 快速大小查找(已将聚合字节大小添加到对象中),(b) 大文件重复数据删除(添加一个列表对象),以及(c)将提交嵌入到树中。但是,IPFS 文件对象与 Git 足够接近,可以在两者之间进行转换。此外,可以引入一组 Git 对象进行转换而不会丢失任何信息(unix 文件权限等)。
注意:下面的文件对象格式使用 JSON。请注意,该结构实际上是使用 protobufs 进行二进制编码的,尽管 ipfs 包括导入/导出到 JSON。
2.7 IPNS:命名和可变状态
到目前为止,IPFS 堆栈形成了一个点对点块交换,构建了一个内容寻址的对象 DAG。 它用于发布和检索不可变对象。 它甚至可以跟踪这些对象的版本历史。 但是,缺少一个关键组件:可变命名。 没有它,所有新内容的通信都必须在带外进行,发送 IPFS 链接。 所需要的是在同一路径上检索可变状态的某种方法。
值得说明一下为什么 :如果最终需要可变数据,我们努力建立一个不可变的 Merkle DAG。 考虑掉出 Merkle DAG 的 IPFS 属性:对象可以 (a) 通过它们的哈希检索,(b) 完整性检查,(c) 链接到其他对象,以及 (d) 无限缓存。 从某种意义上说:
对象是永久的
这些是高性能分布式系统的关键特性,其中数据在网络链接上移动的成本很高。 对象内容寻址构建的网络具有 (a) 显着的带宽优化,(b) 不受信任的内容服务,(c) 永久链接,以及 (d) 对任何对象及其引用进行完全永久备份的能力。
Merkle DAG(不可变的内容寻址对象)和 Naming(指向 Merkle DAG 的可变指针)实例化了许多成功的分布式系统中存在的二分法。 其中包括 Git 版本控制系统,具有不可变对象和可变引用; Plan9 是 UNIX 的分布式继承者,具有可变的 Fossil 和不可变的 Venti 文件系统。 LBFS 还使用可变索引和不可变块。
2.8 使用IPFS
IPFS 旨在以多种不同的方式使用。以下是我将要追求的一些用例:
- 作为挂载的全局文件系统,在 /ipfs 和 /ipns 下。
- 作为安装的个人同步文件夹,自动版本、发布和备份任何写入。
- 作为加密文件或数据共享系统。
- 作为所有软件的版本包管理器。
- 作为虚拟机的根文件系统。
- 作为 VM 的引导文件系统(在管理程序下)。
- 作为数据库:应用程序可以直接写入 Merkle DAG 数据模型,并获得 IPFS 提供的所有版本控制、缓存和分发。
- 作为链接(和加密)的通信平台。
- 作为大文件(无 SSL)的完整性检查 CDN。
- 作为加密CDN。
- 在网页上,作为网络 CDN。
- 作为一个新的永久网站,链接不会消失。
IPFS 实现目标:
- (a) 要导入您自己的应用程序的 IPFS 库。
- (b) 直接操作对象的命令行工具。
- (c) 安装文件系统,使用 FUSE 或作为内核模块。
3、未来
IPFS 背后的理念是学术界和开源领域数十年成功的分布式系统研究的产物。 IPFS 综合了迄今为止最成功的系统中的许多最佳创意。 除了 BitSwap 是一种新颖的协议,IPFS 的主要贡献是这种系统的耦合和设计的综合。
IPFS 是新的去中心化互联网基础设施的雄心勃勃的愿景,可以在其上构建许多不同类型的应用程序。 至少,它可以用作全局的、挂载的、版本化的文件系统和命名空间,或者用作下一代文件共享系统。 在最好的情况下,它可以将网络推向新的视野,在这种情况下,发布有价值的信息不会强加给发布者,而是将其托管给感兴趣的人,用户可以信任他们收到的内容,而无需信任他们从中收到的同行,以及旧的 但重要的文件不会丢失。 IPFS 期待将我们带入永久网络。