区块链 | IPFS:CID

🦊原文:Anatomy of a CID
🦊写在前面:本文属于搬运博客,自己留存学习。



1 CID

在分布式网络中与其他节点交换数据时,我们依赖于内容寻址(而不是中心化网络的位置寻址)来安全地定位和识别数据。

CID 规范起源于 IPFS,现在以 Multiformats 形式存在,并支持包括 IPFS、IPLD、libp2p 和 Filecoin 在内的系统。尽管我们在教程中会分享一些 IPFS 的例子,但本教程实际上是关于 CID 自身的结构,它作为这些分布式信息系统的核心标识符,用于引用内容。

内容标识符(CID)是一种自描述的内容寻址标识符。

自描述是指,标识符能够自行表达其含义或者数据类型。例如 HTTP 中的 URL就是一个自描述的标识符,因为它包含了指向资源的信息(如文件路径),并且基于协议和结构,用户和系统可以理解其含义。

CID 不指示内容存储的位置,而是基于内容本身形成一种地址。CID 的长度取决于内容的哈希,而不是内容本身的大小。由于在 IPFS 中大多数内容都使用 sha2-256 进行哈希处理,因此大多数 CID 都具有相同的大小,即 256 位或称 32 字节。

例如,如果我们在 IPFS 网络中存储 土豚 的图像,它的 CID 将如下所示:

QmcRD4wkPPi6dig81r5sLj9Zm1gDCL4zgpEj9CfuRrGbzF

访问方式:https://ipfs.io/ipfs/QmcRD4wkPPi6dig81r5sLj9Zm1gDCL4zgpEj9CfuRrGbzF

创建 CID 的第一步是使用 加密算法 转换输入的数据。具体来说,是将任意大小的输入映射到固定大小的输出。如下图所示:

在这里插入图片描述
这种转换称为 加密哈希摘要(cryptographic hash digest)或简称为 哈希

个人理解:不管是文本、图片还是视频,它们在计算机中都是以二进制的形式进行存储的,即一个 01 字符串。而哈希函数要做的事,就是将不同文件不同长度的 01 字符串转换为固定长度的 01 字符串。

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

  • 确定性:对于任何给定的输入数据,加密算法必须始终产生相同的输出哈希,确保一致性。
  • 抗碰撞性:即使输入数据发生微小变化,也应导致完全不同的哈希值,以保证数据的唯一性。
  • 不可逆性:从哈希值应当无法反推出原始数据,确保数据的隐私和安全。
  • 唯一标识:每份文件都应该有一个独特的哈希值,确保数据的不可篡改性和可追溯性。

当我们使用内容地址去获取数据时,我们可以保证看到数据的预期版本。这与中心化网络上的位置寻址有很大的不同,在中心化网络中,给定地址(URL)处的内容可能会随时间变化。

说明:在去中心化网络中,我们使用 CID 去获取数据;在中心化网络中,我们使用 URL 去获取数据。

哈希并不是 IPFS 所独有的,还有许多其他的哈希算法,如 sha2-256、blake2b、sha3-256 和 sha3-512,以及不再安全的 sha1 和 md5 等。IPFS 默认使用 sha2-256,尽管 CID 支持几乎任何强大的加密哈希算法。



2 CIDv0

随着时间的推移,某些哈希算法可能被证明对于 IPFS 和其他分布式信息系统的内容寻址是不够安全的。

因此,我们的系统需要支持多种加密算法,同时我们应该能够知道是哪种算法被用来生成特定内容的哈希值。为了支持多种哈希算法,我们使用了多重哈希。



2.1 多重哈希

多重哈希(multihash)是一种自描述的哈希,它本身包含元数据,这些元数据描述了其长度以及生成它的加密算法。

多重哈希遵循 TLV 模式,即 type — length — value。也就是说,原始哈希 value 前面附带着所使用的哈希算法的类型 type 和哈希的长度 length。如下图所示:

