区块链 | 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.mfbz.cn/a/588295.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

stm32单片机开发四、USART

串口的空闲状态时高电平&#xff0c;起始位是低电平&#xff0c;来打破空闲状态的高电平 必须要有停止位&#xff0c;停止位一般为一位高电平 串口常说的数据为8N1&#xff0c;其实就是8个数据位&#xff08;固定的&#xff09;&#xff0c;N就是none&#xff0c;也就是0个校验…

审计师能力与专长数据集(2014-2022年)

01、数据介绍 审计师是专门从事审计工作的人员&#xff0c;他们对企业、政府机关、金融机构等组织进行独立的、客观的、合法的审计&#xff0c;以评估这些组织的财务状况、经营绩效和风险水平。审计师通过收集和评估证据&#xff0c;以确定被审计单位的财务报表是否公允、合法…

[数据结构]———交换排序

目录 1.交换排序 第一个定义了一个名为Swap的函数 第二个三数取中 2.冒泡排序 代码解析 冒泡排序的特性总结&#xff1a; 3.快速排序 1. hoare版本 2. 挖坑法 代码解析 3. 前后指针版本 代码解析 1.交换排序 基本思想&#xff1a;所谓交换&#xff0c;就是根据序列中两…

MyBatis-plus笔记——条件构造器和常用接口

wapper介绍 Wapper&#xff1a;条件构造抽象类 AbstractWapper&#xff1a;用于查询条件封装&#xff0c;生成 sql 的 where 条件 QueryWrapper&#xff1a;查询条件封装UpdateWrapper&#xff1a;Update 条件封装AbstractLambdaWrapper&#xff1a;使用Lambda语法 LambdaQuery…

五一假期Llama 3之魔改不完全攻略(Part 2)

2024年4月18日&#xff0c;Meta AI 正式宣布推出 Llama 3&#xff0c;这标志着开源大型语言模型&#xff08;LLM&#xff09;领域的又一重大进步。如同一颗重磅炸弹&#xff0c; Llama 3 以其卓越的性能和广泛的应用前景&#xff0c;预示着 AI 技术的新时代。 目前开源的是Lla…

Agent AI智能体:机器学习与自我优化的奇妙之旅

文章目录 &#x1f4d1;前言一、Agent AI智能体的基本概念二、Agent AI智能体的技术进步2.1 机器学习技术2.2 自适应技术2.3 分布式计算与云计算 三、Agent AI智能体的知识积累3.1 知识图谱3.2 迁移学习 四、Agent AI智能体的挑战与机遇4.1 挑战4.2 机遇 小结 &#x1f4d1;前言…

ASP.NET网络商店设计与实现

摘 要 本文首先系统地研究了开发电子商务网站的背景和意义&#xff0c;分析了当今B2C电子商务交易的网站特点和共性&#xff0c;从而得出设计本网站的思路和方法。接着介绍了实现系统开发的ASP.NET和IIS5.0环境&#xff0c;数据库用ACCESS实现。同时简要介绍了以上工具的功能…

手拉手springboot整合kafka

前期准备安装kafka 启动Kafka本地环境需Java 8以上 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。 Kafka启动方式有Zookeeper和Kraft&#xff0c;两种方式只能选择其中一种启动&#xff0c;不能同时使用。 Kafka下载…

状态模式

文章目录 1.UML类图2.状态基类3.状态实现类3.状态机管理类使用示例 1.UML类图 2.状态基类 public abstract class State {public string? Name { get; set; }public StateMachine? StateMachine {get; set;}public abstract void Exit();public abstract void Enter(); }3.…

Devops部署maven项目

这里讲下应用k8s集群devops持续集成部署maven项目的流程。 failed to verify certificate: x509: certificate signed by unknown authority 今天在执行kubectl get nodes的时候报的证书验证问题&#xff0c;看了一圈首次搭建k8s的都是高频出现的问题。 couldn’t get curren…

