Alert Source Discuss
🚧 Stagnant Standards Track: ERC

ERC-2021: 可支付 Token

Authors Fernando Paris <fer@io.builders>, Julio Faura <julio@adhara.io>, Daniel Lehrner <daniel@io.builders>
Created 2019-05-10
Discussion Link https://github.com/ethereum/EIPs/issues/2106
Requires EIP-20, EIP-1066, EIP-1996

简单总结

ERC-20 标准 Token 的扩展,允许 Token 钱包所有者通过调用智能合约并附加支付指令字符串来从其钱包请求支付。

参与者

Token 钱包所有者

拥有钱包并下达支付指令的个人或公司。

Token 合约所有者/代理

负责/拥有 Token 合约以及 Token 发行/铸造的实体、公司。 此参与者负责尝试满足所有支付请求、读取支付指令并关联支付详细信息。

下单者

被授权代表 Token 钱包所有者发起支付订单的参与者。

摘要

Token 钱包所有者(或经批准的地址)可以通过区块链发出支付请求。 这是通过调用 orderPayoutFromorderPayoutFrom 方法完成的,这些方法启动 Token 合约运营者接受或拒绝支付请求的工作流程。 在这种情况下,在提交请求时会提供支付指令,运营者使用这些指令来确定资金的去向。

一般来说,不建议在区块链上逐字地放置明确的支付路由指令,建议使用私有通信替代方案,例如私有频道、加密存储或类似方式(在区块链账本之外)来执行此操作。 另一种(不太理想的)可能性是将这些指令以加密形式放置在指令字段中。

动机

如今,大多数 Token 支付请求都需要先进行中心化交易,以便能够定义支付目的地,从而能够执行支付(销毁交易)。 为了尝试将所有必需的步骤纳入去中心化,公开 Token 生命周期和支付交易的所有必需步骤,支付请求允许钱包所有者通过区块链发起支付订单。 主要优点:

  • 增强了支付、销毁的可追溯性,将发起纳入账本。 所有支付、支付状态都可以存储在链上。
  • 几乎所有资金/Token 生命周期都通过去中心化方法覆盖,并辅以生态系统中常用的私有通信。

在这种情况下,Token 的以下移动是随着流程的进行而完成的:

  • 在启动支付请求时,相应金额的资金将由平台定义的预定义公证人持有,并且支付将置于 Ordered 状态
  • 然后,运营者可以将支付请求置于 InProcess 状态,这会阻止支付的 下单者 取消支付请求
  • 在检查支付是否实际可行后,运营者然后执行持有,这将资金转移到待处理钱包,并将支付置于 FundsInSuspense 状态
  • 然后,运营者将资金转移到链下(通常来自综合账户)到相应的目标账户,然后从待处理钱包中销毁 Token,并将支付置于 Executed 状态
  • 在将请求置于 InProcess 状态之前或之后,运营者还可以拒绝支付,这将资金退还给付款人并消除持有。 支付的最终状态是 Rejected
  • 当支付处于 Ordered 状态并且运营者将其置于 InProcess 状态之前,支付的下单者也可以取消它,这将释放持有并将支付置于最终的 Cancelled 状态

规范

interface IPayoutable /* is ERC-20 */ {
    enum PayoutStatusCode {
        Nonexistent,
        Ordered,
        InProcess,
        FundsInSuspense,
        Executed,
        Rejected,
        Cancelled
    }
    function authorizePayoutOperator(address orderer) external returns (bool);
    function revokePayoutOperator(address orderer) external returns (bool);
    function orderPayout(string calldata operationId, uint256 value, string calldata instructions) external returns (bool);
    function orderPayoutFrom(string calldata operationId, address walletToBePaidOut, uint256 value, string calldata instructions) external returns (bool);
    function cancelPayout(string calldata operationId) external returns (bool);
    function processPayout(string calldata operationId) external returns (bool);
    function putFundsInSuspenseInPayout(string calldata operationId) external returns (bool);
    function executePayout(string calldata operationId) external returns (bool);
    function rejectPayout(string calldata operationId, string calldata reason) external returns (bool);

    function isPayoutOperatorFor(address walletToDebit, address orderer) external view returns (bool);
    function retrievePayoutData(string calldata operationId) external view returns (address walletToDebit, uint256 value, string memory instructions, PayoutStatusCode status);

    event PayoutOrdered(address indexed orderer, string indexed operationId, address indexed walletToDebit, uint256 value, string instructions);
    event PayoutInProcess(address indexed orderer, string indexed operationId);
    event PayoutFundsInSuspense(address indexed orderer, string indexed operationId);
    event PayoutExecuted(address indexed orderer, string indexed operationId);
    event PayoutRejected(address indexed orderer, string indexed operationId, string reason);
    event PayoutCancelled(address indexed orderer, string indexed operationId);
    event PayoutOperatorAuthorized(address indexed walletToBePaidOut, address indexed orderer);
    event PayoutOperatorRevoked(address indexed walletToBePaidOut, address indexed orderer);
}

函数

authorizePayoutOperator

钱包所有者,允许给定的地址成为支付下单者。

参数 描述
orderer 下单者的地址。

revokePayoutOperator

钱包所有者,撤销给定的地址成为支付下单者。

参数 描述
orderer 下单者的地址。

orderPayout

