# 新一代互联网底层协议——IPFS

By [W3.Hitchhiker](https://paragraph.com/@w3hitchhiker) · 2022-03-30

---

作者：Xiang｜W3.Hitchhiker

什么是IPFS
=======

为去中心化互联网(web3.0)提供动力

一种点对点超媒体协议，通过使网络可升级、弹性和更开放的方式保存与发展人类的知识。

IPFS 是一个分布式系统，用于存储和访问文件、网站、应用程序和数据。

HTTP
----

"IPFS"对标的是一个叫"HTTP"的东西，这你可能比较熟悉，当你上网打开百度搜索页面时，它所见即所得。

web的应用层协议是超文本传输协议（HTTP），它是传统web的核心。HTTP由两个程序实现：一个客户程序和一个服务器程序。客户程序和服务器程序运行在不同的端系统，通过交换HTTP进行会话。HTTP定义了这些数据的结构以及客户端和服务器进行交互的方式。

web页面是由对象组成的，一个对象只是一个文件，诸如一个HTML文件，一个JPEG图形，或一段小视频片这样的文件，且它们可以通过URL地址寻址。多数web页面含有一个html基本文件，以及几个引用对象。

HTTP定义了web客户向web服务器请求web页面的方式，以及服务器向客户传送web页面的方式。

而浏览器做的工作就是执行和解析HTTP协议与前端代码然后将内容展示出来，提交查询的时候通常是web端查询它的数据库然后将结果返回给请求方，也就是浏览器，然后浏览器展示出来。

HTTP协议的弊端
---------

我们现在使用互联网都是在http或https协议下运行的，http协议也就是超文本传输协议，是用于从万维网服务器传输超文本到本地浏览器的传送协议，从1990年提出至今已经32年了，他对于目前互联网的爆炸性成长居功至伟，成就了互联网的繁荣。

但是HTTP协议是基于C/S架构下的互联网通信协议，基于主干网络中心化运行的机制，也存在诸多弊端。

1.  互联网上的数据经常因为文件被删除或服务器关闭而永久被抹去。有人统计过目前互联网上的web页面平均保存寿命只有100天左右，我们经常看到一些网站出现"404错误"。
    
2.  主干网络运行效率低，使用成本高。使用HTTP协议每次需要从中心化的服务器下载完整的文件，速度慢、效率低。
    
3.  主干网络并发机制制约互联网访问速度。这种中心化主干网络的模式也导致在高并发情况下网络访问时候的拥堵。
    
4.  在现有的http协议下，所有的数据都保存在这些中心化服务器上，互联网巨头们不但对我们的数据有绝对的控制权和解释权，各种各样的监管、封锁、监控一定程度上也极大的限制了创新和发展。
    
5.  成本高，易被攻击，为了支撑HTTP协议，对于大流量公司，比如百度、腾讯、阿里等，投入大量资源维护服务器和安全隐患，防止DDoS等攻击。主干网络受制于战争，自然灾害，中心服务器宕机等因素，都可能造成整个互联网中断服务。
    

### IPFS的解决方案

1.  IPFS提供了文件的历史版本回溯功能，可以很容易的查看文件的历史版本, 且数据无法删除，可以得到永久保存。
    
2.  IPFS是基于内容寻址的存储模式，相同的文件都不会重复存储，它会把过剩的资源挤压下来，包括存储空间都释放出来，数据存储成本就会降低。如果改用P2P的方式下载，带宽使用成本可以节省近60%。
    
3.  IPFS是基于P2P网络，可以有多个源保存了数据，可以并发从多个节点下载数据。
    
4.  建立在去中心化的分布式网络上的IPFS很难被中心化管理和限制，互联网将更加开放。
    
5.  IPFS分布式存储可以极大的降低对中心主干网络的依赖。
    

言简意赅地说：

HTTP依赖中心化服务器，容易遭受攻击，访问量暴增服务器容易宕机，下载速度慢，存储成本高；

而IPFS是分布式节点，更加安全不易被DDoS攻击，不依赖主干网，降低存储成本且存储空间大，下载速度快还能查找文件历史版本记录，并且理论上能永久储存。

**新的技术取代老的技术，无非就两点：**

**第一，能提高系统效率；**

**第二，能够降低系统成本。**

**IPFS把这两点都做到了。**

![](https://storage.googleapis.com/papyrus_images/b91ec02c3819b60581daff7b09eb3f210a062bc2794c62c7593670f2e32d8597.png)

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好处

*   融合了Kademlia、BitTorrent、Git等理念的一种**超媒体分发协议**
    
*   避免了中心节点失效，无审查和管控的完全去中心化的**点到点传输网络**
    
*   **驶入互联网的明天**——新的浏览器已经默认支持IPFS协议（brave，opera），传统浏览器可以通过访问地址如`https://ipfs.io`等的公共IPFS网关，或者安装[IPFS 伴侣](https://github.com/ipfs-shipyard/ipfs-companion#ipfs-companion)扩展来访问储存在IPFS网络中的文件
    
*   **下一代内容分发网络CDN**——只需要在本地节点添加文件就可以使得全球都可以通过缓存友好的内容哈希地址和类BitTorrent网络带宽分发来获得文件
    
*   依托强大的开源社区为后盾，为构建[完整分布式应用和服务](https://awesome.ipfs.io/)的一个**开发者工具集**
    

IPFS把文件在系统中如何存储、索引和传输都定义好，也就是将上传好的文件转换成专门的数据格式进行存储，同时IPFS会将相同的文件进行了hash计算，确定其唯一的地址。所以无论在任何设备，任意地点，相同的文件都会指向相同的地址（不同于URL，这种地址是原生的，由加密算法保证的，你无法改变，也无需改变）。然后通过一个文件系统将网络中所有的设备连接起来，然后让存储在IPFS系统上的文件，在全世界任何一个地方快速获取，且不受防火墙的影响（无需网络代理）。所以从根本上说，IPFS能改变WEB内容的分发机制，使其完成去中心化。

IPFS工作原理
--------

IPFS 是一个点对点 (p2p) 存储网络。可以通过位于世界任何地方的节点访问内容，这些节点可能会传递信息、存储信息或两者兼而有之。IPFS 知道如何使用其内容地址，而不是其位置来查找您要求的内容。

理解 IPFS 的三个基本原则：

1.  **通过内容寻址的唯一标识**
    
2.  **通过有向无环图 (DAG) 进行内容链接**
    
3.  **通过分布式哈希表 (DHT) 发现内容**
    

这三个原则相互依赖，而打造的IPFS 生态系统。让我们从**内容寻址**和**内容的唯一标识**开始

### **内容寻址**和**内容的唯一标识**

IPFS 使用**内容寻址**来根据内容而不是位置来识别内容。按内容查找项目是每个人一直在做的事情。

比如你在图书馆找一本书，经常是按书名来找的；那是内容寻址，因为你在问它是什么。

如果你使用位置寻址来查找那本书，你会通过它的位置来找："我想要在二楼的书，第三个书架，第四层，从左边算起四本书。"

如果有人搬了那本书，那你就倒霉了！

互联网和您的计算机上都存在这个问题！现在，内容是按位置查找的，例如：

*   `https://en.wikipedia.org/wiki/Aardvark`
    
*   `/Users/Alice/Documents/term_paper.doc`
    
*   `C:\Users\Joe\My Documents\project_sprint_presentation.ppt`
    

相比之下，每条使用 IPFS 协议的内容都有一个\*[内容标识符](https://docs.ipfs.io/concepts/content-addressing/)\*，即 CID。哈希对于它所来自的内容来说是唯一的，即使它与原始内容相比可能看起来很短。

许多分布式系统通过哈希使用内容寻址，不仅可以识别内容，还可以将其链接在一起——从支持代码的提交到运行加密货币的区块链，一切都利用了这种策略。然而，这些系统中的底层数据结构不一定是可互操作的。

#### CID (Content Identifiers )

[CID 规范](https://github.com/multiformats/cid)起源于 IPFS，现在以多格式存在，并支持包括 IPFS、IPLD、libp2p 和 Filecoin 在内的广泛项目。尽管我们将在整个课程中分享一些 IPFS 示例，但本教程是关于 CID 本身的剖析，每个分布式信息系统都将其用作引用内容的核心标识符。

内容标识符或**CID**是一个自描述的内容寻址标识符。它并不表示内容存储\_在哪里\_，而是根据内容本身形成一种地址。CID 中的字符数取决于基础内容的**加密哈希**，而不是内容本身的大小。由于 IPFS 中的大多数内容都使用 哈希`sha2-256`，因此您遇到的大多数 CID 将具有相同的大小（256 位，相当于 32 字节）。这使它们更易于管理，尤其是在处理多条内容时。

例如，如果我们在 IPFS 网络上存储了土豚的图像，它的 CID 将如下所示： `QmcRD4wkPPi6dig81r5sLj9Zm1gDCL4zgpEj9CfuRrGbzF`

之前的演示过的uniswap的IPFS链接：

[

Uniswap Interface
-----------------

Swap or provide liquidity on the Uniswap Protocol

https://bafybeiagkgmmhux6fswdoedmwqqsvt5arjivl35wuk25jljb2yqgn7njgu.ipfs.dweb.link



](https://bafybeiagkgmmhux6fswdoedmwqqsvt5arjivl35wuk25jljb2yqgn7njgu.ipfs.dweb.link/)

创建 CID 的第一步是转换输入数据，使用**加密算法**将任意大小的输入（数据或文件）映射到固定大小的输出。这种转换称为**哈希数字指纹**或简称**哈希**（默认使用sha2-256）。

![](https://storage.googleapis.com/papyrus_images/be5c24bfc3bcd1553fa6a5207d731cf331d463ca43ce2cfab07cb47b4ee66398.png)

使用的**加密算法**必须生成具有以下特征的哈希值：

*   **确定性**：相同的输入应该总是产生相同的哈希。
    
*   **不相关**：输入数据中的一个小变化应该会产生一个完全不同的哈希。
    
*   **单向**：从哈希值中回推输入数据是不可行的。
    
*   **唯一性**：只有一个文件可以产生一个特定的哈希。
    

请注意，如果我们更改土豚图像中的单个像素，加密算法将为图像生成完全不同的哈希。

当我们使用内容地址获取数据时，我们可以保证看到该数据的预期版本。这与传统Web 上的位置寻址完全不同，在传统 Web 上，给定地址 (URL) 上的内容会随时间而变化。

![](https://storage.googleapis.com/papyrus_images/3a4c78344f9be89d189487852bb32515b8dae1a41f54bfa56d5defb7eea1e0bd.png)

#### CID的结构

![](https://storage.googleapis.com/papyrus_images/a8b2b7c7373ab7e75b1e0c2caff494f00da1e25203d4d2f2b6509193f79689af.png)

### Multiformats

Multiformats在IPFS体系中主要负责身份的加密和数据的自我描述。

Multiformats是未来安全系统的协议集合，自描述格式可以让系统可互相协作和升级。

**Multiformats**协议里面包含以下协议：

multihash - 自描述哈希

multiaddr - 自描述网络地址

multibase - 自描述基编码

multicodec - 自描述序列化

multistream - 自描述流网络协议

multigram (WIP) - 自描述分组网络协议

内容链接 **有向无环图**（DAG）
===================

Merkle DAG 继承了CID的可分配性。对 DAG 使用内容寻址会对它们的分发产生一些有趣的影响。首先，当然，任何拥有 DAG 的人都能够充当该 DAG 的提供者。第二个是当我们检索编码为 DAG 的数据时，比如文件目录，我们可以利用这一事实并行检索节点的所有子节点，可能来自许多不同的提供者！三是文件服务器不仅限于集中式数据中心，让我们的数据覆盖范围更广。最后，因为 DAG 中的每个节点都有自己的 CID，所以它所代表的 DAG 可以独立于它本身嵌入的任何 DAG 进行共享和检索。

### 可验证性

是否曾经备份了文件，然后在几个月后找到这两个文件或目录并想知道它们的内容是否相同？你可以为每个备份计算一个 Merkle DAG，而不需要费力地比较文件：如果根目录的 CID 匹配，就会知道哪些可以安全地删除，并释放硬盘驱动器上的一些空间！

### 可分配性

例如，一个大型数据的分发。在传统web网络上：

*   共享文件的开发人员负责维护服务器及其相关费用
    
*   同一台服务器很可能用于响应世界各地的请求
    
*   数据本身可以作为单个文件存档以单片方式分布
    
*   很难找到相同数据的替代供应者
    
*   数据可能是大块的，必须从单个供应者那串行下载
    
*   其他人很难共享数据
    

Merkle DAG 帮助我们缓解所有这些问题。通过将数据转换为内容寻址的 DAG：

*   任何想要的人都可以帮助收发文件
    
*   来自世界各地的节点都可以参与服务数据
    
*   DAG的每一部分都有自己的CID，可以独立分发
    
*   很容易找到相同数据的替代供应者
    
*   构成 DAG 的节点很小，可以从许多不同的供应者处并行下载
    

所有这些都有助于重要数据的可扩展性。

### 重复数据删除

例如，以浏览网页为例！当一个人使用浏览器访问网页时，浏览器必须先下载与该页面相关的资源，包括图像、文本和样式。其实许多网页实际上看起来非常相似，只是使用了相同主题其他只是略有变化。这里会产生很多冗余。

![](https://storage.googleapis.com/papyrus_images/661acc4fb9c7e03d703fc20067ceaf7e74a1febc8bc8f53e0c04809832e7f623.png)

当浏览器足够优化的时候，可以避免多次下载该组件。每当用户访问新网站时，浏览器只需下载其 DAG 中与不同部分相对应的节点，而之前已经下载了其他部分不需要再次下载！（想想 WordPress 主题、Bootstrap CSS 库或常见的 JavaScript 库）

**分布式哈希表 (DHT)**
----------------

分布式哈希表 (DHT) 是用于将键映射到值的分布式系统。在 IPFS 中，DHT 被用作内容路由系统的基本组件，并且充当目录和导航系统之间的交叉点。它将用户正在寻找的内容映射到存储匹配内容的peer节点。可以把它想象成一个巨大的表格，存储谁拥有什么数据。

Libp2p
------

[**libp2p**](https://libp2p.io/)**是一个模块化的网络堆栈，它从**[IPFS](https://ipfs.io/)演变为一个独立的项目。波卡也在用，eth2.0也在部分使用。

为了解释为什么 libp2p 是去中心化网络中如此重要的一部分，我们需要退后一步，了解它的来源。libp2p 的初始实现始于 IPFS，一个点对点文件共享系统。让我们从探索 IPFS 旨在解决的网络问题开始。

网络
--

网络是非常复杂的系统，有自己的规则和限制，因此在设计这些系统时，我们需要考虑很多情况和用例：

*   **防火墙**：您的笔记本电脑中可能安装了防火墙，阻止或限制特定连接。
    
*   **NAT**：您的家庭 WiFi 路由器，带有 NAT（网络地址转换），可将您笔记本电脑的本地 IP 地址转换为您家外的网络可以连接的单个 IP 地址。
    
*   **高延迟网络**：这些网络的连接速度非常慢，让用户等待很长时间才能看到他们的内容。
    
*   **可靠性**：世界各地分布着许多网络，而且很多用户经常遇到速度慢的网络，这些网络没有强大的系统来为用户提供良好的连接。连接频繁断开，用户的网络系统质量不佳，无法为用户提供应有的服务。
    
*   **漫游**：移动寻址是另一种情况，我们需要保证用户的设备在通过世界各地的不同网络导航时保持唯一可发现性。目前，它们在需要大量协调点和连接的分布式系统中工作，但最好的解决方案是去中心化的。
    
*   **审查制度**：在当前的网络状态下，如果您是政府实体，在特定网站域中屏蔽网站相对容易。这对于阻止非法活动很有用，但当一个专制政权想要剥夺其人口对资源的访问权时，就会成为一个问题。
    
*   **具有不同属性**的运行时：周围有许多类型的运行时，例如物联网（物联网）设备（Raspberry Pi、Arduino 等），它们正在获得大量采用。因为它们是用有限的资源构建的，所以它们的运行时通常使用不同的协议，这些协议对它们的运行时做出了很多假设。
    
*   **创新非常缓慢**：即使是拥有大量资源的最成功的公司也可能需要数十年的时间来开发和部署新协议。
    
*   **数据隐私**：消费者最近越来越担心越来越多不尊重用户隐私的公司。
    

### P2P协议当前问题

点对点 (P2P) 网络从互联网的概念中被设想为一种创建弹性网络的方式，即使peer节点由于重大的自然或人为灾难而与网络断开连接，该网络仍能正常工作，从而允许人们继续通信。

P2P 网络可用于各种用例，从视频通话（例如 Skype）到文件共享（例如 IPFS、Gnutella、KaZaA、eMule 和 BitTorrent）。

**基础概念**

**Peer** - 去中心化网络的参与者。peer节点是应用程序中同等特权、同等能力的参与者。在 IPFS 中，当您在笔记本电脑上加载 IPFS 桌面应用程序时，您的设备将成为去中心化网络 IPFS 中的Peer节点。

**Peer-to-Peer (P2P)** - 一个分散的网络，工作负载在peer节点之间共享。因此，在 IPFS 中，每个Peer节点都可能托管要与其他peer节点共享的全部或部分文件。当一个节点请求文件时，任何拥有这些文件块的节点都可以参与发送请求的文件。然后，请求数据的节点方可以稍后与其他节点方共享数据。

IPFS 在当前和过去的网络应用和研究中寻找灵感，尝试改进其 P2P 系统。学术界有大量的科学论文提供了如何解决其中一些问题的想法，但是虽然研究产生了初步结果，但它缺乏可以使用和调整的代码实现。

现有 P2P 系统的代码实现真的很难找到，而且在它们确实存在的地方，由于以下原因，它们通常难以重用或重新调整用途：

*   文件不佳或不存在
    
*   限制性许可或找不到许可
    
*   十多年前最后一次更新的非常旧的代码
    
*   没有联系点（没有维护人员可以联系）
    
*   闭源（私有）代码
    
*   已弃用的产品
    
*   未提供规格
    
*   没有暴露友好的 API
    
*   实现与特定用例的耦合过于紧密
    
*   无法使用未来的协议升级
    

必须有更好的方法。看到主要问题是互操作性，IPFS 团队设想了一种更好的方法来集成所有当前的解决方案并提供一个促进创新的平台。一种新的模块化系统，可以使未来的解决方案无缝集成到网络堆栈中。

libp2p 是 IPFS 的网络栈，但从 IPFS 中抽离出来，成为独立一流的项目和 IPFS 的依赖项目。

通过这种方式，libp2p 能够在不依赖于 IPFS 的情况下进一步发展，获得自己的生态系统和社区。IPFS 只是成为 libp2p 的众多用户之一。

这样，每个项目都可以只专注于自己的目标：

IPFS 更专注于内容寻址，即查找、获取和验证网络中的任何内容。 libp2p 更侧重于进程寻址，即查找、连接和验证网络中的任何数据传输进程。那么 libp2p 是如何做到的呢？

答案是：**模块化**。

![](https://storage.googleapis.com/papyrus_images/c6f8f3fc492d051010c4f8287268188bab570b3bed76cae7dc57bfcca9f6dc14.png)

libp2p 已经确定了可以构成网络堆栈的特定部分：

![](https://storage.googleapis.com/papyrus_images/8fa1d526fc81b7d057e7c397d87f1eea1e8b0583cb96d6536bebb7d3e4856deb.png)

多语言实现，支持7种开发语言，libp2p 的 JavaScript 实现也适用于浏览器和移动浏览器！这非常重要，因为它使应用程序也可以在桌面和移动设备上运行 libp2p。

![](https://storage.googleapis.com/papyrus_images/5bf4a20640f282aed117a100badaa1a0e3769ec7b45ab5bd486fa6cb39fc1f9a.png)

应用程序包括文件存储、视频流、加密钱包、开发工具和区块链。可以区块链顶流的项目都已经有采用IPFS的libp2p模块。

![](https://storage.googleapis.com/papyrus_images/70ed053f0868163b259dc7c631be904da5031b33d4852012b3f30956a8286429.png)

**IPLD**
--------

**IPLD 用于理解和处理数据。**

*   **IPLD是一个转换中间件，将现有的异构数据结构统一成一种格式，方便不同系统之间的数据交换和互操作，数据模型与解码，使用CID做为链接。**
    
    首先，我们定义了一个“数据模型”，它说明了数据的域和范围。这很重要，因为它是我们将要构建的一切的基础。 （广义地说，我们可以说数据模型“像 JSON”，像map、string、list等） 此后，我们定义了“编解码器”，它说明了如何从消息中解析它并作为我们想要的消息形式发出。 IPLD 有很多编解码器。您可以根据您希望与之交互的其他应用程序选择使用不同的编解码器，或者仅根据您自己的应用程序喜欢的性能与人类可读性的适合性来选择使用不同的编解码器。
    
    IPLD 实现了最上面的三层协议：**对象、文件、命名**。
    
    *   **对象层** - IPFS 中的数据以 Merkle Directed Acyclic Graph（Merkle DAG）的结构组织，节点称为对象，可以包含数据或指向其他对象的链接，链接是嵌入在源中的目标数据的加密哈希。这些数据结构提供了许多有用的属性，如内容寻址、数据防篡改、重复数据删除等；
        
    *   **文件层** - 为了在 Merkle DAG 之上建模一个类似 Git 的版本控制系统，IPFS 定义了如下的对象：
        
        *   blob 数据块：blob 是一个可变大小的数据块（无链接），代表一个数据块；
            
        *   list：用于有序地组织 blob 或其他 lists，通常代表一个文件；
            
        *   tree：代表目录并包含 blobs、lists 以及其他 trees；
            
        *   commit：类似于 Git 的提交，表示对象的版本历史记录中的快照；
            
    *   **命名层** - 由于对象的每次更改都会改变其哈希值，因此需要对哈希值做一个映射。IPNS（Inter Planetary 命名空间系统）为每个用户分配一个可变的命名空间，并且可以将对象发布到由用户私钥签名的路径，以验证对象的真实性。类似 URL。
        
    
    **对应IPLD的展示：**
    

![](https://storage.googleapis.com/papyrus_images/7b0e04b606c7cbd1a410a06c0679eb1e573f94cad613e15ebc85df9aa1255560.png)

**IPFS应用了以上个模块的功能，集成为一种容器化的应用程序，运行在独立节点上，以Web服务的形式，供大家使用访问**。IPFS允许网络中的参与者互相存储，索取和传输可验证的数据。但是由于IPFS是开源的，可以被免费下载和使用，并且已经被大量的团队使用。

Filecoin
--------

运用 IPFS 及技术各个节点可存储它们认为重要的数据；**但如果没有简单的方法，没有可以激励他人加入网络或存储数据，IPFS的推广难以展开，这时就需要并诞生了Filecoin，IPFS的激励层，证券化。**

Filecoin为 IPFS 添加了激励性的存储。IPFS 用户可以直接可靠地存储其数据在Filecoin上，从而为网络打开了众多应用程序和落地场景的大门。

---

*Originally published on [W3.Hitchhiker](https://paragraph.com/@w3hitchhiker/ipfs)*
