# CKB ACL Brainstorming
## Metadata
**Status**:: #x
**Zettel**:: #zettel/literature
**Created**:: [[2023-10-12]]
## Synopsis
权限代理是比较常见的 scripts composition。主要思路就是对逻辑进行模块化,然后通过 运行时 ACL 配置对模块进行组合。
我们也经常能看到 ACL 的实际应用。
1. Anyone Can Pay: 可以看做是 secp256k1 lock script 将部分的操作权限授予了任意 script。
2. .bit 中的 wrapper lock 也可以看做是 user lock script 将部分操作权限代理授予了 .bit type script。
3. Taproot MAST 也可以看做是权限的代理,一个 UTXO 可以有不同的解锁途径。
## Lock Scripts Authorizing Type Scripts
按照约定 Lock Script 不会去验证 cell data,所以它主要就是整个 cell 的所有权,主要是其 CKB capacity 的所有权。
Lock ACL 表示在不需要对应的 Signature 的情况下对 cell 进行操作:
- 更新 cell data
- 修改 type script
- 减少 ckb capacity
使用场景
- 游戏的高频操作,可以将 cell data 更新的权限授予游戏的 type script
### 场景
- 代付 CKB
- 用于存储或者 tx fee
- Offline Payment
- User operations auto approvals (session key)
- ESC 中 Component 授权 System
### 操作判断
#### 识别 inputs/outputs 的关联
Cell 的一次性的,在 tx 中总是销毁一批然后新创建一批。所以 Update 这种操作其实从 CKB 底层中是不存在的,但是在应用层来说这种需求又是非常常用的。
目前常用的识别的模式有:
- 通过 lock script。这种关联是多对多的,Inputs / Outputs 都是使用该 lock script 的 cells 的集合。这时候一些操作就不太好定义,要么是根据这种集合的情况重新定义可以执行的操作,要么是再进一步定义如果推导出一对一的关系。
- 通过 ID,比如 Type ID 本身。因为占用了 Type Script,如果 Cell 本身需要使用应用的 type script,应用的 type script 就必须支持某种 ID 机制。
### 代理方式
只要在 lock script 中加上分支即可
- 可以使用 private key signing 解锁,
- 或者同一个 tx 在存在对应的 type script,并且所执行的操作在授权范围之内
授权可以在以下地方存储
- lock script args 里直接指定。如果需要更新就必须修改所有使用该 lock 的 cell
- lock script args 里指定一个 cell,在 cell 里保存,这样更新会比较方便。因为需要更新,需要使用 type id (或者其它类似的方式)指定 cell。
授权可以直接保存,或者保存 Merkel Tree Root。
### 一种可行方案
- 使用 Combine Lock 为 Lock Script 增加分支
- Type Script 必须兼容 Cell ID
- 定义一个授权的格式,并支持使用 Merkle Tree 保存
- 将授权单独保存的一个 Cell 中
- 在 Combine Lock 的分支中加入授权的支持。
## Type Scripts Authorizing Type Scripts
Type Scripts 的授权和 Lock Scripts 是相似的,最在的挑战在于如何编码 Type Script 做了什么操作。
### 场景
- 模块化
- Type scripts composition
- ESC 中 System 授权 System
### 操作识别
第一种方法是通过 Type Script inputs/outputs 进行推导。对于复杂的应用需要一定的模式识别,比如:
- Inputs / Outputs 能方便的归纳出各自的 states 和 values,这样所有的操作都可以编码成:`{from_state, to_state, value_diff_range}`。
- 例子,inputs / outputs 中的第一个 cell 的前 N 了字节保存了 state 和 value
第二种方法是 Type Script 直接声明自己的操作,比如在 [Witness, OTX, Typed Message](https://www.notion.so/cryptape/Witness-OTX-Typed-Message-c6f11cb982474d77aac534b75314595a) 中,可以把操作写到 `TypedMessage` 里。
第三种方法,把操作的判断代理给 script,只要 script 执行结果是成功就认为是对应的操作。这样只需要在授权对象里填上对应的 script。验证交易的时候需要执行对应的 script。不过这个对组装交易带来更多的挑战,至少需要知道怎么补上 cell deps。
## 授权时效性
### 次数
在指定授权 data cell 的同时指定一个计数器 cell 即可,也可以
计数会导致更新瓶颈,但是考虑到可以为不同的操作分配不同的次数器,单个操作可以对交易排序,避免并发使用计数器,对于大部分场景是没影响的。
### 时间
CKB 不支持 until,如果不使用 time oracle,需要使用两步 commit 的方式来判断是否授权已经过期。
别一种就是用户需要手动操作移除过期的授权。
退一步的话,如果不是要求交易发生时间在某个时间这前,而是可以接受当 input cell 在某个时间之前授权有效,那可以使用 input cell + dep header 实现。