Web3时代的分布式存储——IPFS技术指引(教程)

Web3时代的分布式存储——IPFS技术指引(教程)

Web3时代的分布式存储——IPFS技术指引(教程)
当你想开发一个去中心化应用的时候,可能会想到像以太坊这样的区块链。区块链在管理状态、实现智能合约自动流程和交换经济价值等方面是非常有用的。你可以根据这篇教程(https://www.freecodecamp.org/news/build-a-blockchain-in-golang-from-scratch/)搭建一个区块链从而了解有关区块链的更多知识。

不过,你的应用的数据存储在哪里?这些数据包括了图像、文件,以及由HTML、CSS和JS文件构成的应用网站前端服务。你的应用和用户的数据是从一个中心化的亚马逊云服务器上加载的吗?

在区块链上存储内容是很昂贵和低效的。你的区块链应用需要去中心化的存储方案!

在这个教程中,我会向你介绍星际文件系统(InterPlanetary File System, 缩写为IPFS)。你将会学到:

1.   如何通过去中心化存储来存取数据。

2.   如何运行自己的IPFS节点。

3.   有关IPFS协议的底层构造

4.   我们还会读取一个存储在IPFS上的维基百科网站。

准备好了吗?那开始吧。

目录

  • 什么是IPFS?
  • 如何设立一个IPFS节点
  • 如何使用CLI命令行和HTTP协议来存取IPFS内容
  • 什么是CID标识——IPFS上的基于内容的标识
  • 如何反向工程IPFS数据存储
  • 如何将IPFS节点连接到去中心化网络
  • 如何使用 Bitswap协议在点对点网络上交换数据
  • 如何在点对点网络上进行内容持久化

什么是IPFS?

星际文件系统的缩写是IPFS,它是一个点对点的超媒体协议,旨在让网络变得更快、更安全和更开放。

IPFS是一个用于存储和分享内容的协议。就如在区块链世界里的那样,每一个用户都会运行自己的节点(服务器)。节点之间可以互相通讯并交换文件。

IPFS的特别之处在哪里?

首先,IPFS是去中心化的,因为它从数千个节点中载入内容,而不是从单一的中心化服务器中载入。数据的每一个片段都是用密码学哈希运算处理的,从而生成一个安全的,独特的内容标识:CID。

在IPFS上存储网站可以避免审查和单点故障问题。你担心自己的IPFS节点掉线吗?不用害怕,网站仍然能从全球其他提供相应数据的节点上载入内容。

例如,假设维基百科服务难以使用,就可以从IPFS的点对点网络上获取在4月17日进行索引并持久化存储的去中心化版维基百科。具体是通过CID:

“QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX”

其次,IPFS内容的完整性可以通过密码学验证

最后,IPFS内容是有重复内容处理机制的。如果你尝试在同一个IPFS节点上存储两个一样的1MB大小文件,它们只会被存储一次。这就消除了重复数据的问题。因为它们的哈希值会生成同样的CID标识。

如何设立一个IPFS节点

安装IPFS

打开 IPFS文档(https://docs.ipfs.io/install/)的安装页,根据你的操作系统类型(Windows, macOS, Linux)参照相应指示。我会在下面记录Ubuntu环境下的安装过程。

Web3时代的分布式存储——IPFS技术指引(教程)

IPFS安装文档

我倾向于从头开始编译ipfs/go-ipfs 代码库(http://github.com/ipfs/go-ipfs)并按需查错。毕竟,Go语言真的很棒。

在Go环境里编译代码

克隆代码库,并运行 Makefile里的安装脚本。

Web3时代的分布式存储——IPFS技术指引(教程)

或者下载并安装预编译版本的 IPFS:

Web3时代的分布式存储——IPFS技术指引(教程)验证安装效果

说实话吧,Go语言是很棒的,自己编译代码也是很酷的,也算是去中心化精神的体现。由此生成的二进制文件会在你的$GOPATH里创建。

新节点初始化

运行 ipfs init 以创建新节点。默认情况下,这会新建一个文件夹并将所有数据存储在 ~/.ipfs  。你可以通过编辑IPFS_PATH 环境变量来修改此配置。

Web3时代的分布式存储——IPFS技术指引(教程)

现在你的节点已经完成初始化了,等待你上传内容。

如何使用IPFS

增加内容

IPFS可以处理不同类型的数据,这包括了简单的文本、图像、视频和网站等。

下面先从存储这段简单的信息开始:hello IPFS world by Web3Coach:

Web3时代的分布式存储——IPFS技术指引(教程)

这样,内容就存储好了,并通过密码学哈希函数建立索引,然后返回其独特的内容标识号 (CID):

Web3时代的分布式存储——IPFS技术指引(教程)

你的IPFS节点会在本地的文件系统中生成与本文相同的CID标识号。这是因为IPFS对内容进行哈希值运算并返回其独特的指纹,毕竟一个安全的哈希函数总是会对指定的输入值返回固定的输出值。

Pin(固定)住内容

当你增加内容时,你只是增加到你的本地节点里。这些内容并不会自动地复制到整个网络里——这也是IPFS用户和开发者之间的常见误解。

当你使用add 命令, IPFS默认情况下也会执行 pin 命令:

Web3时代的分布式存储——IPFS技术指引(教程)

为了将内容进行全网复制,你必须将节点上线,加入点对点网络,并在其他节点上pin特定的CID标识号。在这篇教程的后面,你会学习到操作方法,了解到背后的工作原理。

读取内容

拷贝这个CID标识到 IPFS的 cat命令行,以从磁盘中读取:

Web3时代的分布式存储——IPFS技术指引(教程)

add , pin和cat命令是最重要的IPFS功能,你现在已经了解了。恭喜!

IPFS内容寻址是如何运作的

QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z是什么?

这是一个自我描述的基于内容的标识号。

“自我描述”是什么意思?即根据IPFS的规格约定,你可以通过切割这个字符串,就可以了解其索引的数据。

  • 它的CID版本
  • CID字符串的读取方式(base32? base58? hex?)
  • 数据的编码方式
  • 数据指纹对应的哈希函数是什么
  • 哈希函数的长度

IPFS团队搭建了一个方便的网站(https://cid.ipfs.io/)用于分析一个 CID标识号:

Web3时代的分布式存储——IPFS技术指引(教程)

通过解析 QmRBkKi1P…p6z 这个CID标识,你会发现:

  • 这个CID标识是基于版本0规格,因为它以 Qm开头
  • QmRBkKi1P…p6z 这个字符串是使用base58btc来编码的
  • hello IPFS world by Web3Coach. BTW: Ethereum FTW” 这个数据在往磁盘上存储之前,是根据0x70编码器作为DAG Protobuf编码的。
  • 哈希值 0x12 意味着数据指纹是使用sha256 哈希函数获取的,从而生成了一个32字节长的独特摘要值

相比于一个MySQL数据表里的自增INT键值,这就“稍微复杂了点”。不过这是非常有效的,而且能够应对未来的挑战。让我展开解释一下:

CID标识号版本

当前有两个CID标识号版本: v0 v1

CID v0版不是很灵活,而且受限于:

  • 以 “Qm”开头
  • CID标识号字符串使用base58btc编码
  • 默认使用 dag-pb来编码数据
  • 可以转换成 CID v1版,但反过来不行。

CID v1版利用了几个前缀,来最大化互操作性:

  • CID v1 = Multibase + Multicodec + Multihash

换句话说,根据这个规格将二进制内容解析成为CID V1版:

<base><codec><hash-function><hash-length><hash-digest>Multihash(多种哈希支持)

为了满足未来需求,且支持不同的哈希算法,IPFS设立了如下的标准:

CODE : SIZE : DIGEST

Web3时代的分布式存储——IPFS技术指引(教程)

Multihash有很多优势。当未来5年内计算机的性能更强大时,你可以通过配置相应的0x13代码作为CID标识前缀里的Multihash ,就可以使用一个更强的哈希函数(如sha3-512)。到时候协议早就就绪了。

Multicodec

Code 属性告诉你数据在存储到磁盘前的编码方式,这样当用户想读取数据时,就可以知道如何解码。它可以是CBOR, Protobuf, JSON等。

IPFS维护了各种潜在的编码器列表(https://github.com/multiformats/multicodec/blob/master/table.csv)。最常用的编码器有:

Web3时代的分布式存储——IPFS技术指引(教程)

Multibase

CID v0版标识和base58btc 编码的问题是在不同的环境间缺乏互操作性。multibase前缀增加了对 base32这样的编码方案的支持,从而实现对DNS友好的命名。

Multibase编码表(https://github.com/multiformats/multibase/blob/master/multibase.csv):

Web3时代的分布式存储——IPFS技术指引(教程)

你可以通过第一个字母看到 Multibase的编码方式:

QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z

  • 这是CID v0版标识
  • CID字符串使用base58btc来编码

bafybeibkjmxftowv4lki46nad4arescoqc7kdzfnjkqux257i4jonk44w4

  • 这是CID v1版的标识
  • CID字符串使用了base32来编码

两个CID标识版本都可以取回同样的内容,因为在你忽略编码方式时,其实就是 Multihash在数据存储的区块层面进行索引。与此相反, Multibase只用于在不同环境间(CLI, URL, DNS)正确传递CID标识号。

Web3时代的分布式存储——IPFS技术指引(教程)

现在情况很快就变得“有点复杂了”。

既然谈到了复杂的话题,那IPFS还是很强大的,因为它不仅将内容视为数据,还将其视为 数据结构,具体而言就是星际链接数据结构——InterPlanetary Linked Data Structure: IPLD. 简单地说,你可以在IPLD结构之上实施任何的文件系统、数据库或结构。

例如,你可以在IPFS上存储所有的以太坊区块链,只要你设置eth-block和eth-tx 编码器,并在操作 IPLD graph时注册合适的解码器。

让我们研究一下默认的IPLD结构与DAG Protobuf编码器使用的情形:

IPFS如何在文件系统上存储内容

“ ipfs add 命令会根据UnixFS 数据格式 来为数据创建一个 Merkle DAG (默克尔有向无环图)。你的内容将会被使用 Chunker分割器来打散成 blocks块 ,然后使用链接节点’link nodes’将其连接在一起并整理成树状结构。返回的CID标识号则是DAG里的根节点的哈希值。”

迷糊了么?

让我们先回到一些基础问题。

探索节点的数据目录

在这篇教程的开头处,当使用ipfs init 进行IPFS节点初始化时,你生成了以下的目录:

Web3时代的分布式存储——IPFS技术指引(教程)

顶层的角度看,

  • blocks — IPFS在这里存储了所有的数据切块,不同 go-ipfs 的灵活接口让你可以将存储方案改成不同的数据库
  • config — 节点的设置(文件系统,身份,规格和网络)
  • datastore —索引和其他逻辑

实践是检验真理的标准。你可以使用下面的内容在本地的文件系统上创建新文件,并将其添加到IPFS上:

Web3时代的分布式存储——IPFS技术指引(教程)

对go-ipfs 代码进行反向工程,这是它背后的机制:

Web3时代的分布式存储——IPFS技术指引(教程)

IPFS UnixFS添加新文件并转换到数据块里

你可以通过检查数据块来验证持久化过程。你会发现这使用了DAG Protobuf 编码(131 bytes + Protobuf 额外编码)来将内容写在Multihash Datastore Key下。

Web3时代的分布式存储——IPFS技术指引(教程)

为了与原始内容互动,使用 ipfs object 命令:

Web3时代的分布式存储——IPFS技术指引(教程)

Web3时代的分布式存储——IPFS技术指引(教程)

  • 因为内容只有131字节,它可以放在一个DAG节点(Node)下
  • 这个DAG节点在磁盘上是以一个数据块(Block) 的单位来实现持久化
  • 这个DAG节点与其他节点的链接数量为0

下面是实验时间。

再次添加同样的文件,但将Chunker切块器配置为64字节 (或使用更大的文件,但一个较小的分割器配置会更好地解释这些问题)。

Web3时代的分布式存储——IPFS技术指引(教程)

你得到了一个新的CID标识号!

IPFS将内容分割为4个DAG节点,并向磁盘写入了以DAG Protobuf 格式编码的4个数据块。

Web3时代的分布式存储——IPFS技术指引(教程)

IPFS将一个文件分割成多个chunks (DAG Nodes + Blocks)

Web3时代的分布式存储——IPFS技术指引(教程)

Web3时代的分布式存储——IPFS技术指引(教程)

终极的测试就是取回每一个DAG节点的数据,并验证该文本被分割为三块 :

DAG Protobuf 节点 1:

Web3时代的分布式存储——IPFS技术指引(教程)

Web3时代的分布式存储——IPFS技术指引(教程)

DAG Protobuf 节点 2:

Web3时代的分布式存储——IPFS技术指引(教程) Web3时代的分布式存储——IPFS技术指引(教程)

DAG Protobuf 节点 3:

Web3时代的分布式存储——IPFS技术指引(教程) Web3时代的分布式存储——IPFS技术指引(教程)

将内容分割成多个切块(chunks)和使用内容寻址和CID标识的好处是什么?

  • 重复数据删除
  • 去中心化

下一次,当你想存储一个文件,而这个文件的一部分内容会与另一个文件共享时,IPFS不会重复存储数据块,而是会链接到一个已经存在的DAG节点,从而实现只存储新的、唯一的切块。

将内容转换成带有多个节点的DAG也有助于并行载入内容。例如,一篇博客文章、图像和整个维基百科网站都可以从多个IPFS节点上载入。你的节点会通过所获取数据块的内容数据哈希值和相应的CID标识号来验证完整性。

你已经了解了IPFS的主要构成部分,这是一个很大的进步!

还剩下一个关键的组件:联网。

如何将IPFS节点连接到点对点网络上

每一个节点在执行 ipfs init命令后都会生成一个config文件。

打开这个文件。

Web3时代的分布式存储——IPFS技术指引(教程)

先不看其他设置,你可以找到节点的Identity身份 (PeerID节点标识 + Private Key私钥):

Web3时代的分布式存储——IPFS技术指引(教程)

以及一系列的初始化启动地址(Bootstrap addresses):

Web3时代的分布式存储——IPFS技术指引(教程)

你会通过运行ipfs daemon 命令来连接到IPFS网络上的其他节点。你的节点会先与Protocol Labs 实验室(IPFS背后的公司)的初始化启动节点建立点对点连接,通过它就进一步找到几百个其他节点。

Web3时代的分布式存储——IPFS技术指引(教程)

注意,在运行 IPFS Daemon后台程序后:

1.   你的节点会连接到点对点网络,并能与其他节点交换数据块

2.   其他节点可以访问你节点上的内容——只要它们知道对应的CID标识号

3.   其他节点会通过TCP和UDP协议在端口 4001 上与你的节点通讯

4.   如果你有一个应用程序。可以通过在端口5001上监听的HTTP API接口来存储和使用节点的内容。

对应用开发而言,我提议使用官方的ipfs-http-client JS库(https://www.npmjs.com/package/ipfs-http-client),这样可以使用所有的核心命令——add, cat, object等。它会加快你的开发过程。

为了简单展示,我会使用curl命令来与这个API接口互动。

如何使用IPFS HTTP API接口:

增加内容: :5001/api/v0/add

Web3时代的分布式存储——IPFS技术指引(教程)

读取内容 :5001/api/v0/cat

Web3时代的分布式存储——IPFS技术指引(教程)

查看 官方的HTTP API文档(https://docs.ipfs.io/reference/http/api/#getting-started)可获得完整的可用命令列表。

Web3时代的分布式存储——IPFS技术指引(教程)

如何与其他IPFS节点连接

这是一个有趣的实验。使用 ipfs swarm 命令并检查你已经发现的节点数量:

Web3时代的分布式存储——IPFS技术指引(教程)

太棒了!你已经从无法阻挡的点对点网络上连接到了186个节点。

隐私性如何?

其他节点可以访问你添加到IPFS节点上的所有内容。这个网络没有内置的隐私保护机制,所以千万不要将没有加密的、敏感的或个人内容添加到IPFS上。

节点如何使用 Bitswap协议交换数据

目前,你只与本地的内容交互过。现在来介绍一下如何访问远程的内容。

现在维基百科已经被添加到IPFS上,所以你可以运行自己的节点并从全球的节点上获取相关的内容。

http://localhost:8080/ipfs/QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX/wiki/Anasayfa.html

DAG Service会在你的数据存储中检查数据块,但不会找到与 QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX对应的内容。

因此,节点会通过exchange 组件来使用Bitswap 协议,向网络的其他节点发送网络请求:

Web3时代的分布式存储——IPFS技术指引(教程)

在内部,CID被添加到一个 Wantlist 里:

Web3时代的分布式存储——IPFS技术指引(教程)

PeerManager会遍历已知的节点及其他相连的节点,找到一个能够提供所索取的数据块的在线节点:

Web3时代的分布式存储——IPFS技术指引(教程)

结果是?

你可以直接从 localhost:8080 读取维基百科内容:

Web3时代的分布式存储——IPFS技术指引(教程)

IPFS在你的本地节点上载入维基百科

这就是无法审查的去中心化存储。

 

如何在点对点网络上固定内容

你必须知道IPFS的一个关键信息:除非你进行pin固化 操作,不然你从网络访问的内容会成为垃圾。

Pinning和垃圾回收

在这篇文章的开头,你了解到了使用 ipfs add命令或其HTTP的等效操作是会默认进行pin操作的。

Web3时代的分布式存储——IPFS技术指引(教程)

当垃圾回收进程开启后,被pin固化住的数据块就被标记为不应该被删除的内容。

为什么垃圾回收会删除一些数据块呢?这是为了控制存储体积来保持节点的健康度。

在点对点网络上阅读维基百科或访问其他内容时,IPFS会下载其数据块。随着节点的数据持续增长,一个定期执行的垃圾回收进程会删除没有进行pin操作的数据块,这样你不至于缺乏可用磁盘空间。

如果你想自己的内容在IPFS网络上全天候可用,我建议使用一个可靠的远程服务商来进行pin操作:Infura(https://infura.io/docs/ipfs?utm_source=web3coach&utm_medium=article) ——这是最简单的开始方式,而且你会得到5GB的免费去中心化存储空间。

Web3时代的分布式存储——IPFS技术指引(教程)

请参照上手教程(https://infura.io/docs/ipfs?utm_source=web3coach&utm_medium=article)。

如何在本地pin维基百科

首先确保维基百科的根CID(最高的DAG节点)还没有在你的节点上pin住:

Web3时代的分布式存储——IPFS技术指引(教程)

IPFS以DAG的形式存储了特定的维基百科版本。我建议在开始pin操作前检查其DAG图:

Web3时代的分布式存储——IPFS技术指引(教程)

根部的 DAG对象有5个链接。其中4个链接相对小,但有一个链接指向了总体积为12GB的一个DAG节点。如果你检查这个DAG节点,就会看到有额外的256个链接和累计(循环)的12GB体积。

Web3时代的分布式存储——IPFS技术指引(教程)

每一个存放了pin住的文章、视频、纪录片或猫咪搞笑图片的节点都会让网络变得更可用,更能抵抗脆弱性,更去中心化和稳健。

Web3时代的分布式存储——IPFS技术指引(教程)

pinning过程会循环遍历整个DAG节点,从Bitswap协议获取所有的链接,然后在你的本地存储中pin住每一个数据块。

 

恭喜!你在这篇文章里学到了去中心化存储背后的工作原理。

“我花了47小时来写这篇文章,不过你可以在5秒内就帮我转发:

如何成为Web3区块链开发者?

我从2018年开始就开发以太坊应用,我的目标是将1000名开发者带入区块链生态系统。

如果你想学习分布式和去中心化系统,我会在这个WIP路线图里分享相关知识。”

— Lukáš Lukáč (@Web3Coach) 6月21日,2021年

 

Lukas Lukac:前任trivago软件工程师,作者和区块链导师。我通过教授搭建区块链系统和以太坊应用的方式,来为Web3.0的新时代训练软件开发者。

免责声明:平台所发布文章仅代表作者个人观点,与链科天下无关。文章内的信息、意见等均仅供参考,并非作为或被视为实际投资建议。

(1836)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注