输入N,从1~N中挑出若干对数字,比如(a,b),(c,d)

题目: 输入N,从1~N中挑出若干对数字,比如(a,b),(c,d) 规定这个数对的value为两数之和,比如(a,b)的value为ab 现在从1~N中挑出若干个数对,他们满足: 每个数字只能被挑出一次 每个数对的value都不相等 每个数对的value都小于等于N 求:对于给定的N,能挑出这样的数对的最大个数max …

2024年Q1葡萄酒行业线上电商(京东天猫淘宝)销售排行榜

五一聚餐不可缺少饮品——葡萄酒。鲸参谋监测的线上电商平台&#xff08;某东&#xff09;Q1季度葡萄酒行业销售数据已揭晓&#xff01; 从鲸参谋的数据中&#xff0c;我们可以明显看到今年Q1季度在线上电商平台&#xff08;某东&#xff09;葡萄酒行业的销售情况呈现出积极的…

【C++】STL使用详解

文章目录 前言1. string类1.1 string类对象的常见构造1.2 string类对象的容量操作1.3 string类对象的访问及遍历操作1.4 string类对象的修改操作1.5 string类非成员函数 2. vector2.1 vector的介绍2.2 vector的使用2.3 vector的迭代器2.4 vector空间容量操作2.5 vector增删查改…

笨蛋学C++之 C++连接数据库

笨蛋学C 之 VS2019使用C连接数据库 创建数据库SQL语句VS2019选择空项目&#xff0c;点击下一步创建输入项目名称&#xff0c;点击创建创建成功点击新建项创建源文件因为mysql是64位&#xff0c;此时的c项目是86位&#xff0c;所以这里需要将项目修改为x64位点击项目 -> 0501…

基于Python的人脸识别系统设计与实现(论文+源码)_kaic

基于Python的人脸识别系统设计与实现 摘 要 随着人工智能的发展,人脸识别系统在我们的生活中越来越被广泛应用。人脸识别系统是指能够从数字图像或视频源中识别人的技术。人脸识别系统可以通过多种方法工作&#xff0c;但是&#xff0c;它们通常是通过将给定图像中的面部特征与…

基于Vue Router和element-ui的LayOut

一、展示 二、代码 app.vue <template><div id"app"><el-container style"border: 1px solid #eee; height: 100vh"><el-aside v-bind:width"asideWidth" style"background-color: rgb(48, 65, 86);"><…

基于ROS从零开始构建自主移动机器人:仿真和硬件

书籍&#xff1a;Build Autonomous Mobile Robot from Scratch using ROS&#xff1a;Simulation and Hardware 作者&#xff1a;Rajesh Subramanian 出版&#xff1a;Apress 书籍下载-《基于ROS从零开始构建自主移动机器人&#xff1a;仿真和硬件》您将开始理解自主机器人发…

ip地址与硬件地址的区别是什么

在数字世界的浩瀚海洋中&#xff0c;每一台联网的设备都需要一个独特的标识来确保信息的准确传输。这些标识&#xff0c;我们通常称之为IP地址和硬件地址。虽然它们都是用来识别网络设备的&#xff0c;但各自扮演的角色和所处的层次却大相径庭。虎观代理小二将带您深入了解IP地…

karpathy make more -- 4

1 Introduction 这个部分要完成一个网络的模块化&#xff0c;然后实现一个新的网络结构。 2 使用torch的模块化功能 2.1 模块化 将输入的字符长度变成8&#xff0c;并将之前的代码模块化 # Near copy paste of the layers we have developed in Part 3# -----------------…

爬虫学习:基本网络请求库的使用

目录 一、urllib网络库 1.urlopen()方法 2.request方法 二、requests网络请求库 1.主要方法 2.requests.get()和requests.post() 一、urllib网络库 1.urlopen()方法 语法格式&#xff1a; urlopen(url,data,timeout,cafile,capath,context) # url:地址 # data:要提交的数据…