我失败了。
从现在看,说不定我真的会像半年前担心的那样,等到明年才发布 CCC 2.0.0 版本。
「阅读 CCC 里 UDT 相关的工具。请帮我制定一份重写相关逻辑的方案。」

Coin
硬币的概念已经存在了上千年,在人类社会中承担着价值流通的职责。在 CKB 上,我们也有数字版本的硬币,即后来被称为 UDT 的寻常代币。每一枚硬币都由 CKB 上的一个 Cell 承载,由类型脚本约束着代表硬币面额的数据。一枚硬币可以拆分成多枚,多枚也可以组合回一枚,而每一枚又都可以在不同的地址中流通。
CKB 有两种货币资产,分别是原生代币和硬币。原生代币几乎是必须支持的类别,但处理原生代币相关的问题,例如最小占用费,却需要消耗开发者大量的心力。而当开发者终于准备支持硬币时,周边基础设施的缺失又让能完整支持硬币的生态应用少之又少,光是在链下实现简单的收付款就是一种挑战,更别说复杂的链上逻辑。
因此,在这次以硬币为主题的预发布里,我决定重写旧的 UDT 包,抛弃很多原来没设计好的部分。同时,我也决定用 Coin(硬币)这个旧名字代替不够直观的 UDT,因为它在社会中有着更广泛的共识,也更能直观体现 CKB 上寻常代币有着独立面额的特点。
CKBC(oin)
新的 Coin 包试图为应用简化硬币操作,而 CKBC(oin) 则试图将硬币的概念也拓展到原生代币上。对于只关心货币资产价值的应用,CKBC 的存在能让它们不再需要分别处理原生代币和硬币,从而降低应用的开发门槛。
在 CKBC(oin) 的设计中,用户必须通过锁定 CKB 才能铸造 CKBC,因此每一枚 CKBC 背后都对应着和面额相同数量的 CKB。锁定的 CKB 在链上以公共金库的形式存在,只有烧毁 CKBC 时才能解锁金库。
这种锁定并铸造的方案和 iCKB 很像。在两种设计中,用户都可以持有锁定了 CKB 价值的硬币。但在 iCKB 的设计中,CKB 被锁定在 Nervos DAO 中,以牺牲部分和 CKB 间的流动性为代价,为持有 iCKB 的用户提供了稳定的收益。
虽然 CKBC 和 iCKB 听起来会互相抢夺用户愿意锁定的 CKB,但它们绝非竞争关系。得益于 CKBC 和 CKB 间优良的流动性,用户随时可以解锁 CKBC 并重新锁定为 iCKB。CKBC 简单的设计帮开发者迈出了兼容硬币的第一步,而在这之后,他们只需要沿着同样的路径,就可以为已经支持了硬币标准的应用加入更多的硬币,包括 iCKB。
在 CKBC 的设计和工具包之后,我还完成了配套的网页工具。用户可以在网页上连接自己的钱包,完成 CKBC 的铸造、解锁和转账等操作。在实现这个工具的过程中,我也注意到了 CKBC 包里需要重新打磨的逻辑。
例如在设计中,CKBC 金库和 CKBC 代币其实是两种可以互相转换的硬币。比起要求开发者单独操作这两种硬币,最终实现利用了它们之间的强联系,让代币的铸造总随着 CKB 被锁定到金库中,而代币的烧毁也总随着金库被解锁。
再比如,CKBC 是去中心化的协议,所有人都共享同一套 CKBC 金库。如果只是简单按时间选择,那在多个用户同时操作时,多笔包含同一个金库的交易必然互相冲突。为了降低冲突发生的可能性,最终实现选用了基于概率选择金库的方式。

