libp2p概览

Introduction to libp2p

Why do we need libp2p?

libp2p 是一个模块化的网络堆栈,从 IPFS 演变为一个独立的项目。 为了解释为什么 libp2p 是去中心化网络中如此重要的一部分,我们需要退后几步,了解它的来源。 libp2p 的初始实现始于 IPFS(一种对等文件共享系统)内部。让我们从探索 IPFS 旨在解决的网络问题开始。

Web 2.0

我们越来越喜欢互联网,并将其用于日常生活的方方面面,例如学习、与朋友和家人联系、购物、管理财务等等。

我们已经变得依赖互联网,以至于我们真的需要它可靠和安全,但在当今时代,情况并非如此。我们都遇到过连接问题,我们也觉得我们的身份和数据在我们日常使用的多种在线服务中并不安全。

比如你想给住在同一条街的朋友发一张照片,这张照片经过的服务商数量太多了:你的手机会抓拍图片,通过网络发送,直到到达应用程序服务器(可能在海外);然后服务器会将照片存储在数据库中,对其进行分析以进行面部识别以建议在照片中标记朋友,并向您朋友的设备发送通知;最后你的朋友会检查通知并从海外数据库加载照片。

在这种情况下有很多事情可能会出错,而事实是,您可能不希望照片存储在某个无法删除的遥远数据库中。您只是想直接与朋友分享您的照片。

Location Addressing vs Content Addressing

我们面临的许多问题来自使用位置寻址方法来查找用户正在寻找的内容,并从该地址提供服务。例如,我们希望我们的 libp2p logo 可以在 https://proto.school/tutorial-assets/T0009L01-libp2p-logo.svg 获得,但是如果这个网站的服务器宕机了怎么办?如果 DNS 服务器关闭怎么办?如果图像被转换为​​ PNG 文件,所以新位置是 T0009L01-libp2p-logo.png 怎么办?如果您所在的国家/地区已阻止 proto.school 域怎么办?所有这些问题都是常见的,都是由位置寻址引起的,我们试图通过位置寻址找到我们需要的内容。

然而,IPFS 以不同的方式通过使用内容寻址来解决这个问题。如果我们知道 libp2p 标志的 CID(内容标识符)而不是它的位置,我们可以简单地询问网络谁拥有带有此 CID 的图像。这种方法的优势非常吸引人,因为它们解决了前面提到的所有其他问题,但要做到正确,还需要首先解决其他问题,特别是在网络中。

Networks are complex

要拥有由内容寻址提供支持的网络,我们需要重新设计和重新想象计算机网络的工作方式。网络是非常复杂的系统,有自己的规则和限制,因此在设计这些系统时,我们需要考虑很多情况和用例:

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

哦,这是一个长长的清单!但为了创建成功的 P2P(点对点)通信,IPFS 必须解决这些问题。

事实是,正如我们将在下一课中看到的那样,IPFS 并不是第一个尝试解决这些问题并创建 P2P 网络的项目。

The current problem with P2P protocols

点对点 (P2P) 网络是从互联网的概念中构想出来的,它是一种创建弹性网络的方式,即使对等点由于重大自然或人为灾难而与网络断开连接,该网络也能正常运行,使人们能够继续通信。

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

Peer - 去中心化网络中的参与者。对等方在应用程序中享有同等特权、等能参与者。在 IPFS 中,当您在笔记本电脑上加载 IPFS 桌面应用程序或从命令行运行 ipfs 守护程序时,您的设备将成为 IPFS 去中心化网络中的对等点。

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

Reinventing the wheel

所有具有 P2P 连接的应用程序必须解决的主要挑战之一是可发现性:两个或多个对等点如何找到彼此并共享信息?过去,每个 P2P 应用程序都解决了这个问题(以及许多其他问题),并使用针对各自用例定制的不同想法和方法实施了自己的解决方案。

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

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

  • 文档不完善或不存在
  • 限制性许可或找不到许可
  • 十多年前最后一次更新的非常旧的代码
  • 没有联系点(没有维护人员可以联系到)
  • 闭源(私有)代码
  • 弃用产品
  • 未提供规格
  • 没有公开友好的 API 实现与特定用例过于紧密地耦合
  • 不能用未来的协议升级

