CID (内容标识符)

Swift Package Manager compatible Build & Test (macos and linux)

用于分布式系统的自描述内容寻址标识符

目录

概述

CID 是一种自描述的内容寻址标识符。它使用加密哈希来实现内容寻址。它使用多种 multiformats 来实现灵活的自描述性,即使用 multihash 用于哈希,multicodec 用于数据内容类型,以及 multibase 用于将 CID 本身编码为字符串。

安装

要在您的 swift 项目中使用 CID,只需将该软件包作为依赖项包含在您的 Package.swift 中即可

let package = Package(
    ...
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        .package(url: "https://github.com/swift-libp2p/swift-cid.git", .upToNextMajor(from: "0.0.1")),
        ...
    ],
    ...
        .target(
            ...
            dependencies: [
                ...
                .product(name: "CID", package: "swift-cid"),
            ]),
    ...
)

使用方法

示例

从 v0 CID 字符串初始化 v0 CID

import CID

let mhStr = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"
let cid = try CID(mhStr)

cid.codec => .dag_pb
cid.code => 112
cid.version => .v0
cid.multibase => .base58btc
cid.toBaseEncodedString => "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"
cid.multihash.asString(base: .base58btc) => "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"

从 Multibase 编码的 v1 CID 字符串初始化 v1 CID

let peerIdStr = "k51qzi5uqu5dj16qyiq0tajolkojyl9qdkr254920wxv7ghtuwcz593tp69z9m" //LibP2P peerID
let cid = try CID(peerIdStr)

cid.codec => .libp2p_key
cid.code => 114
cid.version => .v1
cid.multibase => .base36
cid.toBaseEncodedString => "k51qzi5uqu5dj16qyiq0tajolkojyl9qdkr254920wxv7ghtuwcz593tp69z9m"

从部分初始化 v1 CID

let mh = try Multihash(raw: "abc", hashedWith: .sha2_256)
let cid = try CID(version: .v1, codec: .dag_cbor, multihash: mh)

cid.codec => .dag_cbor
cid.code => 113
cid.version => .v1
cid.multibase => .base32
cid.toBaseEncodedString => "bafyreif2pall7dybz7vecqka3zo24irdwabwdi4wc55jznaq75q7eaavvu"

查看 CIDTests.swift 以获取有关如何实例化和使用 CID 的更多示例

API

/// Initializers
/// Specify the version, codec and hash
CID.init(version:CIDVersion, codec:Codecs, hash:[UInt8])
CID.init(version:CIDVersion, codec:Codecs, hash:String)

/// From a Multihash
CID.init(v0WithMultihash multihash:Multihash)

/// From a CID compliant String / Data
CID.init(_ cid:String)


/// Properties
/// Integer based Enum, currently supports v0 or v1
CID.version:CIDVersion

/// The `Codec` used (ex: 'dag-pb')
CID.codec:Codecs

/// The Multibase used for encoding (ex: 'base32')
CID.multibase:BaseEncoding

/// The CIDs Multihash
CID.multihash:Multihash

/// Returns the Integer code of the Codec used by this CID (ex: dag-pb' -> 112)
CID.code:Int 

/// Returns the entirety of the CID as Bytes (Prefixs and Multihash Digest)
CID.rawBuffer:[UInt8] 
    
/// Returns the entirety of the CID as Data (Prefixs and Multihash Digest)
CID.rawData:Data
    
/// Returns the CIDs Prefix (includes everything but the multihash digest)
///
/// The CID prefix includes the following...
/// - [version] [codec] [hash-algo] [hash-length]
CID.prefix:[UInt8]


/// Convert between CID versions
CID.toV1()
CID.toV0()

更多信息

它是什么?

CID 是一种用于在分布式信息系统中引用内容的格式,例如 IPFS。它利用 内容寻址加密哈希自描述格式。它是 IPFSIPLD 使用的核心标识符。它使用 multicodec 来指示其版本,使其完全自描述。

您可以在此处阅读关于为什么 IPFS 需要这种格式的深入讨论:ipfs/specs#130(第一篇文章转载于 此处

CID 是一种自描述的内容寻址标识符。它使用加密哈希来实现内容寻址。它使用多种 multiformats 来实现灵活的自描述性,即使用 multihash 用于哈希,multicodec 用于数据内容类型,以及 multibase 用于将 CID 本身编码为字符串。

具体来说,它是一个类型化的内容地址:(内容类型, 内容地址) 的元组。

它是如何工作的?

当前版本:CIDv1

CIDv1 有四个部分

<cidv1> ::= <mb><multicodec-cidv1><mc><mh>
# or, expanded:
<cidv1> ::= <multibase-prefix><multicodec-cidv1><multicodec-content-type><multihash-content-address>

其中

就是这样!

设计考虑

CID 的设计考虑了在构建 IPFS 时遇到的许多困难的权衡。这些主要来自 multiformats 项目。

人类可读的 CID

拥有 CID 的人类可读描述是有利的,仅用于调试和解释的目的。我们可以轻松地将 CID 转换为“人类可读的 CID”,如下所示

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

其中每个子组件都以其自身的人类可读形式表示

例如

# example CID
zb2rhe5P4gXftAwvA4eXQ5HJwsER2owDyS9sKaQRRVQPn93bA
# corresponding human readable CID
base58btc - cidv1 - raw - sha2-256-256-6e6ff7950a36187a801613426e858dce686cd7d7e3c0fc42ee0330072d245c95

参见:https://cid.ipfs.io/#zb2rhe5P4gXftAwvA4eXQ5HJwsER2owDyS9sKaQRRVQPn93bA

版本

CIDv0

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

cidv0 ::= <multihash-content-address>

CIDv1

CIDv1 有四个部分

<cidv1> ::= <mb><multicodec-cidv1><mc><mh>
# or, expanded:
<cidv1> ::= <multibase-prefix><multicodec-cidv1><multicodec-content-type><multihash-content-address>

解码算法

要解码 CID,请按照以下算法操作

  1. 如果它是一个字符串 (ASCII/UTF-8)
  1. 给定一个(二进制)CID (cid)
    • 如果它长度为 34 个字节,并且前导字节为 [0x12, 0x20, ...],则它是 CIDv0。
      • CID 的 multihash 是 cid
      • CID 的 multicodec 是 DagProtobuf
      • CID 的版本是 0。
    • 否则,令 Ncid 中的第一个 varint。这是 CID 的版本。
      • 如果 N == 0x01 (CIDv1)
        • CID 的 multicodec 是 cid 中的第二个 varint
        • CID 的 multihash 是 cid 的其余部分(在第二个 varint 之后)。
        • CID 的版本是 1。
      • 如果 N == 0x02 (CIDv2) 或 N == 0x03 (CIDv3),则 CID 版本是保留的。
      • 如果 N 等于其他一些 multicodec,则 CID 格式错误。

贡献

欢迎贡献!此代码在很大程度上是一个概念验证。我可以向您保证,有更好/更安全的方法可以实现相同的结果。欢迎任何建议、改进,甚至只是批评!

让我们一起使这段代码变得更好!🤝

鸣谢

许可证

MIT © 2022 Breth Inc.