Fuel 的 UTXO 智能合约是什么?状态声明前移怎么换来并行执行 图 1
Fuel 的 UTXO 智能合约是什么?状态声明前移怎么换来并行执行 · 图 1

“把 UTXO 拿回来写智能合约”听起来像复古,Fuel 走的正是这条路,并且做得比一般侧链激进:它的状态不是”账户—余额—合约存储”这张全局表,而是一堆可被交易显式声明消费的 UTXO。Fuel 规范仓库(fuel-specs)用一句话概括自己——一个可验证、可大规模并行执行的交易账本——而支撑这个定位的正是状态模型的这次换底。

交易必须先说出自己会碰什么

翻开规范的交易格式,输入类型分三种:Coin(一枚币)、Contract(一个合约)、Message(跨链消息);输出类型分五种:Coin、Contract、Change、Variable、ContractCreated。每笔交易要把用到的输入和期望的输出逐条列全。这带来一个本质差别:以太坊的交易执行到一半才”发现”自己要读写哪些存储槽,而 Fuel 的交易在签名那一刻就把接触的状态集合写死了。执行器因此可以在多核上放心并发——读写集互不相交的交易天然没有冲突,不需要推测执行再回滚。

币、谓词与消息

机制示意(图片由 Agnes 生成,非产品界面或链上数据图)

Coin 输入由交易哈希加输出索引定位(规范里叫 outpoint),附带金额、资产 ID、所有者和见证索引。值得细看的是 owner 字段:它可以是普通地址,也可以是一段谓词脚本的根哈希——规范规定当谓词长度大于零时,计算出的谓词根必须等于 owner,等于把”什么条件能花这笔钱”编进了输出本身。签名验证、时间锁、多签都能以谓词形式存在,而不是靠链上合约代理。Message 输入则专用于从以太坊等外部系统带进来的消息,其 ID 由发送方、接收方、nonce、金额与数据哈希而成。

合约在这里怎么存状态

合约作为 Contract 输入出现,对应输出要声明执行后的余额根与状态根。也就是说,合约的状态变更被摊平成”这笔交易结束后根是什么”的断言,和交易的合法性一起被验证。合约自身不维护”当前总余额”这种隐式记账——资产永远以币的形式存在,合约只是持有与转换它们的规则。这套设计让重入防护近乎免费:资产被消费而不是被就地改余额,但代价也直白——开发者要为币的碎片化管理找零(Change 输出)与选择逻辑负责。交易格式里还有一类专门的 Change 输出,用于把多花的币退回付款方,它和 Variable 输出的区别在于收款地址是否写死:前者的接收方在签名时锁定,后者允许执行过程决定去向,因此签名者要为后者预留更大的授权面。

与其他并行方案差在哪

同为并行执行,Solana 的 Sealevel 靠账户模型下的静态读写集声明,Move 系靠对象所有权,Fuel 则把声明下沉到 UTXO 粒度:消费即声明,天然没有共享热点键。好处是没有全局锁争议;短板是状态碎片化和表达复杂应用状态时需要更多输出条目,交易体积更大。它不是绝对领先的方案,只是把”冲突检测”这一步前移到了交易构造期。

场景与风险

适合高频小额支付、批量结算、谓词即账户这类对并行度敏感的应用;需要超大共享状态的通用金融乐高则要在碎片化开销上多做权衡。费用侧的一个特点是写入惩罚:fuel-core 仓库的费用文档说明,为补偿网络长期存储合约数据,向存储写新数据或部署新合约的指令要额外支付 gas(早期文档给过一个按目标存储增速反推的每字节 gas 参考价,并说明执行费与存储费分离是后续方向)。普通用户核验一笔 Fuel 交易的思路也简单:看输入列表是否覆盖了被花费资产、Change 输出是否找回给自己、谓词字段是否为空——这些都是区块浏览器上可直接核对的字段。机制以 fuel-specs 与 fuel-core 仓库当期文本为准,网络参数可能随升级变化。本文不构成投资建议,也不对项目性能作承诺。