# CKB DAO Co-Build Compatibility
## Metadata
**Status**:: #x
**Zettel**:: #zettel/permanent
**Created**:: [[2023-12-15]]
**Notion**:: [Design the witness layout for a transaction with a Co-Build lock and the system DAO type script](https://www.notion.so/cryptape/Design-the-witness-layout-for-a-transaction-with-a-Co-Build-lock-and-the-system-DAO-type-script-dab41b1ee114431da540b1fcb6d1bef4)
## Synopsis
当进行 Withdraw Phase 2 的时候会碰到 Witness Layout 的冲突问题。
![[CKB DAO Co-Build Compatibility - Withdraw Phrase 2.excalidraw.svg]]
%%[[CKB DAO Co-Build Compatibility - Withdraw Phrase 2.excalidraw.md|🖋 Edit in Excalidraw]]%%
上图展示了一个 DAO Withdraw Pending Cell,也就作为 Withdraw Phase 1 的 output,等待 Withdraw Phase 2 进行结算作为 input 的 DAO cell。
在 Withdraw Phase 2 中,DAO 需要读取 Withdraw Pending Cell 的 Deposit Block 在 header deps 中的位置。这一信息必须放在 Input Cell 对应位置的 Witness 中。Witness 必须使用 WitnessArgs 格式,而 DAO 使用了其中的 `input_type` 字段。
由于 DAO 的这些限制,就必须在其 Lock Script Group 的范围内使用 WitnessArgs,和目前 Co-Build 的 Witness Layout 冲突。
## 方法提案
### A. Lock 兼容模式
让 Lock 支持兼容 WitnessArgs 的模式,在 Withdraw Phrase 2 交易中使用 WitnessArgs 布局排放 Witness。在 DAO 合约升级之前,只支持 Co-Build 的 Lock 就不能用于 Withdraw Pending Cell 了。
### B. 使用临时 Lock
这个和 A 的 Lock 兼容模式差别不大,就是在 Withdraw Phase 1 的给 Withdraw Pending Cell 使用一个 WitnessArgs 布局的 Lock,Withdraw Phrase 2 的时候再换回 Co-Build Lock。
对于 DAO 可以使用专门设计的 Lock,可以让任何人进行 Withdraw Phase 2 操作但是保证所有资产都转给了指定地址,即 DAO 版本的 Anyone Can Pay。
### C. 升级 DAO
升级 DAO 有两个方案。
第一个方案是让 DAO 不使用 Witness。比如 DAO 可以遍历 header deps 直到找到 block number 和 cell data 相匹配的 block header。考虑到 DAO Withdraw Phase 2 并不会有太多 header deps,并且可以通过 Molecule Lazy Read 优化,遍历的开销并不会太大。另外也可以直接在 Withdraw Phase 1 的时候把需要的信息如 DAO Field 直接放到 cell data 时,不过这个会要求更多的存储开销,从 8 个字节变成至少 32 个字节,而存储占用的 CKB 是不计算 DAO 补贴的。
第二个方案就是让 DAO 支持 Co-Build,从 TypedMessage 里读取 Deposit Block 的位置。
升级最大的障碍是必须硬分叉。
### D. 使用 Co-Build OTX 模式
OTX 中不是按照 Lock 的位置排放 ExtendedWitness,所以可以更灵活的和 WitnessArgs 组合。比如可以把 Withdraw Pending Cells 放在开始的位置,对应的 Witness 都用 WitnessArgs,下一个位置上开始放 OtxStart 和 Otx,并且 Otx 的范围从第个非 Withdraw Pending Cells 开始。这个方案的问题在于 Witness 的签名覆盖,不过对于 DAO 来说可有可无,改了 Deposit Header 位置信息只会让交易验证失败。
### E. 让 ExtendedWitness 位置更加灵活
如果 `ExtendedWitness::SighashWithAction` 不强制要求和 Lock Script Group 中第一个 input 的位置必须一致的活,就能更灵活的处理兼容性的问题。这个可以把位置让给 DAO,而把 Lock 的 ExtendedWitness 放到超出 input cells 数量的位置上。
这里会有签名覆盖的问题,目前 Co-Build Lock 的签名不会去包含 input cells 数量之内的 witness 中除 TypedMessage 之外的内容。对于 DAO,签名不覆盖也不会有问题,参考 D。
### F. 通过编排 cells 位置错开 ExtendedWitness 和 WitnessArgs
![[CKB DAO Co-Build Compatibility - Organize Cells in Withdraw Phrase 2.excalidraw.svg]]
%%[[CKB DAO Co-Build Compatibility - Organize Cells in Withdraw Phrase 2.excalidraw.md|🖋 Edit in Excalidraw]]%%
这是我能想到的最理想的布局了。这个布局存在两个问题:
1. 需要一个额外的 Cell 参与交易。会出现 ETH 中有 ERC20 Token 但是没有 Gas 进行转账的尴尬。
2. 按照目前 Co-Build 的设计,第二个 cell 也包含在 Lock Script Group 之内,是不应该放 Witness 的,而且该 Witness 也没有包含在签名覆盖范围之内。对于 DAO,签名不覆盖也不会有问题,参考 D。
### Overview
- Co-Build 签名: 签名使用 Co-Build 的 ExtendedWitness
- 不用改 Lock: 不需要 Co-Build Lock 有对应的逻辑支持,比如要兼容 Co-Build 和 WitnessArgs。
- 不用改 Co-Build: 不需要修改 Co-Build 协议。
- 签名能有效覆盖: 不会有 WitnessArgs 中 `input_type` 和 `output_type` 没有被签名覆盖的情况。
- 无额外开销: DAO 的交易没有额外的存储开销,不用额外的 Cells 参与交易。
- 无须硬分叉
| | Co-Build 签名 | 不用改 Lock | 不用改 Co-Build | 签名能有效覆盖 | 无额外开销 | 无须硬分叉 |
| --- | --- | --- | --- | --- | --- | --- |
| A | X | X | O | O | O | O |
| B | X | O | O | O | O | O |
| C | O | O | O | O | O | X |
| D | O | O | O | X | O | O |
| E | O | O | X | X | O | O |
| F | O | O | X | X | X | O |