想和大家分享一个我一直在做的项目,也坦诚地说说它现在处在什么阶段。
Cell 模型是我在区块链架构中见过的最优雅的设计之一。CKB 证明了 UTXO 风格的状态管理,配合通用虚拟机,能给你账户模型永远做不到的东西:显式的所有权、没有隐式突变、在交易级别真正的可组合性。
但手写 Cell 脚本有点难。你要手动解析 witness 字节,追踪索引,把状态编码进原始数组,用数字调用系统调用。它很强大,但它无法扩展到一个生态系统。
所以我做了 CellScript。
CellScript 是一个领域特定语言,把 .cell 源码编译成 RISC-V ELF 二进制文件——就是 ckb-vm 已经在运行的那种。它不引入新的虚拟机。不修改交易的容器/信封。它在现有的执行栈上,叠加了一个类型安全、线性强制执行(linearity-enforced)的编程模型。
它给你什么
类型化的资源 (Typed Resources)
resource: 线性的 Cell 支持资产,编译器跟踪它的生命周期。不能静默丢弃,不能意外复制shared: 共享状态 Cell,用于池、注册表、配置。读写对元数据和工具可见receipt: 一次性证明 Cell,用于存款、归属授权、投票、流动性头寸
显式的生命周期操作
consume: 消费一个 Cell,线性值不再可用create: 创建新的输出 Cell 和类型化的输出数据transfer: 转移资源所有权destroy: 销毁资源claim: 认领 receiptsettle: 结算状态
这些不是隐喻。它们 1:1 映射到 Cell 交易的形状。
编译器能力 gates
声明像 has store, transfer, destroy 这样让资产权限显式化,而不是隐藏在实现里。
生命周期状态机
#[lifecycle(...)] 让 Cell 支持的值描述状态机,比如 Granted -> Claimable -> FullyClaimed。
效果推断 (Effect Inference)
编译器知道你的代码是读取、写入、创建还是销毁。action 体被分类为 Pure、ReadOnly、Mutating、Creating 或 Destroying。
调度器元数据
对于 DAG 并行执行,编译器发出访问摘要和共享触达域,让区块构建者和执行管线能推理独立工作。
策略门控 (Policy Gates)
生产构建可以在部署前拒绝不完整或有风险的路径。checked-runtime、fail-closed、runtime-required——所有语义状态都是显式的。
类型化的 schema 元数据
Cell 数据布局、类型身份、输出字段溯源、源码哈希、运行时访问和验证者义务,都作为机器可读的元数据发出。
包管理
Cell.toml 清单,本地模块,配置的源码根目录,本地路径依赖。
它还不做什么
坦诚地说:
- 完整的 CKB 合约兼容性——v1 只支持受限的子集。CKB profile 是有意边界的
- 通用的 AMM/池语义——原语存在,但经济学还在完善
- 包注册表——目前只有本地路径依赖
- Wasm 后端——只有 RISC-V
launch作为一等公民——还在规划中- 用户定义的泛型——后续版本
这是一个早期测试版本。编译器能工作。类型检查器能捕获真正的错误。代码生成产生有效的 ELF。但有状态的协议语义还在成熟中,我在寻找愿意把它弄坏的人。
工具链
# 安装
cd cellscript
cargo install --path .
# 编译单个文件
cellc examples/token.cell
cellc examples/token.cell --target riscv64-elf
cellc examples/token.cell --target riscv64-elf --target-profile ckb
# 编译或检查包
cellc check --target-profile ckb
cellc check --target-profile portable-cell
# 发出元数据
cellc metadata examples/token.cell --target riscv64-elf --target-profile ckb
# 验证产物
cellc verify-artifact examples/token.elf --metadata examples/token.elf.meta.json
# 运行测试
cellc test
# 生成文档
cellc doc
# 格式化代码
cellc fmt
# 初始化新包
cellc init my_token
# REPL 交互式环境
cellc repl
目标配置 (Target Profiles)
| 配置 | 用途 | 产物形状 |
|---|---|---|
ckb |
CKB 产物(受限纯子集) | CKB 主网系统调用配置,CKB Molecule/BLAKE2b 约定,CKB 头 ABI |
示例
仓库包含完整的示例,展示语言如何映射到真实的 Cell 模式:
token.cell — 可替代代币
- 铸造授权 (MintAuthority)
- 限额检查
- 转账和销毁
- 能力 gates:
store, transfer, destroy
nft.cell — 不可替代代币
- 唯一标识符
- 所有权转移
- 不可复制语义
vesting.cell — 归属计划
- 生命周期状态机:
Granted -> Claimable -> FullyClaimed - 时间锁检查
- 部分认领支持
- Receipt 作为状态化证明
timelock.cell — 时间锁
- 基于 since 的解锁条件
- 紧急恢复路径
multisig.cell — 多重签名
- M-of-N 签名验证
- 提案和批准流程
amm_pool.cell — 自动做市商池
- 共享状态 Cell (
shared) - 流动性添加和移除
- 恒定乘积不变量
- 交换费用计算
- 流动性凭证 (receipt)
这些不是生产合约。它们是证明语言能映射到真实 Cell 模式的示例。
VS Code 扩展
仓库包含一个 VS Code 扩展 (editors/vscode-cellscript):
.cell语法高亮- 代码片段
- 格式化集成
- 诊断信息
- 悬停提示
- 跳转到定义
- 查找引用
- 面向元数据的代码操作
和其他语言的对比
| 维度 | CellScript | Solidity | Move | Sway |
|---|---|---|---|---|
| 执行目标 | ckb-vm 上的 RISC-V ELF 或汇编 | EVM 字节码 | Move 字节码 | FuelVM 字节码 |
| 状态模型 | 类型化 Cells,显式 inputs/deps/outputs | 账户存储槽 | 全局存储中的 resources | UTXO 加原生资产 |
| 资产模型 | 原生 resource、生命周期、receipt 和 shared Cell 模式 |
手写 token 合约 | 原生 resources | 原生资产,但 type-script 概念较少 |
| 线性所有权 | 对 Cell-backed 值做编译器强制 | 无 | 通过 abilities 支持 | 无通用用户定义线性 resource |
| 共享状态 | 显式 shared Cells |
隐式 contract storage | 部分 Move 链中的 shared objects | 无通用 shared Cell 对应物 |
| 重入形态 | 没有账户存储 callback 风格重入 | 常见风险面 | 设计上较低 | predicate 风险较低 |
| 调度 metadata | target 原生支持 | 无 | 非 GhostDAG 导向 | predicate 级独立性 |
| CKB 兼容性 | 对受支持 Cell 子集提供有边界的 ckb-vm artifact profile | 需要不同 VM | 需要不同 VM | 需要 FuelVM |
与手写 CKB 脚本相比,CellScript 保留同一个运行时底层,但用类型化 Cell 操作、线性检查、schema 元数据和可被策略验证的产物取代原始字节/系统调用编程。
快速开始
# 克隆仓库
git clone https://github.com/tsukifune-kosei/CellScript
cd CellScript
# 安装编译器
cargo install --path .
# 编译示例
cellc examples/token.cell --target riscv64-elf
# 检查包
cellc check --target-profile ckb
# 运行所有测试
cellc test
# 查看元数据
cellc metadata examples/token.cell --json
项目布局
cellscript/
├── src/ # 编译器、解析器、类型检查器、IR 降级、代码生成、CLI
├── examples/ # 示例合约和协议模式
├── tests/ # 编译器和 CLI 测试
└── editors/
└── vscode-cellscript/ # VS Code 扩展
如果你在用 CKB
CellScript 的 CKB profile 是 v1 中有边界的。它是为通过 CKB 可移植性门的源码准备的产物配置;它不承诺任意有状态的 CellScript 程序或任意手写的 CKB 合约能完全互换。
不支持的 CKB/运行时/有状态形状会被策略拒绝,或保留为 v1 后的工作。
状态
这不是生产就绪的语言。这是:
工作的编译器 (解析 → 类型检查 → IR 降级 → 代码生成)
类型安全的资源操作
线性强制执行
有效的 RISC-V ELF 输出
CKB profile (受限子集)
元数据策略门控
有状态协议语义还在成熟
AMM/池经济学未完全形式化
包注册表不存在
Wasm 后端
泛型
我在寻找愿意:
- 写合约,发现边界情况
- 报告编译器应该拒绝但接受的东西
- 报告抽象泄漏的地方
- 测试 CKB profile 的边界
- 贡献示例和文档
—
仓库: GitHub - CellScript
问题和建议: 直接开 issue