# 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 |