CKB 脚本编程简介[1]: 验证模型
本文作者:Xuejie
原文链接:Introduction to CKB Script Programming 1: Validation Model
本文译者:Jason,Orange (排名不分先后)
截至目前,CKB 中的 Cell 验证模型或多或少已经趋于稳定,因此我将在这里开始写一系列文章来介绍 CKB 脚本编程。我的目标是补充在阅读白皮书后编写 CKB 脚本所需的所有缺失的细节实现,这样您就可以开始探索 CKB 呈现的这个美丽的仙境。
您可能会注意到我将在CKB上运行的代码称为脚本,而不是智能合约。这是因为智能合约对我来说是一个令人困惑的术语,我在这里想用另一个词来表示 CKB 独特的可编程性。CKB 中的脚本不一定只是我们在脚本语言中看到的脚本,例如 Ruby,JS,它实际上是指在 CKB VM 上运行的 RISC-V 格式二进制文件。
这第一篇文章将专门介绍 CKB v0.14.0 中引入的全新验证模型。这可能听起来很无聊,但我保证这是最后一篇没有实际例子的帖子
请注意,尽管我认为 CKB 的编程模型现在非常稳定,但目前仍然在进行开发,因此可能会有变化。我会尽力确保这篇文章更新,但如果有什么让你感到困惑的话,这篇文章现在正在描述 CKB 的这次提交。
概述
下面一张图片说明了 CKB 的真实交易过程:
这张图中有很多内容,我们将在稍后的文章中再次回到此图。今天,我们将只关注 Cell 数据结构中的 2 个实体:lock
和 type
。
pub struct CellOutput {
pub capacity: Capacity,
pub data: Bytes,
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 都拥有一个独一无二的名字,注意一下,这是非常有趣的,未来的文章很多都将和这一点息息相关,敬请期待。
-
实现经济结构。事实上,NervosDAO 完全是作为一个
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 脚本的使用周期。