CKB 上 type script 的定位


#1

阅读 CKB 源代码的过程中,一个疑惑是:校验交易时,为什么要校验 output.type
在两次 CKB 分享会上,这个问题都被不同的同学抛出来,然后也都引起了热烈的讨论,讨论期间大家也提出了对该字段的不同的认知。之所以对 type script 有各种不同的认知,可能的几点原因:

  • CKB 的设计先进
  • CKB 文档未给出官方定义
  • lock script 和 type script 的对数据的获取权限相同,二者界限模糊
  • “type” 这个命名较难理解

CKB 上 type script 的定位

Cell 有两个脚本字段,locktype,校验交易时会对这两个字段做校验:

  • lock 可以类别为比特币里的 P2SH。交易需提供 input cell 的解锁脚本 unlock script,用于解锁 input cell:
`return VM.exec(ctx, input_cell.lock + transaction.unlock) == 0`
  • type 比较难理解。相关验证:
`return VM.exec(ctx, output.type) == 0`

大家的普遍疑惑是,后面这个校验 output.type 的意义是什么?output 是我交易发起人构造的,难道我还会构造出一个不满足校验的 type 不成? 所以就牵涉出 type 到底是啥?

type script 的定位

type 就是 type script,对于 type script 的多种解读:

  1. 如钱林峰:“type 是对 cell data 的约束”
  2. 如“lock 表资产所有权,type 表资产使用权”
  3. 如“type 是对 cell data 的描述方式,类似于关系型数据库中的 schema”

我比较倾向于第 1 种解读,type 是对 cell data 的约束。对于第 3 种解读,我认为这只是 lock/type 的一种使用方式,并不是其本质定位;对于第 3 种解读,我认为 CKB 作为 verifier 角色,仅对链上交易做校验,并不对数据做操作,也不做“描述(表达)”。

对 “type” 命名的疑问

CKB 设计 type 字段,是借用了 type system 的 type 概念。
参考 Data type - Wikipedia,我对 data type 的理解是:data type 定义了一类 data 的三个元素:

  • operations:该类型的 data 的相关操作,如加减、拼接、存储
  • representation:该类型的 data 的表达意义
  • constraits:该类型的 data 满足的约束,如 8bit 整型数据不能超过 8 比特位

而作为 verifier 角色的 CKB,实际上链上只能定义 constraits of cell data,而其它两个元素 operations 和 representation 是在链下完成的。从这个角度想,我认为 “constrait script” 比 “type script” 更贴切,求指正。

校验** output.type **的意义

解释了 type 的定义,接下来回到最初的问题,交易过程中,校验 output.type 的意义是什么?简单举两个例子说明。

  • 对于 SoV cells,或者说其 cell data 没有意义的 cell,并不需要用到 type script,置空即可
  • 对于 utility cells,其 cell data 需要满足一定约束条件。比如我们想定义一种 ERC20 资产,就可以将 ERC20 标准约束写到 contract-cell 里,而表示 ERC20-cell (表示 ERC20 资产的 cell)的 type script 字段指向 contract-cell,也就是让 contract-cell 来约束 ERC20-cell 中的数据是否合法:
`return cell.type == contract-cell.id && 
       VM.exec(contract-cell.data, cell) == 0`

会发现,对于第二种场景,contract-cell.id 就像是一种数据类型的标识 identifier of data type,contract-cell.data 是该数据类型的约束,cell type 指向 contract-cell 即表示该 cell 满足该数据类型的约束。

更具体的解释,可能还需要 CKB 的同学梳理一下


#2

我是学姐的秘书,以下回答来自学姐,我想混个回复

我大概知道这个问题的答案(因为 type script 就是我反复争取要加上去的)

简单的说,其实没有 type script 大部分功能(注意只是大部分,我们讨论中是的确找到了某些 case 光用 unlock script 是会有安全问题的)也能工作。我觉得 type script 的主要功能是给人提供一个 trust,比如我创建了一个 ERC20 的 cell,通过 type script,你不需要相信我,只需要审查 type script 之后,就知道这个 cell 能怎么演化,确保我不会做恶,就会放心来买我的币。

在 ETH 模型中,因为 generator 过程发生在链上,所以不会有这个问题,但是我们 generator 是在外面,没有 type script 的话,假设你来买我的币,我自己发 generator 随便改吞掉你的币就好了


我也是 Ian 的秘书,以下回答来自 Ian

Lock 管死,type 管生。Lock 负责 tx 中 input cells 的验证,Type 负责 output cells 的验证。Type 负责的是不能随意创建有某个 Type 的 cell 出来,反过来的话,如果 cell 的 type 是 X,那 cell 一定通过了 X 的验证。


#3

我个人觉得,的确有个 type 描述状态更方便
一看就知道这个 cell 是哪个 type 的
所以就叫了 type
这名字我觉得尚可


#4

怎么像 PGP 的逻辑


#5

