CID规范

本文作者:星际联盟 原创作品,转载请注明出处

CID被广泛应用在IPFS项目中,而Filecoin又是以IPFS为基础进行构建的项目,自然也在很多地方使用到了CID,CID本身是一串编码的字符串,给我们的理解带给困难。
本文将从以下几点对CID进行介绍,以期读者对CID能有一个较为全面的认识。

CID是什么


一个CID就是一个“自描述的基于内容寻址的标识符”,使用加密哈希达到内容寻址的目的,使用了若干种multiformats来实现灵活的“自描述”,也就是用multihash来表示哈希,用multicodec表示数据内容格式,使用multibase以将CID编码成字符串形式。
具体来说,它是一个“类型化的内容地址”,是基于(内容类型,内容地址)的元组。

CID的设计动机


CID是一种在像IPFS这样的分布式系统中用于引用内容的格式,它利用了“内容寻址”,“加密哈希”,和“自描述格式”,被IPFS和IPLD项目用作核心标识符。

CID的工作方式


CID的当前版本是 CIDv1。
v1版的CID包含四部分:

<cidv1> ::= <mb><version><mc><mh>

展开后的形式如下:

<cidv1> ::= <multibase-prefix><cid-version><multicodec-content-type><multihash-content-address>

其中

  • 是一个multibase码(占用1或2个字节),用以使将CID编码进不同的base变得更容易。
    注:当编码清晰无异义时,二进制(非基于文本的)协议和格式可能会忽略这个前缀
  • 用于表示CID版本的varint编码,目标是维护版本的可升级性。
  • 一个multicodec编码,用于表示要寻址的数据的内容类型或格式。
  • 一个multihash值,代表要寻址内容加密哈希值。出于维护可升级性和协议灵活性的目的,multihash使CID能使用不同的加密哈希函数。

设计考量


CID的设计深深地考虑了在构建IPFS过程时出现的各种权衡因素。这些权衡考量主要来自multiformats项目:

  • 简洁性:CID本质上是二进制的,目的就是使其尽量地简洁紧凑,因为它注定要成为更长的路径标识或URL的一部分。
  • 传输友好性:也可叫“可复制性”,CID使用multibase编码,这样就能允许为了可传输性以选择最好的base。例如,CID可被编码进base58btc以产出更短且容易复制粘贴的哈希值。
  • 多功能性:CID注定要能够表示任意格式的值,这些值可能使用任意加密哈希进行编码。
  • 避免锁定:CID会阻止锁定老旧的,有潜在过时可能的决策。
  • 可升级性:CID编码一个版本号以保证CID格式自身的演进。

人类可读的CID


就算是仅仅为了调试和说明,拥有人类可读的CID的描述也是极为有益的。我们可以简单地将一个CID转化为像下面这样的“人类可读CID”:

<hr-cid> ::= <hr-mbc> "-" <hr-cid-version> "-" <hr-mc> "-" <hr-mh>

其中每一个子项都使用其自身的人类可读形式来表示:

  • 人类可读的multibase码,如base58btc
  • 是形如“cidv#”的字符串,如cidv1或cidv2
  • 人类可读的multicodec码,如cbor
  • 人类可读的multihash,如sha2-256-256-abcdef0123456789…

请看下面的示例:

# 示例 CID
zb2rhe5P4gXftAwvA4eXQ5HJwsER2owDyS9sKaQRRVQPn93bA
# 对应的人类可读CID
base58btc - cidv1 - raw - sha2-256-256-6e6ff7950a36187a801613426e858dce686cd7d7e3c0fc42ee0330072d245c95

版本


CIDv0

CIDv0一个向后兼容的版本,其中:

  • 字符串的multibase部分的表示永远是base58btc或隐式的(不写明的)
  • multicodec部分永远是dag-pb或隐式的
  • cid-version部分永远是cidv0或隐式的
  • multihash部分写作并永远是一个完整的(32位长)的sha256哈希值
cidv0 ::= <multihash-content-address>
CIDv1

详见“CID的工作方式”一节

<cidv1> ::= <multibase-prefix><cid-version><multicodec-content-type><multihash-content-address>

解码算法


想要解码一个CID,需要参照以下算法流程:
1.若CID是一个ASCII或UTF-8编码的字符串:

  • 若长度为46个字符且以”Qm…”开头,则是一个v0版本的CID,按照base58btc解码并跳至第2步。
  • 若不是,依照multibase规范解码并:
    • 若解码出的首个字节是0x12,直接返回错误。
    • 否则,你拥有的就是一个二进制CID,请跳转到步骤2继续。

2.给定一个二进制的CID:

  • 如果长度有34个字节且开头的字节是[0x12, 0x20, …],则是v0版的CID。
    • 此CID的multihash是 cid
    • 此CID的multicodec是 DagProtobuf
    • 此CID的版本是0
  • 否则,把N 作为CID内的第一个varint,可如此计算版本号
    • 若N等于1,则版本是CIDv1:
      ♦ 此CID的multicodec是CID中的第二个varint
      ♦ 其multihash是CID的剩余部分(位于第二个varint之后)
      ♦ 版本号是1
  • 若N小于或等于0,则本CID是畸形有误的
  • N大于1的版本号是保留的,暂未被使用。

实现列表


目前CID规范有着以下不同语言的实现

https://juejin.im/post/5e12ea105188253a821082be

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论