本文介绍了Token Collectors,它是一种用于链上支付基础设施的模块化系统,旨在解决token授权方法碎片化的问题。Token Collectors通过抽象出特定的消费机制,实现了与各种token和钱包的兼容,同时保证了安全。文章还详细介绍了TokenCollector.sol合约的核心接口要求以及五种已实现的collector。
在构建链上支付基础设施时,最大的挑战之一是代币授权方法的碎片化。当付款人需要在不直接发起交易的情况下授权支出时(从而实现无 gas、异步、操作员驱动的体验),存在多个相互竞争的标准,每个标准都有不同的权衡。
ERC-3009,由 USDC 和几个主要的稳定币实现,提供了优雅的单签名 UX 与非连续 nonce,但是没有被大多数 ERC-20 代币广泛采用。Permit2 提供了与任何 ERC-20 代币的通用兼容性,但需要每个代币的初始设置步骤,从而在首次使用时产生摩擦。Spend Limits 为特定的智能钱包实现(如 Coinbase Smart Wallet)提供最佳体验,但兼容性有限。传统的 ERC-20 授权到处都适用,但需要单独的交易,并且不能是无 gas 的。
这种碎片化创建了一个艰难的选择:选择一个标准会对协议施加一种观点,并排除不兼容的代币和钱包的用户。将多种机制构建到协议中会更具包容性,但最终是原始问题的一个分形。无论我们选择哪种实施方式,随着钱包技术的成熟和新标准的出现,选择的范围将继续发展。
我们没有做出这个选择,而是将协议设计为完全不可知于代币授权方法。解决方案是一个模块化的“代币收集器”系统,该系统抽象出特定的支出机制,同时保持安全保证。
<div align="center"> <img src="diagrams/TokenCollectorsDiagram.png" alt="Token Collectors Architecture Diagram" width="80%"> <p>加粗代币收集器可以被设计成与各种支出机制交互加粗</p> </div>
代币收集器处理资金从付款人到 Escrow 的实际转移,但 AuthCaptureEscrow
并不关心它们是如何工作的,它只是指定所需的金额,并通过余额检查来验证是否收到了资金。操作员可以根据付款人的钱包和代币组合为每个支付选择最佳收集器。收集器实现了用于兑换授权的特定逻辑(无论是 ERC-3009 签名、Permit2 调用还是任何其他方法),而核心协议保持不变。
<div align="center"> <img src="diagrams/TokenCollectionSequence.png" alt="Example authorization flow with ERC3009PaymentCollector" width="80%"> <p>加粗使用 ERC3009PaymentCollector 授权期间的示例调用流程。加粗</p> </div>
这种抽象使系统具有面向未来的能力和普遍的兼容性。随着新的授权标准的出现或钱包技术的发展,开发人员可以简单地实现新的收集器,而无需修改核心协议。最终形成一种支付基础设施,该基础设施适用于长尾的代币和钱包,同时保持对所有参与者的无信任安全保证。
代币收集器是由操作员任意指定的参数,因此不受协议信任。协议通过防重入保护和余额检查来保护自身免受恶意或执行不力的代币收集器的侵害,这些检查确保收集器已交付协议期望的代币。然而,代币收集器受到授权他们消费资金的付款人的信任。当付款人授权支付时,他们授权特定的代币收集器消费他们的资金,这使得正确的收集器实现至关重要。就像所有密码签名都是关键操作一样,付款人不应为未正确实现的代币收集器签署授权。
诚实实现的收集器必须派生出特定于支付的 nonce,以包含在付款人实际生成的实际签名方案(即 ERC-3009、Permit2 等)中(并将完整的支付条款以密码方式绑定到该方案)。这确保了每个授权只能用于其预期的支付。收集器还必须将其 collectTokens 方法的访问权限限制为仅 AuthCaptureEscrow,这可以防止在协议执行上下文之外未经授权的资金转移。
有两种类型的收集器:
支付和退款收集器的分离可以防止原始支付授权授予支付收集器的剩余未用余额被用于支付退款。
TokenCollector.sol
TokenCollector
抽象基合约定义了所有代币收集器必须实现的预期接口。
1. 收集器类型识别
function collectorType() external view returns (CollectorType);
每个收集器都必须通过 CollectorType
枚举(Payment
或 Refund
)声明它处理支付还是退款。AuthCaptureEscrow
验证此类型是否与正在执行的操作匹配,从而确保支付收集器不能用于退款,反之亦然。这可以防止使用剩余支付授权余额来支付退款的可能性。
2. 代币收集函数
function collectTokens(
AuthCaptureEscrow.PaymentInfo calldata paymentInfo,
address tokenStore,
uint256 amount,
bytes calldata collectorData
) external;
这是 AuthCaptureEscrow
调用的主要接口,用于执行代币转账。收集器在内部 _collectTokens
函数中实现其特定的授权逻辑——无论是 ERC-3009 签名、Permit2 转移、传统授权还是任何其他机制。collectorData
参数允许传递收集器特定的信息,如签名或授权证明。基合约强制执行只有 AuthCaptureEscrow
才能调用 collectTokens
,从而防止未经授权的代币收集。各个收集器实现必须确保其授权机制(签名、授权等)已正确实现,以防止在不同支付之间重复使用或未经授权访问用户资金。
3. 与payer无关的hash实用程序
function _getHashPayerAgnostic(AuthCaptureEscrow.PaymentInfo memory paymentInfo) internal view returns (bytes32);
此实用程序函数解决了链下支付构造中的一个常见模式:在不知道哪个特定钱包将签署支付消息之前创建支付消息。该函数暂时将 payer
字段设置为 address(0)
,计算支付 hash,然后恢复原始payer地址。这种与payer无关的哈希可以用作支付的完整详细信息与payer提供的签名之间的密码链接。这种模式是安全的,因为实际的payer地址在签名验证期间被恢复,因此无法伪造。
该协议启动时,已实现的收集器支持以下主要授权模式:
ERC3009PaymentCollector
用例:支持 ERC-3009 的代币(包括 USDC)
receiveWithAuthorization
进行无 gas、基于签名的转移Permit2PaymentCollector
用例:通过 Permit2 的任何 ERC-20 代币
PreApprovalPaymentCollector
用例:具有预授权流程的传统 ERC-20 代币
transferFrom
SpendPermissionPaymentCollector
用例:Coinbase Smart Wallet 用户的最佳 UX,可以涵盖订阅支付计划
SpendPermissionManager
中的原生支持,支持 ERC-6492 用于智能合约钱包签名OperatorRefundCollector
用例:运营商资助的退款
- 原文链接: github.com/base/commerce...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!