Principal id

pid 的生成是由 IC 系统内部控制的。这里可以看到更多关于 pid 的设计机制的内容。


目前主要有两种方式:

  1. 系统随机生成的不透明 ID

这是最常见的一种形式。系统会使用随机数生成器随机生成一个 0-29 字节长度的二进制值,并在末尾添加 0x01 。这个过程完全由系统内部控制,外部无法影响,所以对外是不透明的。这种 ID 是随机生成的。


  1. 根据公钥生成的自认证 ID

这种 pid 需要一个外部的公钥,一般是用户控制的公钥。系统会对这个公钥进行 DER 编码,然后取其 SHA-224 哈希,再在末尾连接 0x02 ,构成一个 29 字节的 Principal id 。拥有对应的私钥的用户就可以使用这个 ID 进行认证和签名等操作。


  1. 系统也可以从已有的 Principal 派生出新的 ID ,具体方法是:

给 Principal 连接一个 nonce ,计算哈希值,再连接 0x03 。这样就产生了一个只有该 Principal 才能注册的 ID 空间。


  1. 匿名 ID

它的形式为 0x04 ,用于匿名调用者。它可以在没有签名的情况下向 IC 网络发送调用和查询请求。


  1. 保留 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 的文本格式是这样定义的:

  1. 对原始 Principal 的二进制值计算 4 字节 CRC32 校验。
  2. 将校验之和连接在 Principal 值前面。
  3. 对连接的结果用 Base32 编码。
  4. 每 5 个字符插入一个 " - " 作为分隔符,分组显示。
  5. 统一用小写字母显示。

举个例子,对于 ID 为 0xABCD01 的 Principal :

  1. 它的 CRC32 校验和是 0x233FF206 。
  2. 连接校验和后进行 Base32 编码,结果是 em77ebvlzuaq 。
  3. 每 5 个字符插入 " - " ,则文本格式是 em77e-bvlzu-aq 。

这样的格式有很多好处:

  • 统一的显示格式,适用于不同场景
  • 长度固定,最长 63 字节,易处理
  • CRC 校验可检测转换错误
  • 不区分大小写,解析简单