Principal id
pid 的生成是由 IC 系统内部控制的。这里可以看到更多关于 pid 的设计机制的内容。
目前主要有两种方式:
- 系统随机生成的不透明 ID
这是最常见的一种形式。系统会使用随机数生成器随机生成一个 0-29 字节长度的二进制值,并在末尾添加 0x01 。这个过程完全由系统内部控制,外部无法影响,所以对外是不透明的。这种 ID 是随机生成的。
- 根据公钥生成的自认证 ID
这种 pid 需要一个外部的公钥,一般是用户控制的公钥。系统会对这个公钥进行 DER 编码,然后取其 SHA-224 哈希,再在末尾连接 0x02 ,构成一个 29 字节的 Principal id 。拥有对应的私钥的用户就可以使用这个 ID 进行认证和签名等操作。
- 系统也可以从已有的 Principal 派生出新的 ID ,具体方法是:
给 Principal 连接一个 nonce ,计算哈希值,再连接 0x03 。这样就产生了一个只有该 Principal 才能注册的 ID 空间。
- 匿名 ID
它的形式为 0x04
,用于匿名调用者。它可以在没有签名的情况下向 IC 网络发送调用和查询请求。
- 保留 ID
保留 ID 是一个特殊的 Principal 格式,它不是真正的 ID ,但具有类似的格式,可为 Dapp 提供更多表达能力。
格式为:
blob · 0x7f
, 0 ≤ |blob| < 29
(一个 0 - 28 字节的任意字节序列 + 0x7f )
保留 ID 不对应于任何实际的主体,它目的是用于 Dapp 想要重用 Principal 的文本表示格式,但是明确表示这个 ID 不指向一个真实的 Canister 或用户。
举个例子,如果一个 Dapp 需要显示一个类似 Principal 的 ID ,但是这个 ID 并不代表一个真正的 pid ,那么它可以构造一个保留 ID ,比如:
0x123456789520 + 0x7f
这样就生成了一个保留 ID ,它有一个类似 Principal 的文本表示格式,但是 Dapp 和系统都知道它不对应真正的主体。
保留 ID 的最大长度也是 29 字节,和其他形式的 Principal 一致。它只由 Dapp 构造,系统在生成新的 Principal 时不会构造出保留 ID 。
Principal 的文本格式是这样定义的:
- 对原始 Principal 的二进制值计算 4 字节 CRC32 校验。
- 将校验之和连接在 Principal 值前面。
- 对连接的结果用 Base32 编码。
- 每 5 个字符插入一个 "
-
" 作为分隔符,分组显示。 - 统一用小写字母显示。
举个例子,对于 ID 为 0xABCD01 的 Principal :
- 它的 CRC32 校验和是 0x233FF206 。
- 连接校验和后进行 Base32 编码,结果是 em77ebvlzuaq 。
- 每 5 个字符插入 "
-
" ,则文本格式是 em77e-bvlzu-aq 。
这样的格式有很多好处:
- 统一的显示格式,适用于不同场景
- 长度固定,最长 63 字节,易处理
- CRC 校验可检测转换错误
- 不区分大小写,解析简单