这篇工程笔记整理自 TokenRail 的本地合约设计与原子性实验。案例使用模拟存款和合成债券,只讨论单条 EVM 链上的程序行为。
确认条款与授权额度
实验中,买方用 1,000,000 元模拟存款代币购买卖方的 1,000 单位债券。卖方先创建不可修改的指令,买方确认条款后进入 READY。
双方还要分别 approve DvP 合约。ERC-20 allowance 表达支出额度,不包含具体对手方、价格和期限,因此授权不能代替确认。READY 也没有锁定余额;真正执行前,需要重新检查资产、授权、身份与到期时间。
第二条转移失败时
DvP 的 execute 在一笔 EVM 交易内先转债券,再转现金。若现金腿(即资金转移环节)执行失败,且错误向上传播并触发 revert,本次交易中已发生的债券转移、allowance 消耗和指令状态变化都会回滚,失败路径上的事件也不会留下。
检查 READY 与执行条件
↓
暂置 SETTLED → 转移债券 → 转移现金
↓
全部成功:提交状态与事件
任一失败:回滚本次交易内的业务变更
失败交易仍会产生 receipt、消耗 gas 并推进发送者 nonce。所谓“余额不变”,指的是两种业务代币;不能据此说交易没有发生。
如何验证回滚
只把买方余额设成不足,可能在预检查时就被拒绝,无法证明第一条转移完成后仍能回滚。TokenRail 的测试专门让第二腿(本例中的资金转移)主动失败,并在真实 Anvil 交易后检查失败 receipt、余额、授权额度和 READY 状态。测试替身仅用于验证,不进入实际部署。
链下还有另一条流程
Java 服务随后消费 Transfer 事件并更新持仓投影。这里涉及数据库和链,无法通过一个数据库事务获得同样的原子性:链上已经确认的转移不会因数据库失败自动撤销。
因此提交尝试、链上交割和投影同步分别记录。RPC 超时进入待确认状态,投影按区块重扫并去重;对账固定同一区块水位。这些流程处理恢复与一致性,适用范围与合约内的原子交换不同。