从 omnilock 讲起(一)
最近一个月,工作内容有了新的变化,一切围绕着 omnilock 进行,为它添加 rust-sdk 的支持,这个合约在本身已经很复杂了,它支持多种算法多种模式同时验证,而最近的一次大改动是为这个 lock 加上了 cobuild 模式的支持,从而变得更加复杂了,各种模式都几乎是正交的,分支功能承指数级别上升,对应灵活性提升的代价是复杂度急剧提高,要做全功能支持的 sdk 并不是一件简单的事情,经过一个多月的努力,形成了一个 PR ,大部分场景已经覆盖完成,考虑到这个合约的复杂性,开了这个系列的 blog,个人希望通过这个系列的文章,能让一部分人从最基础的合约验证开始,逐步理解到 omnilock transaction 应该怎么正确构建,并了解 omnilock 的整体功能,方便在后续项目中选择性使用。
交易与验证
在区块链世界,所谓的交易本质上都是链上状态的修改,根据链的不同又有各自独特的属性。而链上状态的修改都需要在链上验证该修改的是否有权限,根据不同的链,具体验证方式不一样,但大体上都使用了非对称加密算法,大部分链的算法是固定的,对应的公私钥对和地址的关系也相对简单,而 ckb 上的情况就复杂很多。
在 ckb 上,所有的链上信息都表现为一个个单独的 cell 结构,每个 cell 有自己单独的 lock script、type script、data 区,任意交易在 ckb 上体现为任意 cell 的逝去和对应 cell 的生成,cell 的生成数据在链下已经确定了,链上只做验证。cell 的 lock script 是解锁 cell 的关键,它可以指向任意密码学库,同时 lockscript 上的 args
字段将指明解锁的条件,以 ckb 默认的解锁脚本为例,它的 args
上放的就是 black2b_256(pubkey)[0..20]
,而这个系列文章的主角 omnilock 由于它的复杂性,args
上需要表达的东西会更多,也更复杂,后面我们再细说。
由于 ckb 上 lock script 的复杂性叠加上 vm 版本迭代的问题,在 ckb 第一次 hardfork 的时候,提出了一个 RFC 让 ckb 的地址上体现出 lock script 的功能,让钱包和交易者能通过地址确定该 cell 对应的算法是什么,从而更方便地进行解锁操作。
Omnilock 的诞生
在经历过一系列的探索之后,ckb 链上成功出现了多种不同功能的 lockscript,但彼此之间无法进行交互,并且想要同时支持不同的 lock 对各个生态方都会带来相对大的开发压力,并且,随着时间的变化,lock 可能会不断增加,可见的未来这个预期几乎是确定性的。
为了尝试整合各种 lock,nervos 推出了 omnilock 的设计,通过 args
上 auth
的设计,来区分不同的算法(验证方式),而对应的 auth
的 args 将顺延放在 auth 的后面,即 lock script 上的 args 结构变成了 <21 byte auth> <Omnilock args>
这样的结构。
而 auth 又由两部分组成,分别为 1 byte 的 flags
和 20 byte 的 auth content
。flags 确定验证的加密算法,auth content 为不同的算法所验证的东西,比如,flag 为 0x0 时,auth content 即为与 ckb 默认的 lock script 一样的 black2b_256(pubkey)[0..20]
。
到目前为止,omnilock 已经支持了 12 个 flag,分为两大类:
-
对各种链算法的模拟(即支持各种其他链的验证方式)
- ckb 默认的 PubkeyHash
- Ethereum
- Eos
- Tron
- Bitcoin(暂不支持 P2TR)
- Dogecoin
- Solana(主网暂时没有)
- EthereumDisplay
-
特殊模式下的解锁行为
- Multisig
- Ownerlock
- Exec
- Dl
-
特殊模式的支持
- Regulation Compliance Extension
- Anyone-Can-Pay Lock
- time-lock mode
- supply mode
至此,omnilock 已经能够以一个 lock 支持多种不同的算法和行为,几乎是一个 lock 集大成者,但同时,正是因为它的功能性,也带来了不少复杂性。
CoBuild 与 Omnilock
在经历了一段时间之后,nervos 与各个生态方在 ckb 的实际使用过程中发现了一些问题,想要尝试使用一种链外协议来规定和统一合作方之间的交易构造过程,让用户、应用方、钱包能够在同一套行为协议下更有效更安全地构造交易,于是提出了 cobuild 的设想。
cobuild 希望能通过定义一套标准的构建交易流程和动作,统一化交易构建的交互流程,omnilock 也需要支持 cobuild 标准,这样,在支持各种算法和功能的基础上,omnilock 增加了对 cobuild 交易构建的支持,即到目前为止,omnilock 同时支持两种不同的交易构建过程,并且每种过程同时支持上诉的所有算法和解锁方式,复杂度 * 2。
小结
接下来几章,我们将面对的就是这样一个功能强大同时复杂性拉满的 omnilock,好消息是,我们不需要实现它,坏消息是,我们需要构建所有能通过 omnilock 验证的交易,并实现对应的签名方式。