在这里插入图片描述

  • type:用于生成哈希的加密算法的标识符。例如,sha2-256 的标识符是 18,即十六进制的 12;
  • length:哈希的实际长度。使用 sha2-256 时,它将是 256 位,相当于 32 字节;
  • value:实际的哈希值;

通过查看 multicodec 表,可以获取各个哈希算法对应的标识符。



2.2 基数编码

为了将 CID 表示为紧凑的字符串而不是纯二进制(一串 0 和 1),我们可以使用基数编码(base encoding)。

在 IPFS 最初创建时,它使用 base58btc 编码来生成看起来像这样的 CID:

QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU

多重哈希和 base58btc 编码构成了第一版 CID,即如今所说的版本 CIDv0,以 Qm 开头的序列仍然是它的一个显著特征。

然而,随着时间的推移,人们开始对多重哈希是否足够的问题产生了疑问:

  • 我们如何知道使用了什么方法来编码数据?
  • 我们如何知道使用了什么方法来创建 CID 的字符串表示?我们是否会一直使用 base58btc

为了应对这些担忧,有必要对 CID 的下一版本进行改进。

个人理解:在本文中,“基数编码” 是指将二进制转换为可读的字符串,“编码” 是指将文件转换为二进制。



3 CIDv1

CIDv0 使用多重哈希来支持多种哈希函数。这允许我们针对特定内容创建哈希值,且可以选择不同的哈希算法进行处理。有了这一机制,我们日后便能通过这些哈希值来辨识内容。



3.1 多码前缀

但当我们试图阅读数据本身时,如何知道采用了哪种编码方式?数据可能是由 CBOR、Protobuf 或纯 JSON 等编码的。为了解决这个问题,CIDv1 引入了另一个前缀,用以唯一标识所使用的编码方法。

个人理解:哈希是将任意长度的 01 字符串转换为固定长度的 01 字符串,而编码是将非 01 字符串的数据本身转换为 01 字符串。

多码前缀(multicodec prefix)指示了数据使用了哪种编码方式。如下图所示:

在这里插入图片描述

多码支持许多不同类型的编码,每种编码都有自己的简短码缀,可以在 complete 表中查看。

在上述示例中,我们了解到使用 dag-pb 编码的数据是如何被表示在 CID 中的。其中,dag-pb 是众多 IPLD 编码格式中的一种。由于 IPFS 总是选择一种 IPLD 格式来处理其数据,因此 IPFS 生成的 CID 中的多码前缀必然对应于一个 IPLD 编码。

IPLD 是指 Inter Planetary Linked Data,星际链接数据

需要指出的是,多码不仅仅是为了 IPFS 和 IPLD 而设计的,它还是 Multiformats 项目的一部分。这个项目最初是从 IPFS 分离出来的,现在它支持包括我们正在学习的 CID 规范在内的许多其他项目和协议。



3.2 版本前缀

添加多码前缀后,CIDv1 包含以下字段:

<multicodec><multihash-algorithm><multihash-length><multihash-hash>

那么我们如何区分不同版本的 CID 呢?答:版本前缀。如下图所示:

在这里插入图片描述

现在我们的 CID 看起来像这样:

<cid-version><multicodec><multihash>

其中,<cid-version> 代表 CID 的版本是 0 还是 1 。

注意:<multihash> 包含了 <multihash-algorithm><multihash-length><multihash-hash>。特别地,只有 CIDv1 具有 <cid-version>,而 CIDv0 只有 <multihash>



3.3 多基前缀

CIDv1 以二进制的形式为我们提供了以下信息:

<cid-version><multicodec><multihash>

由于二进制 CID 对人类不太友好,因此我们可以将这些二进制 CID 表示为字符串形式,即把二进制数据表示为字符串。

采用的就是前文提到的基数编码技术。

示例:

bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi

在二进制和字符串形式之间转换数据需要进行基数编码,因此在处理字符串格式的 CID 时,我们需要知道应用于二进制数据的基数编码的类型。