创建一个支付请求,该请求将由 Token 运营者处理。 如果之前已使用过操作 ID,则该函数必须恢复。

参数 描述
operationId 用于标识请求的唯一 ID
value 要支付的金额。
instruction 包含支付指令的字符串。

orderPayoutFrom

代表钱包所有者创建一个支付请求,该请求将由 Token 运营者处理。 如果之前已使用过操作 ID,则该函数必须恢复。

参数 描述
operationId 用于标识请求的唯一 ID
walletToBePaidOut 代表要支付的钱包。
value 要支付的金额。
instruction 包含支付指令的字符串。

cancelPayout

取消支付请求。

参数 描述
operationId 用于标识要取消的请求的唯一 ID。 这只能由 Token 持有者或支付发起者/下单者完成。
reason 解释为什么支付请求被拒绝的具体原因。 可以使用 EIP-1066 代码。

processPayout

将支付请求标记为正在处理中。 状态为正在处理中后,订单无法取消。

参数 描述
operationId 用于标识请求正在处理中的唯一 ID。

putFundsInSuspenseInPayout

将给定的支付置于待处理状态。 只有在处理中才能完成。

参数 描述
operationId 用于标识请求正在处理中的唯一 ID。

executePayout

销毁 Token 数量并将支付请求标记为已执行。

参数 描述
operationId 用于标识已执行的请求的唯一 ID。

rejectPayout

由于某种原因拒绝给定的操作。

参数 描述
operationId 用于标识已执行的请求的唯一 ID。
reason 解释为什么支付请求被拒绝的具体原因。 可以使用 EIP-1066 代码

isApprovedToOrderPayout

检查给定的玩家是否被允许为给定的钱包下达支付请求。

参数 描述
walletToBePaidOut 要支付的钱包,并检查批准权限。
orderer 要检查批准权限的下单者的地址。

retrievePayoutData

检索所有支付请求数据。 只有运营者、tokenHolder 和下单者才能获得给定的操作数据。

参数 描述
orderer 下单者的地址,以关联正确的数据。
operationId 用于标识支付订单的唯一 ID。

事件

支付已下单

当 Token 钱包所有者下达支付请求时发出。

参数 描述
operationId 用于标识请求的唯一 ID
walletToBePaidOut 请求支付的钱包
value 要资助的金额。
instruction 包含支付指令的字符串。

支付资金待处理

当运营者将资金置于待处理状态时发出。

参数 描述
orderer 支付请求下单者的地址。
operationId 用于标识支付的唯一 ID。

支付正在处理中

当运营者接受支付请求并且操作正在处理中时发出。

参数 描述
orderer 支付请求下单者的地址。
operationId 用于标识支付的唯一 ID。

支付已执行

当运营者已执行支付请求时发出。

参数 描述
orderer 支付请求下单者的地址。
operationId 用于标识支付的唯一 ID。

支付已拒绝

当运营者已拒绝支付请求时发出。

参数 描述
orderer 支付请求下单者的地址。
operationId 用于标识支付的唯一 ID。
reason 解释为什么支付请求被拒绝的具体原因。 可以使用 EIP-1066 代码

支付已取消

当 Token 持有者、下单者取消支付请求时发出。 只有在运营者未将支付订单置于处理中时才能执行此操作。

参数 描述
orderer 支付请求下单者的地址。
operationId 每个支付发行者用于标识支付的唯一 ID。

支付运营者已授权

当给定的玩家、运营者、公司或给定的角色已被批准为给定的 Token 持有者启动支付请求时发出。

参数 描述
walletToBePaidOut 允许玩家启动支付请求的钱包
orderer 允许玩家启动请求的地址。

支付运营者已撤销

当给定的玩家已被撤销启动支付请求时发出。

参数 描述
walletToBePaidOut 允许玩家启动支付请求的钱包
orderer 允许玩家启动请求的地址。

基本原理

此标准提供了一种功能,允许 Token 持有者以分散的方式启动支付请求。

重要的是要强调 Token 运营者需要处理所有支付请求,并根据将要完成的关联支付更新支付状态。

支付指令格式是开放的。 ISO 支付标准是一个很好的起点。

此 EIP 使用 EIP-1996 在支付已下达后持有资金。 Token 合约所有者或代理(其实现不属于本提案的一部分)充当预定义的公证人,以决定是否执行支付。

operationId 是一个字符串,而不是更节省 gas 的东西,以便于跟踪持有并允许人类可读的 ID。 字符串是否应存储在链上或仅存储其哈希值取决于实施者,因为它足以识别持有。

operationId 是一种竞争性资源。 建议(但不是必需)持有发行人使用唯一前缀以避免冲突。

向后兼容性

此 EIP 是完全向后兼容的,因为它的实现扩展了 ERC-20 和 [ERC-1996] 的功能。

实现

GitHub 存储库 IoBuilders/payoutable-token 包含参考实现。

贡献者

本提案由 adhara.ioio.builders 共同实施。

版权

版权及相关权利通过 CC0 放弃。

Citation

Please cite this document as:

Fernando Paris <fer@io.builders>, Julio Faura <julio@adhara.io>, Daniel Lehrner <daniel@io.builders>, "ERC-2021: 可支付 Token [DRAFT]," Ethereum Improvement Proposals, no. 2021, May 2019. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2021.