Alert Source Discuss
🚧 Stagnant Standards Track: ERC

ERC-1337: 区块链上的订阅

Authors Kevin Owocki <kevin@gitcoin.co>, Andrew Redden <andrew@blockcrushr.com>, Scott Burke <scott@blockcrushr.com>, Kevin Seagraves <k.s.seagraves@gmail.com>, Luka Kacil <luka.kacil@gmail.com>, Štefan Šimec <stefan.simec@gmail.com>, Piotr Kosiński (@kosecki123), ankit raj <tradeninja7@gmail.com>, John Griffin <john@atchai.com>, Nathan Creswell <nathantr@gmail.com>
Created 2018-08-01
Discussion Link https://ethereum-magicians.org/t/eip-1337-subscriptions-on-the-blockchain/4422
Requires EIP-20, EIP-165

简单总结

按月订阅是传统网络的一个关键的盈利渠道,并且可以说,它们是传统网络上企业最健康的盈利渠道(特别是与基于广告/监控的模式相比)。它们可以说比基于代币的经济系统更健康(取决于ICO的归属模型),因为

对于用户:
  • 你不必阅读复杂的白皮书来使用 dapps 的实用程序(与实用代币相反)
  • 你不必了解创始人的归属时间表
  • 你可以随时取消
对于服务提供商:
  • 因为你知道你的订阅者数量、流失率、转化率,所以你可以获得稳定的现金流和准确的预测
  • 你可以专注于让你的客户满意
  • 使你能够将投机者从你的生态系统中移除

由于这些原因,我们认为创建一个在以太坊上执行“订阅”的标准方法是当务之急。

摘要

为了启用可重放的交易,用户签署一个连接的字节哈希,该哈希由执行交易所需的输入数据组成。这些数据由付款的接收者链下存储,并与提供的签名一起传输到客户的智能合约以供执行。

动机

经常性付款是 SaSS 和无数其他业务的基石,定义这种交互的强大规范将使各种收入生成和商业模式成为可能。

规范

枚举合约

EIP-1337 合约应使用引用操作所需的所有枚举的合约进行编译

/// @title Enum - 枚举集合
/// 原始概念来自 Richard Meissner - <richard@gnosis.pm> Gnosis 安全合约
contract Enum {
    enum Operation {
        Call,
        DelegateCall,
        Create,
        ERC20, 
        ERC20Approve
    }
    enum SubscriptionStatus {
        ACTIVE,
        PAUSED,
        CANCELLED,
        EXPIRED
    }
    
    enum Period {
        INIT,
        DAY,
        WEEK,
        MONTH
    }
}

EIP-165

EIP-1337 兼容合约支持 EIP-165,声明它们支持哪些接口