所以最终,每次需要 P2P 协议时,开发人员都会从头开始一次又一次地解决相同的挑战,因为已经嵌入软件包的 P2P 协议是不可提取和可重用的。

有人会认为这是过去的问题。开源社区经过多年的发展,构建了一个强大的生态系统,提供了数千个开源软件包,其中包括完整的测试套件、良好的文档和友好的 API。但不幸的是,还没有出现可以解决各种用例中出现的所有问题的好的 P2P 协议实现。

从历史上看,生产 Skype 或 BitTorrent 等产品的公司创建了自己的协议来支持它们。这些协议对它们运行的​​环境和它们将满足的需求做了很多假设,使它们难以升级或适应新环境。

The solution

当然,所有这些问题的答案是一个闪亮的新协议,它一劳永逸地解决了所有这些问题!嗯……不完全是。

libp2p概览_第1张图片

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

Enter libp2p

libp2p 是 IPFS 的网络堆栈,但是从 IPFS 中提取出来,成为一流的项目和 IPFS 本身的依赖项。

libp2p概览_第2张图片

通过这种方式,libp2p 能够进一步发展而无需专门附加到 IPFS,从而获得自己的生态系统和社区。 IPFS 只是成为 libp2p 的众多用户之一。

这样,每个项目都可以专注于自己的目标:

  • IPFS 更专注于内容寻址,即查找、获取和验证网络中的任何内容。

  • libp2p 更侧重于进程寻址,即查找、连接和验证网络中的任何数据传输进程。

查找、连接和验证网络中的任何进程是一个大胆的声明。那么 libp2p 是如何做到的呢?答案是 模块化

模块化

libp2p概览_第3张图片

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

libp2p概览_第4张图片

就本教程而言,您无需了解所有这些部分是什么,但了解构建网络堆栈时需要考虑的组件数量很重要。如果您想了解有关这些单个组件的更多信息,可以查看 libp2p 文档中的概念页面。

用户可以选择他们需要的特定部分,并为他们的用例量身定制自己的配置。所有这些部分都具有定义明确的接口,可实现互操作性和轻松升级,从而创建面向未来的网络堆栈。

libp2p概览_第5张图片

通过提供一致的接口,libp2p 能够创建一个可互操作的模块生态系统。将接口视为乐高积木顶部的螺柱和它们下方的连接点……乐高可以创造出无穷无尽的新部件,它们可以完美地组合在一起,只要它们都使用相同的方法粘在一起。

让我们将其与家具购物进行比较。当然,您可以花费数周时间寻找最适合您的客厅的完美沙发,但最终,它仍然不是您想要的样子。如果相反,您可以去一家允许您订购自己的沙发的在线商店,并使用您想要的材料设置颜色。这家沙发公司已经确定了构成沙发的基本构件(1 人座、2 人座或 3 人座?带或不带躺椅?天鹅绒、纤维或皮革?),并提供了一项网络服务,允许客户定制他们想要的沙发。无论您选择什么单品,它们的设计都旨在完美地组合在一起。如果您在一个月后改变主意,您可以更换面料或增加一个额外的座位,没问题。这就是 libp2p 提供的模块化。它将网络的构建块形式化为接口(传输、发现等),以便它们可以以不同的方式(TCP、UDP 等)实现。

例如,让我们看看传输接口。传输是定义数据传输方式的基础协议的集合。即使在这个模块中,也需要做出许多决定,例如每个数据块发送多少字节,是否应该单独或一次性验证完整性等。

libp2p概览_第6张图片

我们可以看到七个实现传输接口的模块。因此,如果我们想将传输协议从 TCP 切换到 WebSockets ,我们可以通过简单地从 js-libp2p-tcp 切换到 js-libp2p-websockets 来轻松实现。

如果我们缺少需要实现的模块,我们可以自己创建模块及其接口,并使用接口提供的测试套件来验证其实现。因此,您可以像任何其他可用的 libp2p 传输一样插入我们自己的 libp2p-mail传输。

libp2p in the OSI Model

那么,libp2p 在哪里适合当前的网络? Web 建立在复杂的网络协议系统之上,其中一些协议为最终用户所熟悉,例如 HTTP 和以太网,而其中一些协议仅为网络专家所熟悉。