在 CIDv0 中,哈希总是使用 base58btc 进行编码。因此我们可以直接假设 CIDv0 哈希是由 base58btc 编码的。然而,由于环境限制(例如 DNS 名称),我们需要支持其他基数编码的能力。你猜对了,我们可以添加另一个前缀!

多基数前缀(multibase prefix),用于表示 CID 在进行格式转换时使用的基数编码,仅用于 CID 的字符串形式:

Binary:
<cid-version><multicodec><multihash>
String:
<base>base(<cid-version><multicodec><multihash>)

其中,base( ) 应该是指使用某种基数编码方法,对括号中的内容进行基数编码。

让我们来分析两个 CID 的字符串形式示例:

CIDv0:
QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR
CIDv1:
bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi

易知第一个 CID 是一个 CIDv0,因为它以 Qm 开头。所有以 Qm 开头的哈希,都可以解释为采用的是 base58btc 基数编码。第二个示例以 b 开头,这是 base32 的基数编码前缀标识符,大多数 IPFS 实现默认使用 base32



4 One hash, multiple CID versions

我们可以将任何的 IPFS CID 粘贴到 CID Inspector 中,以可视化其所有前缀及其代表的内容。



4.1 示例 1:CIDv1

bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi

通过 CID Inspector 工具查看结果:

在这里插入图片描述

我这里只截取了一部分,请自行查看剩余部分。

我们可以看到工具为我们解析了许多部分:

  • 人类可读 CID:将 CID 的每个部分分解为人类可以轻松阅读的形式;
  • 多基数:基数的标识符,在这个例子中是 b,代表 base32
  • 多编码:编码的标识符,在这个例子中是 0x70,代表 dag-pb,一种 IPLD 格式;
  • 多哈希:将多哈希分解为所使用的哈希算法、哈希的长度、内容哈希本身。

其中,18 是哈希算法 sha2-256 的代码,哈希的长度是 256 位即 32 字节,内容哈希本身是十六进制的摘要。

从 “人类可读 CID” 中,我们可以看到在添加 CIDv1 的前缀之前,内容的原始哈希是:

C3C4733EC8AFFD06CF9E9FF50FFC6BCD2EC85A6170004BB709669C31DE94391A


4.2 示例 2:CIDv0

QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR

通过 CID Inspector 工具查看结果:

在这里插入图片描述

在 CIDv0 的结果中,多基数和多编码都显示为 “implicit”。这是由于 CIDv0 没有这两个前缀,因此它们被分别默认为 base58btcdag-pb

在原文的截图中,两个前缀都显示的是 “implicit”,但是我查看到的多编码并不是 “implicit”。

在 CIDV1(Base32) 标签下,我们看到:

bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi

这与第一个示例中的 CID 完全相同!CID 检查器为我们提供了从 CIDv0 到 CIDv1 的转换。

注意,CIDv0 示例与 CIDv1 示例中的 “人类可读 CID” 的末尾完全相同:

C3C4733EC8AFFD06CF9E9FF50FFC6BCD2EC85A6170004BB709669C31DE94391A

这是因为这两个 CID 指向相同的内容,即本质上两个 CID 代表的是相同的哈希。



4.3 转换 CID 的版本

我们可以将任何的 CIDv0 转换为 CIDv1,但不能将任何的 CIDv1 转换为 CIDv0 。这是由于 CIDv1 支持多编码和多基数,而 CIDv0 不支持。事实上,只有具有以下属性的 CIDv1 可以转换为 CIDv0:

  • 多基数 = base58btc
  • 多编码 = dag-pb
  • 多哈希算法 = sha2-256
  • 多哈希长度 = 32 字节

为了测试这个理论,你可以查看我们亲爱的 土豚 图片,它托管在 IPFS 网络上:

https://ipfs.io/ipfs/QmcRD4wkPPi6dig81r5sLj9Zm1gDCL4zgpEj9CfuRrGbzF

