# Fiber + UDT + Thoughts
## Metadata
**Status**:: #x
**Zettel**:: #zettel/fleeting
**Created**:: [[2024-04-16]]
## 现有方案概述
[Commitment Tx New Design (notion.so)](https://www.notion.so/cryptape/Commitment-Tx-New-Design-d1b756e79bf548ed85a867cef2fe5d36?pvs=4)
Open Channel 创建对应的 UTXO 并上链,以下称该 UTXO 为 Funding Cell。
状态通过一对 Commitment Tx 来体现。每有一个新的状态就新生成一对 Commit Tx 同时交换 Revocation Keys 来回收之前状态中的 Commitment Tx。如果有一方提交了旧状态的 Commitment Tx 上链,另一方可以通过 Revocation Key 拿走 Channel 中的全部资产。
![[Fiber + UDT + Thoughts - Drawing States.excalidraw.svg]]
%%[[Fiber + UDT + Thoughts - Drawing States.excalidraw|🖋 Edit in Excalidraw]]%%
在每个状态中,双方各持有一个 Commitment Tx。 Commitment Tx 包含两个 Outputs
- Local Out: 包含自己的余额和所有的还未清算成功的支付。
- Remote Out: 包含对方的余额。
另外目前为了简化设计,Channel 中的任何一个状态,都必须保证双方的余额能分别满足两个 Commitment Tx 中的 4 个 Outputs 的最小 Capacity 的要求。这个可以通过 lock script, type script 和约定的同时有效的最大 HTLC 数量计算得到。
Remote Out 比较简单,对方使用 Key 签名即可解锁。
Local Out 还包含未清算的支付,在 V0 中就是 HTLC。没有为 HTLC 单独创建 UTXO 是因为 CKB Capacity 最小值的限制,在小额支付场景中,大多数的支付金额不足以创建出一个 CKB Cell。
可以把 Local Out 理解为一个包含多个 Virtual UTXO 的 Cell。 Virtual UTXO 的 Cell Capacity 不足以覆盖其 Occupied Capacity,需要接收方补足 CKB Capacity 并从 Local Out 中分离出去。
可以把 Local Out 的 Virtual UTXO Lock 记为
$
\{M, L, M_1, L_1, \ldots, M_n, L_n\}
$
其中
- $M$ 即 Cell 全部的资产金额
- $L$ 可以用来解锁整个 Cell
- $M_i$ 表示第 $i$ 个 Virtual UTXO 的 CKB Capacity
- $L_i$ 用来解锁第 $i$ 个 Virtual UTXO
使用 $L$ 可以获得当前 Cell 的所有余额 $M$。
使用 $L_i$ 解锁可以处置 $M_i$ 数量的资产,但是要保证 Outputs 中必须存在一个余额为 $M-L_i$ 的资产并且使用如下 Virtual UTXO Lock
$
\{M-L_i, L, M_1, L_1, \ldots, M_{i-1}, L_{i-1}, M_{i+1}, L_{i+1}, \ldots, M_n, L_n\}
$
多个 $L_i$ 的解锁可以合并到一个交易中以提高效率。
![[Fiber + UDT + Thoughts - Drawing Local Out.excalidraw.svg]]
%%[[Fiber + UDT + Thoughts - Drawing Local Out.excalidraw|🖋 Edit in Excalidraw]]%%
对于一笔 Local Out:
- $M$ = Local Balance + 所有 HTLC 的金额之和
- $L$ = 二选一解锁
- 使用 Revocation Key
- 时间 T 之后使用 Commitment Tx 所有者的签名
为每一笔未清算成功的 HTLC 创建一个 Virtual UTXO
- $M_i$ = HTLC 金额
- $L_i$ = 二选一解锁
- HTLC 接收方使用签名和 preimage
- HTLC 发送方在时间 $T_i$ 之后使用签名
$T$ 必须不小于所有的 $T_i$ 并不小于双方创建通道时约定的一个值。
## UDT PoC
支持 UDT 需要以下修改:
1. 创建 Channel 时约定使用的 UDT Type Script。
2. 约定 Commit Tx 中 UTXO Occupied Capacity 的提供方式,可以由 Channel 发起方以赠送的方式代为提供、或者在 Dual Funding 中由双方各自提供。这个可以和 CKB 通道的逻辑进行统一,对于 CKB 通道,双方的 Local Balance 的最小值其实就是这里的 UTXOs 基础的存储需求。这个最小值要能满足能装下所有的 Active HTLC (会占用 Lock Script),并能满足 xUDT 扩展的存储需求。
3. 资产数量的单位使用对应的 UDT 的数额。比如 Remote Out 中的金额和 Local Out 中的 $M$ 和 $M_i$。
4. UDT 通道中,Commitment Tx Outs 的 CKB Capacity 始终等于创建通道时各自提供的 CKB 数量。
5. UDT 通道中,Local Out 的 Virtual UTXO Lock 在提取 Virtual UTXO 时,不能提走 CKB,也就是 Cell 的 CKB Capacity 只能通过 $L$ 进行解锁。
## Thoughts
这些都可以通过扩展的方式,由双方约定启用。对于 PoC 来说都不是必须,这里记录下来方便后续讨论。
#### 允许 CKB 租赁
允许由一方代为提供 CKB,在退出通道时,没有提供 CKB 的一方不能直接得到资产,还是被锁定到一个 1/2 Lock 当中,两个解锁条件分别为:
- 资产所有者提供签名,同时要保证 CKB Capacity 出租的提供者在本次交易中 CKB Capacity 不会减少。
- CKB Capacity 出租的提供者在时间 N 之后可以取走资产和 CKB Capacity
该方案也可以允许 CKB 通道中,有一方的余额不足以创建出 Cell。
#### Commitment Tx Pair 合并成一个 Tx
好处是减少一个交易,坏处是 Lock 逻辑复杂。
#### 允许只保存最新的状态
好处是减少存储开销,坏处主要是复杂性和对 BOLT 的兼容性。
比如像 eltoo 那样,如果旧状态被提交了,可以把最新的状态基于旧状态的 Output 进行提交。在 CKB 中已经可以支持,签名不去包含具体的 Input Out Point 即可。
类似 eltoo 但是对提供旧状态进行惩罚的方案应该也是可以设计出来的。
#### Active HTLC 存放的位置
目前方案比较合理。其它备选方案:
1. 单独一个 Cell 存放 Active HTLC
2. Local Out 和 Remote Out 都只存放自己的 Outgoing HTLC
3. 再加两个 Cell 分别存放各自的 Outgoing HTLC