「这份设计中有几个明显的问题,请帮我评估可能的修复方案。」
命令行重新开始滚动,AI 继续搜索相关的资料。我有多长时间没好好写代码了呢?
对于觉得自己动手比给 AI 下指令更快的情况,我偶尔还会按自己的想法修改代码;难以用自然语言描述的构思,简短的伪代码也是不错的沟通方式;审阅 AI 生成的代码更是家常便饭,直到现在我也相信人类审核的必要性。
但我想说的不是这些。我已经记不得上一次认真思考解决问题的代码方案是什么时候了。我也忘了进入心流状态,几个小时盯着同一份代码是什么感觉。
把看到的问题粗暴地塞到对话框里,然后指派一个看着顺眼的方案;冲一杯咖啡,泡一杯茶,看会视频,刷会社交媒体,总之任何能打发 AI 思考时这段无聊时间的事情;别忘了时不时注意 AI 的进展,等着看它噼里啪啦地把结果吐出来。重复这个过程。
一阵烦躁。与其说我在意每个屏幕上各自切换着的内容,它们更像是思绪里的填充物,让我无暇在意自己在做的事情有多无聊。「迟早要被取代的家伙还在苟延残喘什么。」是啊,我在做什么?「也许我不该继续写代码。」也许我错得太久了。「再努力的人也只能沦为 AI 的训练数据。」人们怎么能这么心安理得?
我不愿让这些混乱的念头占领全部的空白。
「忘了之前对话的内容吧。有趣的想法:我想把 CKB 本身包装成代币,并从这个具体案例出发,重新思考我们需要怎样的工具。把提炼出来的概念叫做硬币 Coin,这样包装代币就可以叫 CKBCoin,你觉得怎么样?」
CoBuild
我签名释放了硬币,等量的硬币进入你的地址,这是一次最简单的硬币转账操作。但是,这个过程也可以理解成我烧毁了硬币,而你刚好铸造了等量的硬币,只看最终状态难以区分。
CKB 这种链上只关心最终状态转移的设计,的确减少了不必要的信息暴露,对隐私而言是件好事,但过程中的意图信息缺失也为开发者带来了额外的挑战。在交易组装、验证行为和数据统计等场景中,开发者们要不就得像个侦探一样,从最终结果反推出发生了什么事情;要不就提前做好小抄,额外记下交易的意图供后面参考。
为了存放意图数据,CoBuild 协议规定了一套统一的信息解析方式,从而在交易中开辟了额外的空间。除此之外,原始的 CoBuild 设计还包括了链上验证逻辑、应用间数据交换格式和可组合交易片段等规范。
不过,这次我在 CCC 中重新引入 CoBuild 协议,只是为了简化 Coin 包的操作。Spore 协议的教训,因过早在链上强制要求 CoBuild 信息而导致的开发体验灾难,至今难忘,我并不希望因为急于实现完整的 CoBuild 而重蹈覆辙。
在 CoBuild 包的帮助下,新的 Coin 包也保持了 CCC 一贯以来「交易流水线」的设计。在往交易里添加操作的过程中,工具可以通过 CoBuild 直接了解交易里已有的意图,避免潜在的冲突。因此,在同一笔交易中,开发者可以自由组合硬币的多种操作。

专业的用词、完整的解析、详细的描述……思想空洞,充满错误。
「请你对发布的内容负起责任,检查 AI 生成的内容。」
刚刚想要认真阅读的欣喜已经消失,心情从无奈变成了愤怒,又再次变回无奈。以为自己终于找回了故友赠予的礼物,却发现只是被随手丢弃的废物,被 AI 的长篇大论欺骗的我心里大概就是这样的感觉吧。
离新年还有四个月。
待办事项随着鼠标滚动,内容流出视野。我打从心底里知道,我该处理那些事情,给出没人会挑剔的正确答案,写下不批判任何人的文字,成为一个更聪明的 AI。
手指却在眼睛勇于看清最后一条内容前关闭了页面,但还是没能阻止堆积物透过鼻子攥住大脑。为什么我没在写代码?我该写代码了。我需要写代码了。我必须写代码了。
我想写代码了。
「回到之前的问题。调研 CoBuild 协议的设计,我想用它来记录交易构建过程中的意图。」
- CCC GitHub: https://github.com/ckb-devrel/ccc
- CKBC(oin) GitHub: https://github.com/ckb-devrel/ckbc
- CKBC(oin) 网页应用: https://test.ckbc.ckbccc.com
- iCKB GitHub: https://github.com/ickb
- CoBuild Protocol: https://talk.nervos.org/t/ckb-transaction-cobuild-protocol-overview/7702
- 本文同时发表在 Nervos Talk 上: https://talk.nervos.org/t/ccc-2-0-0-prerelease-cobuild-coin-ckbc-oin/10597