首先,从 URL 末尾复制 CID:

QmcRD4wkPPi6dig81r5sLj9Zm1gDCL4zgpEj9CfuRrGbzF

然后,将 CID 粘贴到 CID Inspector 工具中,并在页面底部找到等效的 CIDv1 值:

bafybeigrf2dwtpjkiovnigysyto3d55opf6qkdikx6d65onrqnfzwgdkfa

最后,将原始 URL 中的 CID 替换为转换后的 CID:

https://ipfs.io/ipfs/bafybeigrf2dwtpjkiovnigysyto3d55opf6qkdikx6d65onrqnfzwgdkfa

你应该看到的是相同的土豚图片。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/318286.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第8章 软件工程

一、软件工程概述 &#xff08;一&#xff09;软件危机 1、含义&#xff1a;落后的软件生产方式无法满足迅速增长的计算机软件需求&#xff0c;从而导致软件开发与维护过程中出现一系列严重问题的现象。 2、解决方案&#xff1a;引入软件工程的思想。 &#xff08;二&#x…

【MySQL | 第十篇】重新认识MySQL索引匹配过程

文章目录 10.重新认识MySQL索引匹配过程10.1匹配规则10.2举例&#xff1a;联合索引遇到范围查询&#xff08;>、<、between、like&#xff09;10.2.1例子一&#xff1a;>10.2.2例子二&#xff1a;>10.2.3例子三&#xff1a;between10.2.4例子四&#xff1a;like 10…

一对一WebRTC视频通话系列(一)—— 创建页面并显示摄像头画面

本系列博客主要记录WebRtc实现过程中的一些重点&#xff0c;代码全部进行了注释&#xff0c;便于理解WebRTC整体实现。 一、创建html页面 简单添加input、button、video控件的布局。 <html><head><title>WebRTC demo</title></head><h1>…

机器学习之基于Tensorflow(LSTM)进行多变量时间序列预测股价

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 项目简介&#xff1a;机器学习之基于TensorFlow&#xff08;LSTM&#xff09;进行多变量时间序列预测股价 一、项目…

HTML5本地存储账号密码

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>HTML5本地存储账号密码</title> </head…

ROS快速实现helloworld

ROS中涉及的编程语言以C和Python为主&#xff0c;ROS中的大多数程序两者都可以实现&#xff0c;在本系列教程中&#xff0c;每一个案例也都会分别使用C和Python两种方案演示&#xff0c;大家可以根据自身情况选择合适的实现方案。 ROS中的程序即便使用不同的编程语言&#xff…

leetcode51.N皇后(困难)-回溯法

思路 都知道n皇后问题是回溯算法解决的经典问题&#xff0c;但是用回溯解决多了组合、切割、子集、排列问题之后&#xff0c;遇到这种二维矩阵还会有点不知所措。 首先来看一下皇后们的约束条件&#xff1a; 不能同行不能同列不能同斜线 确定完约束条件&#xff0c;来看看究…

Uniapp好看登录注册页面

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

Kafka(十二)Streams

目录 Streams1 什么式是流式处理2 流式处理的相关概念2.1 拓扑2.2 时间2.2.1 输入时间2.2.2 输出时间 2.3 状态2.4 流和表2.5 时间窗口2.5.1 测试时间窗口 2.6 处理保证 3 流式处理设计模式3.1 单事件处理3.2 使用本地状态3.3 多阶段处理和重分区3.4 使用外部查找&#xff1a;流…

日本宇宙航空研究“Int-Ball2”自由飞行相机机器人采用的Epson IMU

IMU有助于飞行的稳定控制和电池充电的自动对接- 精工爱普生公司&#xff08;TSE:6724&#xff0c;“Epson”&#xff09;很高兴地宣布&#xff0c;日本宇宙航空研究开发机构&#xff08;JAXA&#xff09;选择了爱普生M-G370系列的惯性测量单元&#xff08;IMU&#xff09;&…