通常,我们查看 OSI 模型(开放系统互连模型)以了解协议试图解决的层。

但事实是, OSI 模型和 TCP/IP 模型只是概念模型。当前网络中的实际实现并没有完全遵循这些模型,并且不太整洁,例如上面显示的 TCP/IP 协议套件。

最后,这些模型有一些缺点:

  • 动作通过多层重复(重复工作),因为数据可以通过多次认证或多次发现;这是非常低效的!
  • 信息隐藏在层之间,错过了重要的改进机会,并且通过尝试将尽可能多的层放在单个协议模块中,例如 QUIC 协议,已经考虑到这些机会创建了一些协议。

当很明显遵循这些严格的概念模型并不理想时,libp2p 开始做一些不同的事情 - 其他人已经打破了它们。通过允许用户只选择和配置他们需要的网络堆栈部分,libp2p 创造了一种新方法来维护和升级具有安全、可靠和模块化网络堆栈的应用程序。

Multiple environments supported

libp2p 有多种实现,并且它们都可以互操作。在撰写本文时,libp2p 有 7 个本机实现:

libp2p概览_第7张图片

Browser support

libp2p 的 JavaScript 实现也适用于浏览器和移动浏览器!这非常重要,因为它使应用程序也可以在桌面和移动设备上运行 libp2p。

libp2p概览_第8张图片

作为模块化网络堆栈,libp2p 旨在能够满足各种项目需求。 libp2p 的配置是其结构的关键部分。它使您能够准确地使用您需要的功能,并且只使用您需要的功能。例如,它可以配置 libp2p-tcplibp2p-websocketslibp2p 模块。并且您只需要在 libp2p 配置中更改几行代码即可从 NodeJs 版本转到浏览器版本。

让我们使用 js-libp2p 版本 0.30 来看看 NodeJs libp2p 配置的样子:

'use strict'

const TCP = require('libp2p-tcp')
const MulticastDNS = require('libp2p-mdns')
const WS = require('libp2p-websockets')
const WebSocketStar = require('libp2p-websocket-star')
const Bootstrap = require('libp2p-bootstrap')
const KadDHT = require('libp2p-kad-dht')
const Multiplex = require('libp2p-mplex')
const { NOISE } = require('libp2p-noise')
const libp2p = require('libp2p')
const defaultsDeep = require('@nodeutils/defaults-deep')

const defaultConfiguration = {
  modules: {
    transport: [TCP, WS, WebSocketStar],
    streamMuxer: [Multiplex],
    connEncryption: [NOISE],
    peerDiscovery: [MulticastDNS, Bootstrap, WebSocketStar.discovery],
    dht: KadDHT
  },
  config: {
    peerDiscovery: {
      mdns: { enabled: true },
      bootstrap: { enabled: true },
      websocketStar: { enabled: true }
    },
    dht: { kBucketSize: 20 }
  }
}

module.exports = async (options) => (
    libp2p.create(defaultsDeep(options, defaultConfiguration))
)

第一部分导入构成此网络堆栈的所有必需的 libp2p 模块。第二部分是 libp2p 节点配置,我们为网络的每个部分添加不同的模块。在此配置中,我们使用了所有 libp2p 节点所需的 transportstreamMuxerconnEncryption ,以及可选的 peerDiscoverydht 模块。

为了让这段代码在不支持 TCP 传输的浏览器中运行,我们只需要更改 libp2p 配置中的传输协议和 peerDiscovery 协议。不需要在应用程序中进行其他更改!

libp2p概览_第9张图片

在此示例中,我们只需更改很少的代码行即可配置在浏览器中运行的 libp2p 节点。编辑配置以适应新环境的简单性是 libp2p 的主要优势之一。

Applications and services using libp2p

目前有很多使用 libp2p 的服务,包括文件存储、视频流、加密钱包、开发工具和区块链。在这里,我们列出了一些示例,但随着您阅读本文,列表会继续增长。

libp2p概览_第10张图片

IPFS 广泛使用 libp2p,因此所有其他依赖于 IPFS 的服务也间接使用 libp2p。

你可能感兴趣的:(区块链,p2p,区块链,网络协议)