“type 是对 cell data 内容的约束”。这句话应该这么理解:

假设一个 cell 内的 data 就只有 u256 一个数据,代表某个 UDT 的余额。在没有任何约束的情况下,任何人都可以构造一个 data 内容等于 MAX_INT 的 cell,来冒充这种 UDT。

因此 CKB 的小伙伴发明了 type 字段对其进行约束:所有 type 字段相等(=某个合约的hash值)的 cell 中的data 的含义使用同一个合约进行解析,并且只有这种 cell 能够用这个合约进行解析。所以你可以伪造一个 data 内容任意的 cell,但只要你的 type 字段内容不是特定 UDT 的 type,它就不是这个 UDT 的余额。

那么还剩一个问题,type 字段的内容如何管理——总不能谁都可以把自己的 cell 设置为任意的 type 吧。CKB 接着要求每个 cell 在生成的时候必须通过 type script 的校验。也就是说,generator 可以指定生成的 cell 的 type 为任意值,只要这个 TX 能够通过对应的 type script 的校验。那么显然,类似 UDT 的数额平衡会出现在对应的 type script 中,防止凭空印钱以及凭空烧币。其他的合约也会在这里对 cell data 的内容进行约束。

所以,type 就是对 cell data 内容的约束,这个约束发生在 TX / output cell 的创建时。如果一个 TX 包含多个不同 type 的 output cell 怎么办?挨个验算。:grinning:


#6

这个秘书真好吃


#7

对于 type 这么常见的词没必要太纠结于定义吧,很多编程语言里的 type 含义都有偏差也不是和 wiki 上说的一致。

按照我的经验,实际使用中比较复杂的合约可以在 type script 定里义一组状态约束和状态转换的约束。

比如: UDT 抵押 -> DAI + locked UDT。其中的输入、输出都可以由 type 约束(所以 type 并不是仅能约束 cell 的 data 字段),这个例子中我来实现的话会用 DAI type 验证输入和输出的 UDT 的 type(UDT 本身的合法性和格式已经由 UDT 的 type 保证),并在 DAI type 中验证输出的 UDT 被 lock。

这样看来比较本质的描述是:type 约束 cells 的状态和状态转换

其实也和学姐和 ian 说的差不多了,每人的理解方式不同


#8

(BTW,其实我一直感觉叫做 DNA 会更贴切些


#9

嗯,其实理解了之后,看哪种解读觉得都可以。
只是对于我们新人来说,“很多种定义,很多种玩法” 意味着 “越看越搞不懂这是什么东西,应该以什么使用姿势来用它”。跟学一门新的编程语言是一个道理。


#10

举个例子,一开始我理解为 “lock 表所有权,type 表使用权” (忘了从哪儿听来的了)的时候,就很奇怪,为什么我还要给我自己的 cell 定义个使用权?后来才明白,原来这里说的“使用权”,不是指 “cell 的使用权”,而是指“该 cell 作为一个 UDT 来使用的需要满足的条件”。


#11

“type表使用权”这个说法我也很难理解,所以我倾向于认为是以讹传讹… 一开始按照ian的回答去理解可能是最容易的。


#12

表示赞同,更喜欢DNA这个称呼方式,很贴切


#13

unlock lock script(owner script) to transfer cells,
unlock type script to modify data in cells.


#14

很有意思的话题!

我感觉用现实的物品做类比,就像:

  • lock scrip是保险箱的密码,而
  • type scrip是里面物品的防伪认证。

比如在保险箱里放的是“美金”,不是所有纸张都叫“美金”,它是具有一定特征的,这个type scrip实际上认证了这个保险箱里放的确实是“美金”,而不是“人民币”。

按理来说,把价值存储在一个地方(SoV)是要付“保管费”的,以使得管理者能有资金和动力去加强安全网络,以保证你的资产安全;在区块链网络中其实就是矿工,由矿工来保证网络的安全。

在以太坊的网络里,这个“保险箱”是所有用户共有的(所有用户的资产都放在一个合约里),所以所难去收“保管费”。
CKB的高明之处在于,把这个“保险箱”私有化,就可以收取一定的“保管费”来建立整个网络的安全。


#15

jjy提到了这样一个案例,所以我觉得type script的功能可能会比防伪认证有更大的想象空间。

用你的例子来说,通过type script我可能不单单可以证明保险柜中存放的是“美金”,而不是“人民币”;还可以通过type script验证这个“美金”是所在这个特定的保险柜里面的,而不是放在外面或者锁在别的保险柜里面。@jjy 不知道这样的描述对不对?


#16

对,可以通过 type 来验证/控制 lock hash


#17

抛开含义不说(需要一个官方的权威的解释了),不纠结是不可能的。原因如下:

  • type 本身太 generic。
  • 开发者和非开发者,可能对这个词会有非常不同的直觉性理解。
  • 我们需要向大量的开发者和非开发者解释这个词。