附录6-4 黑马优购项目-分类和购物车

目录 1 分类 1.1 接口 1.2 窗口限制 1.3 选中状态样式判断 1.4 点击左侧时右侧会到顶点 1.5 源码 2 购物车 2.1 store 2.2 tabBar徽标 2.3 滑动删除 2.4 结算 2.4.1 结算前登录 2.4.2 结算功能 2.5 触发组件事件 2.6 源码 1 分类 分类最上部是…

JAVA面试专题-微服务篇

Spring cloud Spring Cloud 5大组件有哪些 注册中心/配置中心&#xff1a;nacos 负载均衡&#xff1a;Ribbon 服务远程调用&#xff1a;Feign 服务保护&#xff1a;sentinel 服务网关&#xff1a;Gateway 微服务注册和发现 nacos和eureka的区别 负载均衡 微服务向Ribbon发送…

unity制作app(3)--gps定位

1.unity中定位Unity之GPS定位&#xff08;高德解析&#xff09;_unity gps定位-CSDN博客 代码需要稍微修改一下&#xff0c;先把脚本绑到一个button上试一试&#xff01; 2.先去高德地图认证&#xff08;app定位&#xff09; 创建应用和 Key-Web服务 API | 高德地图API (ama…

Golang | Leetcode Golang题解之第64题最小路径和

题目&#xff1a; 题解&#xff1a; func minPathSum(grid [][]int) int {if len(grid) 0 || len(grid[0]) 0 {return 0}rows, columns : len(grid), len(grid[0])dp : make([][]int, rows)for i : 0; i < len(dp); i {dp[i] make([]int, columns)}dp[0][0] grid[0][0]…

场景文本检测识别学习 day06(Vi-Transformer论文精读、MAE论文阅读)

Vi-Transformer论文精读 在NLP领域&#xff0c;基于注意力的Transformer模型使用的非常广泛&#xff0c;但是在计算机视觉领域&#xff0c;注意力更多是和CNN一起使用&#xff0c;或者是单纯将CNN的卷积替换成注意力&#xff0c;但是整体的CNN 架构没有发生改变VIT说明&#x…

【知识学习/复习】损失函数篇,包含理解应用与分类:回归、分类、排序、生成等任务

损失函数总结 一、损失函数理解二、不同任务的损失函数的应用1.图像分类2.目标检测3.语义分割4.自然语言处理&#xff08;NLP&#xff09;5.图神经网络&#xff08;GNN&#xff09;6.生成式网络 三、损失函数1. 回归任务损失函数常见损失函数IoU系列损失函数1. IoU损失函数&…

计算机网络chapter2——应用层

文章目录 第2章 应用层章节引出—— 2.1应用层协议原理2.1.1 网络应用程序体系结构&#xff08;1&#xff09;客户-服务器体系结构&#xff08;2&#xff09;对等(P2P)体系结构2.1.2 进程通信1.客户和服务器进程2.进程与计算机网络之间的接口3. 进程寻址 2.1.3 可供应用程序使用…

【Cpp】类和对象

标题&#xff1a;【Cpp】类和对象 水墨不写bug 正文开始&#xff1a; &#xff08;一&#xff09;面向过程与面向对象 面向过程和面向对象是两种不同的编程思想。 面向过程指的是将程序分解成多个步骤&#xff0c;每个步骤都是一个独立的函数&#xff0c;通过函数之间的调用实…

# notepad++ 编辑器英文版,如何打开自动换行

notepad 编辑器英文版&#xff0c;如何打开自动换行 在Notepad中&#xff0c;如果你想要开启自动换行功能&#xff0c;可以按照以下步骤操作&#xff1a; 1、打开 Notepad 编辑器。 1.1. 依次点击菜单栏中的【视图】&#xff0c;英文版对应【View】。1.2. 在【视图】下拉菜单…

自动化机器学习流水线:基于Spring Boot与AI机器学习技术的融合探索

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…