【翻译】能够验证多种签名算法的新点子: Chained Locks !

原文:

当我们在开发 CKB 时,我们有如在探索一个未曾访问过的仙境。这意味着我们的设计选择有时可能会出现问题。例如,CKB 中的动态链接(dynamic linking)被证明是弊大于利的东西。因此,我们决定废除它,以支持即将在下一个硬分叉中出现的Exec。

这仍然留下了一个未解决的问题:有时你在一个 lock script 要验证多个不同的签名。通过动态链接,人们可以在当前的虚拟机中加载多种签名验证算法。另一方面,Exec只用 callee 脚本来代替 caller 脚本,callee 脚本只是以一个返回码退出,而不返回 caller 脚本。我们应该如何使用基于exec 的设计来验证多个不同的签名?
译注:Caller 是调用者,Cellee 则是被调用的对象

在本文,我们要来探索下 chained locks 的想法:

一个 Chained lock 看起来就像一个普通的 lock script ,你甚至可以像普通的 lock script 一样使用它。每个 chained lock script 都包含一个特定的签名算法的验证代码,例如,我们可能有secp256k1、secp256r1、RSA、Schnorr、BLS等的 chained lock script。这里的技巧在于,你可以一次执行 chained lock script 的两个不同路径。

常规的执行方式

回顾一下,CKB 脚本的入口点(entrypoint),与 Linux 程序完全一样。

int main(int argc, char* argv[]) {
  // 实际的代码逻辑...
}

通常情况下,当 CKB 执行 lock script 时,argc 为 0,而 argv 则完全为空。在这种情况下,chained lock script 的执行与通常的 lock script 完全一样:它运行 sighash_all 算法来计算签名信息,然后从当前脚本组中的第一个 witness 身上提取签名,然后执行实际的签名验证算法。

执行 Exec

当一个脚本通过 exec syscall 加载和执行时,caller 脚本可以向入口主函数使用的 argc/argv 接口提供参数。当 argc 不为零时,一个 chained lock script 将进入 exec execution模式。

exec execution下,一个 chained lock scipt 将预期 argv 中的每一项都采取以下形式:
code hash in hex>:<hash type in hexmessage 1>:<signature 1>:<message 2>:<signature 2>:...:<message n>:<signature n>

由于 argv 包含以 null 结尾的字符串,argv 中包含的项目的每个组成部分都使用十六进制编码。chain lock script 将以下列逻辑进行:

  • 对于 argv[0] 中包含的每个消息/签名对,chained lock id 也将执行自己的签名验证逻辑。如果任何消息/签名对导致错误状态,lock script 也将以错误状态退出。

  • 如果 argc 正好是 1,chained lock script 就会返回「成功」的返回码。

  • chained lock script 将使用 argv[1] 中包含的 code hash 和hash type 来定位 cell 。然后它会从 argvs 中删除argv[0],然后使用其余的参数来调用exec

使用行为

在这个新的设计中,每个单独的签名验证算法,如 secp256k1、Schnorr、RSA 等,都会有一个 chained lock script 部署到 Nervos CKB。一个 dapp 可以先建立一个 entrypoint lock script,他负责交易的一般验证,然后按照上述格式准备一系列的签名项目进行签名。范例如下 :

┌─────────────────┐
│ │
│ Entrypoint Lock │
│ │
└───────┬─────────┘



┌───────▼─────────┐
│ │
│ RSA │
│ │
└───────┬─────────┘



┌───────▼─────────┐
│ │
│ secp256r1 │
│ │
└─────────────────┘

如例子所示,entrypoint lock 首先被使用 exec 调用 RSA chained lock ,然后调用 secp256r1 chainlock 进行更多验证。 entrypoint lock 准备的参数可能看起来像下面这样:
<RSA code hash>:<RSA hash type>:<message 1>:<signature 1> <secp256r1 code hash>:<secp256r1 hash type>:<message 2>:<signature 2>:<message 3>:<signature 3>

这里消息/签名对1 将通过 RSA 逻辑验证,而消息/签名对 2 和 3 则作为 secp256r1 签名进行验证。

通过这种方式,我们可以将 dApps 的 lock 与签名验证的 lock 解耦。lock script 还能够支持任意的、动态的签名验证算法。

3 Likes