代币不收币也能换着花?ERC-823 兑换标准的回调设计 图 1
代币不收币也能换着花?ERC-823 兑换标准的回调设计 · 图 1

代币不收币也能换着花?ERC-823 兑换标准的回调设计

手持 A 代币却想付 B 代币的账,常规做法是先去交易所换成 B 再支付。ERC-823 在 2018 年 1 月 6 日提出了另一种想象:让两个代币合约自己会“换装”,一笔调用里完成兑换和支付。按 ercs 仓库记录,这份标准状态为 Stagnant,从未广泛部署,但它的接口结构值得当作机制样本细读。

换掉而不是销毁

标准开篇批评了当时的代币转换器:转换器直接减少旧代币的总供应量,等于销毁。ERC-823 的方案是不销毁——你的 A 币换出去之后,被存进 B 币所在的那个合约里,标准称之为“目标合约”,兑换记录让所有人知道谁的币躺在谁家的账上。动机里还有一句直白的话:这会增加后者(目标合约代币)的市场价值。这种“旧币进仓、新币到账”的设想回避了定价问题,把兑换率完全交给一个中间服务合约去算。

代币不收币也能换着花?ERC-823 兑换标准的回调设计 图 2
代币不收币也能换着花?ERC-823 兑换标准的回调设计 · 图 2

交换方的三个函数

想在自家代币里支持兑换的合约要实现发送方接口。存储上有两张表:exchangedWith 记录目标合约地址与累计换出的数量,exchangedBy 记录谁发起了兑换及数量。方法上,exchangeToken(目标合约, 数量) 返回成功标志与到账数量,交给交换服务合约执行;exchangeAndSpend(目标合约, 数量, 收款人) 则把兑换和花掉一步做完;__exchangerCallback 是给服务合约回头扣减发起人余额用的回调,标准明确要求只有交换服务合约有权调用它。所有返回布尔值的函数都附了一句警告:调用方必须处理 false,不得假设永远成功。

接收方的对称接口

愿意收下兑换代币的合约实现接收方接口:一张 exchangesReceived 表记录本合约除自家代币外替别人托管了多少币,回调 __targetExchangeCallback__targetExchangeAndSpendCallback 同样只认服务合约的调用,负责把目标代币记到发起人账上或直接转给收款人。两边各有一对 ExchangeExchangeSpent 事件,把每笔兑换留成链上日志。

卡在哪、盲区在哪

把流程串起来:一次 exchangeAndSpend 都发生了什么

把双方接口拼上,能看清一笔“用 A 付 B”的完整动线。发起方调 exchangeAndSpend(目标合约, 数量, 收款人),A 币合约把请求转给中间交换服务合约;服务合约回调 A 合约的 __exchangerCallback 扣掉发起人对应数量的 A 币,再回调目标合约的 __targetExchangeAndSpendCallback,让目标合约凭空增发或以库存把 B 币记给收款人。两边的回调都只认服务合约的调用权,等于约定“动我账本的只有中间人”。全过程中 A 币没有被销毁,它沉淀在 B 币合约的 exchangesReceived 记录里,按发起地址累计在 exchangedBy,按目标合约累计在 exchangedWith,链上随时可数谁家的库存压了多少别家代币。

标准还处处留着一句同一格式的重话:所有返回布尔的函数,调用方必须处理 false。放在 2018 年的 Solidity 惯例里,这是对“失败静默返回假而不 revert”的古老模式打的补丁。读这份提案的价值就在这里——它把换币流程拆成扣款、记账、放款三段并各配一个事件(ExchangeExchangeSpent 在两侧对称出现),后来真正活下来的兑换方案不管用什么做市模型,动作切分几乎都逃不出这三段。

结构读完不难发现问题:兑换比率谁定、流动性哪来、目标合约拒收怎么办,标准一概留白;把持中间服务合约的实体则是全部信任的集中点,它一旦作恶或宕机,双端回调的权限设计再严也没用。这份提案停在 Stagnant,正说明“机制接口完备但经济模型缺位”的设计走不远。它能说明的是一种代币互花的接口骨架,不能说明任何兑换承诺可靠。本文为机制说明,不构成任何投资建议。