CKB 脚本编程简介[1]: 验证模型
Xuejie Xiao
Nervos Core Team截至目前,CKB 中的 Cell 验证模型或多或少已经趋于稳定,因此我将在这里开始写一系列文章来介绍 CKB 脚本编程。我的目标是补充在阅读白皮书后编写 CKB 脚本所需的所有缺失的细节实现,这样你就可以开始探索 CKB 呈现的这个美丽的仙境。
你可能会注意到我将在 CKB 上运行的代码称为脚本
,而不是智能合约
。这是因为智能合约对我来说是一个令人困惑的术语,我在这里想用另一个词来表示 CKB 独特的可编程性。CKB 中的脚本不一定只是我们在脚本语言中看到的脚本,例如 Ruby,JS,它实际上是指在 CKB VM 上运行的 RISC-V 格式的二进制文件。
这第一篇文章将专门介绍 CKB v0.14.0 中引入的全新验证模型。这可能听起来很无聊,但我保证这是最后一篇没有实际例子的帖子 :P
请注意,尽管我认为 CKB 的编程模型现在非常稳定,但目前仍然在进行开发,因此可能会有变化。我将尽力确保本文始终处于最新的状态,但是如果在过程到任何疑惑,本文以 CKB 的主网 Lina 版本作为依据。
概述
下面一张图片说明了 CKB 的真实交易过程:
这张图中有很多内容,我们将在稍后的文章中再次回到此图。今天,我们将只关注单元数据结构中的2个实体:lock
和type
。
pub struct CellOutput { pub capacity: Capacity, pub lock: Script, #[serde(rename = "type")] pub type_: Option<Script>,}
从数据结构中我们可以看到lock
和type
共享相同的结构,稍后我们可以证明它们也是在同一个环境中执行的,它们之间的差异只是在几个小细节中:
lock
是必须的, whiletype
是可选项- 通常, 他们用于不同的实例
我们首先从type
脚本开始。
type 脚本
请注意,注意这里的名字只是一个幸运的意外,它与你心爱的编程语言无关.
如果你考虑一下,CKB(或大多数基于 UTXO 的区块链)上的交易只会将一组 Cell(或 UTXO )转换为另一组 Cell。有趣的是,这里的实际转换过程。这就是我们开始设计CKB验证模型的地方:我们如何构建模型以更好地验证 Cell 转换?
这就是 type
脚本的用武之地:type
脚本用于验证 Cell 转换阶段的某些规则。这里的一些例子包括:
验证 UDT(用户定义的Token)余额以确保不会无效地发出新 Token。
确保每一个可能发生变化的 Cell 都拥有一个独一无二的名字,注意一下,这是非常有趣的,未来的文章很多都将和这一点息息相关,敬请期待。
实现经济结构。事实上,Nervos DAO 完全是作为一个
type
脚本实现的,而不需要共识层的支持。比特币的虚拟机可以编译成基于 RISC-V 二进制文件,这意味可以将 CKB 转换成另一种实现形式的比特币。
请记住,除了数据之外,Cell 还可以用来存储代码,因此
type
脚本也可以用来对 Cell 中的代码进行测试,确保代码正确。
简而言之,type
脚本可以用来存储 Cell 转换中所需要的任何验证逻辑,结合 CKB 虚拟机的灵活性,我相信它将提供无限的开发潜能。
lock 脚本
type
脚本用来存储 Cell 的逻辑转换,但是还缺少一件事情:如何保护自己的 Cell 不受其他人的攻击呢?换句话说,在这个瞬息万变的世界里,我如何才能确保我的 token 永远属于我呢?
这就是为什么我们需要设计 lock
脚本。只有当 lock
脚本能够成功执行时,才可以使用该 Cell。这与 type
脚本不同,type
脚本可能完全是可选的。而 lock
脚本总是需要用来保护 Cell 的安全性的。
通常,你会期望一个 lock
脚本包含一个签名验证,就像所有其他区块链所做的那样,当然 CKB 还将提供一些全新的解锁用例:
实际的签名算法完全由
lock
脚本来决定,而您可以自由使用任何lock
脚本。这意味着您可以自由地选择任何您需要的适合的签名算法。在官方发行的 CKB 版本中,我们将 secp256k1 作为默认的lock
脚本。如果您想使用这个,并且有人用 schnorr 签名实现了一个lock
脚本,那么我们非常欢迎您使用这个脚本。除了签名验证之外,
lock
脚本还可以包含其他用于解锁 Cell 的规则。比如,如果一笔交易包含了一个使用了我的lock
脚本的 output cell,但是它的容量大于我可以使用的 Cell,那么我可以通过配置我的lock
脚本来进行容量传递。这样的话,当有人向我发送容量时,他们可以使用我现有的 Cell 为我创建一个新的 Cell。他们不需要像比特币那样为我再重新创建一个新的 Cell。
在我看来,CKB 最好的部分就是,社区创建的 lock
脚本与官方默认脚本的处理方式完全相同。官方脚本没有任何特权。与其他一些区块链项目不同,CKB 为整个社区提供了开发 CKB 脚本的完全自由。
运行模型
现在让我们看看是什么时候执行 lock 和 type 脚本的。
回到例子
这是我们之前看到的交易:
在图中,执行流程如下:
Lock Script 1
执行一次。Lock Script 2
执行一次。Type Script 1
执行一次。Type Script 2
执行一次。
在后面的文章中,我们可以看到 lock 和 type 脚本都在相同的环境中执行,并且都可以访问整个交易。如果任何一个脚本失败,整个交易就会失败。只有当所有脚本都成功时,交易才被认为是有效的。
有几点值得一提:
尽管有 2 个带有
Lock Script 1
的 input cell,但它只执行一次,由实际的lock
脚本来定位具有相同lock
脚本的所有 input cell,并验证两个签名。在这个交易中只执行 input cell 中的
lock
脚本,例如:这里不执行Lock Script 3
。即使 input cell 和 output cell 都包含
Type Script 1
,也只执行一次。在 input 和 output cell 中都会执行
type
脚本,其中包括Type Script 1
和Type Script 2
。有些 cell 没有
type
脚本,在本例中我们只是省略了执行。
规则
现在我们总结一下规则:
在 input cell 中的
lock
脚本会被收集和解压,每个单独的lock
脚本会被执行一次,并且只执行一次。input 和 output cell 中的
type
脚本(如果存在的话)会被收集在一起并解码,每个单独的 type 脚本都会被执行一次,并且只执行一次。任何脚本失败,则整个交易验证失败。
下期预告
现在已经介绍了 cell 模型,我们将在下一篇文章中研究如何实际编写 CKB VM 脚本。将验证默认的 secp256k1 lock
脚本,来演示 CKB VM 脚本的使用周期。