interface ERC165 {
  /**
   * @notice 查询合约是否实现了接口
   * @param interfaceID 接口标识符,如 ERC-165 中指定
   * @dev 接口标识在 ERC-165 中指定。 此函数
   * 使用少于 30,000 gas。
   * @return `true` 如果合约实现了 `interfaceID` 并且
   * `interfaceID` 不是 0xffffffff,否则为 `false`
   **/
  function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

公共视图函数

isValidSubscription

/** @dev 检查订阅是否有效。
  * @param bytes subscriptionHash 是客户订阅的标识符,其中包含其相关详细信息。
  * @return success 是订阅是否有效的结果。
  **/

function isValidSubscription(
            uint256 subscriptionHash
        ) 
        public 
        view 
        returns (
            bool success
        )
getSubscriptionStatus

/** @dev 返回订阅的值
  * @param bytes subscriptionHash 是客户订阅的标识符,其中包含其相关详细信息。
  * @return status 是当前订阅的枚举状态,0 表示已过期,1 表示活动,2 表示已暂停,3 表示已取消
  **/
function getSubscriptionStatus(
        uint256 subscriptionHash
    )
    public 
    view 
    returns (
        uint256 status, 
        uint256 nextWithdraw
    )
getSubscriptionHash
/** @dev 返回连接到持有逻辑的合约地址的输入的哈希。
  * 所有者将签署此哈希,然后将其提供给一方以便稍后执行,
  * 这可以被视为一张支票,但除非你专门
  * 在链上捕获哈希,否则有效的签名将在稍后执行,捕获哈希允许你修改状态以取消或使其过期。
  * @param address recipient 收款人的地址。
  * @param uint256 value 交易的价值
  * @param bytes data 用户同意的数据
  * @param uint256 txGas 执行其中一项交易的 gas 成本(可能安全地填充此值)
  * @param uint256 dataGas 执行交易数据部分(委托调用等)的成本
  * @param uint 256 gasPrice 执行此订阅的约定的 gas 成本(成本发生取决于实施,即,发送者或接收者)
  * @param address gasToken gas 将被补偿的代币地址,address(0) 是 ETH,仅适用于托管实施的情况)
  * @param bytes meta 具有 4 个槽的动态字节数组,2 个必需,2 个可选 // address refundAddress / uint256 period / uint256 offChainID / uint256 expiration (uinx 时间戳)
  * @return bytes32,返回连接到持有逻辑的合约地址的哈希输入参数。
  **/
function getSubscriptionHash(
        address recipient,
        uint256 value,
        bytes data,
        Enum.Operation operation,
        uint256 txGas,
        uint256 dataGas,
        uint256 gasPrice,
        address gasToken,
        bytes meta
    )
    public
    view
    returns (
        bytes32 subscriptionHash
    )
getModifyStatusHash
/** @dev 返回所有者用户将使用其公钥签署的连接输入的哈希
  * @param address recipient 收款人的地址。
  * @param uint256 value 交易的价值
  * @return bytes32 返回连接输入与持有订阅哈希的合约地址的哈希
  **/
function getModifyStatusHash(
        bytes32 subscriptionHash
        Enum.SubscriptionStatus status
    )
    public
    view
    returns (
        bytes32 modifyStatusHash
    )

公共函数

modifyStatus

/** @dev 修改当前订阅状态
  * @param uint256 subscriptionHash 是客户订阅的标识符,其中包含其相关详细信息。
  * @param Enum.SubscriptionStatus status 订阅的新状态
  * @param bytes 调用请求方法的签名
  * @return success 是订阅暂停的结果
  **/
function modifyStatus(
        uint256 subscriptionHash, 
        Enum.SubscriptionStatus status, 
        bytes signatures
    ) 
    public 
    returns (
        bool success
    )
executeSubscription

/** @dev 返回连接到持有逻辑的合约地址的输入的哈希。
  * 所有者将签署此哈希,然后将其提供给一方以便稍后执行,
  * 这可以被视为一张支票,但除非你专门
  * 在链上捕获哈希,否则有效的签名将在稍后执行,捕获哈希允许你修改状态以取消或使其过期。
  * @param address recipient 收款人的地址。
  * @param uint256 value 交易的价值
  * @param bytes data 用户同意的数据
  * @param uint256 txGas 执行其中一项交易的 gas 成本(可能安全地填充此值)
  * @param uint256 dataGas 执行交易数据部分(委托调用等)的成本
  * @param uint 256 gasPrice 执行此订阅的约定的 gas 成本(成本发生取决于实施,即,发送者或接收者)
  * @param address gasToken gas 将被补偿的代币地址,address(0) 是 ETH,仅适用于托管实施的情况)
  * @param bytes meta 具有 4 个槽的动态字节数组,2 个必需,2 个可选 // address refundAddress / uint256 period / uint256 offChainID / uint256 expiration (uinx 时间戳)
  * @param bytes signatures 连接在一起的签名,这些签名已签署输入作为有效执行的证明
  * @return bool success 值得注意的是,执行失败仍将向交易发行人支付其 gas 费用。
  **/
function executeSubscription(
        address to,
        uint256 value,
        bytes data,
        Enum.Operation operation,
        uint256 txGas,
        uint256 dataGas,
        uint256 gasPrice,
        address gasToken,
        bytes meta,
        bytes signatures
    )
    public 
    returns (
        bool success
    )

理由

接受信用卡的商家通过存储从第三方处理器(stripe、paypal 等)检索的令牌来做到这一点,此令牌用于授予从 cx 的信用卡提供商提取付款并将资金转移到商家帐户的权限。 让用户签署输入数据的作用方式相似,并使商家能够存储连接的字节哈希的签名以及用于生成哈希的输入数据,并将其传递给持有订阅逻辑的合约,从而实现类似于当前传统网络中存在的工作流程。

向后兼容性

不适用

测试用例

待定

实施

待定

版权

CC0 下放弃版权和相关权利。

Citation

Please cite this document as:

Kevin Owocki <kevin@gitcoin.co>, Andrew Redden <andrew@blockcrushr.com>, Scott Burke <scott@blockcrushr.com>, Kevin Seagraves <k.s.seagraves@gmail.com>, Luka Kacil <luka.kacil@gmail.com>, Štefan Šimec <stefan.simec@gmail.com>, Piotr Kosiński (@kosecki123), ankit raj <tradeninja7@gmail.com>, John Griffin <john@atchai.com>, Nathan Creswell <nathantr@gmail.com>, "ERC-1337: 区块链上的订阅 [DRAFT]," Ethereum Improvement Proposals, no. 1337, August 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1337.