Alert Source Discuss
🚧 Stagnant Standards Track: ERC

ERC-1081: 标准悬赏

Authors Mark Beylin <mark.beylin@consensys.net>, Kevin Owocki <kevin.owocki@consensys.net>, Ricardo Guilherme Schmidt (@3esmit)
Created 2018-05-14
Discussion Link https://gitter.im/bounties-network/Lobby
Requires EIP-20

简单概述

一个用于在以太坊上发布悬赏的标准合约和接口,可用于任何类型的任务,以任何 ERC20 代币或 ETH 支付。

摘要

为了鼓励以太坊上悬赏跨平台互操作性,并简化声誉跟踪,StandardBounties 可以促进资金管理,以换取与已完成任务相对应的可交付成果,以公开可审计且不可变的方式进行。

动机

在缺乏以太坊悬赏标准的情况下,平台很难协作和共享用户创建的悬赏(从而重新创建目前存在于 Web2.0 任务外包平台上的围墙花园)。跨任务类型标准化这些交互,也使得跟踪各种声誉指标(例如,您支付已完成提交的频率,或您的工作被接受的频率)变得更加容易。

规范

在研究了数千年来存在的悬赏之后(以及在主网上以 beta 形式实现和处理了 300 多个悬赏之后),我们发现每个悬赏都有 3 个核心步骤:

  • 一个悬赏被发布:一个 issuer 指定任务的要求,描述期望的结果,以及他们愿意为完成该任务支付多少(以一个或多个代币表示)。
  • 一个悬赏被完成:一个悬赏 fulfiller 可能会看到悬赏,完成任务,并产生一个可交付成果,该成果本身就是任务的期望结果,或者只是完成任务的记录。这些可交付成果的哈希应该以不可变的方式存储在链上,以作为事后证明。
  • 一个完成被接受:一个悬赏 issuerarbiter 可能会选择一个或多个提交被接受,从而向悬赏完成者支付报酬,并将给定的可交付成果的所有权转移给 issuer

为了实现这些步骤,需要一些函数:

  • initializeBounty(address _issuer, address _arbiter, string _data, uint _deadline):这在部署新的 StandardBounty 合约时使用,并且在应用代理设计模式时特别有用,在这种模式下,悬赏无法在其构造函数中初始化。在这里,数据字符串应该代表一个 IPFS 哈希,对应于符合模式(如下所述)的 JSON 对象。
  • fulfillBounty(address[] _fulfillers, uint[] _numerators, uint _denomenator, string _data):调用此函数以提交完成,提交一个表示 IPFS 哈希的字符串,其中包含悬赏的可交付成果。最初,完成只能由一个人一次提交,但是用户一直告诉我们,他们希望能够协作完成,从而允许提交的功劳由多方共享。最终支付的分裂方式由归功于每个完成者的提交比例决定(使用分子数组和单个分母)。在这里,悬赏平台也可以将自己作为合作者 शामिल,以收取一小笔费用,用于将悬赏与完成者进行匹配。
  • acceptFulfillment(uint _fulfillmentId, StandardToken[] _payoutTokens, uint[] _tokenAmounts)issuerarbiter 调用此函数以支付给定的完成,使用代币数组和每个代币的金额数组在贡献者之间分配。这允许悬赏支付金额根据传入的贡献进行必要的调整(这些贡献可以直接转移到合约地址)。如果需要,它还允许轻松地将给定的悬赏余额分配给多个完成。
    • drainBounty(StandardToken[] _payoutTokens):如果需要,issuer 可以调用此函数来耗尽悬赏的资金。
  • changeBounty(address _issuer, address _arbiter, string _data, uint _deadline)issuer 可以调用此函数来更改其悬赏的 issuerarbiterdatadeadline 字段。
  • changeIssuer(address _issuer)issuer 可以调用此函数来更改为新的 issuer(如果需要)
  • changeArbiter(address _arbiter)issuer 可以调用此函数来更改为新的 arbiter(如果需要)
  • changeData(string _data)issuer 可以调用此函数来仅更改 data
  • changeDeadline(uint _deadline)issuer 可以调用此函数来仅更改 deadline

可选函数:

  • acceptAndFulfill(address[] _fulfillers, uint[] _numerators, uint _denomenator, string _data, StandardToken[] _payoutTokens, uint[] _tokenAmounts):在本标准开发过程中,我们发现完成者希望避免支付 gas 费,委托悬赏的 issuer 为他们提交,同时接受它。这很有用,因为它仍然不可变地存储了代币交换已完成的工作,但避免了新的悬赏完成者需要任何 ETH 来预先支付 gas 成本,然后才能获得收入。
  • changeMasterCopy(StandardBounty _masterCopy):对于 issuer 来说,如果采用代理设计模式,能够更改其代理合约所依赖的 masterCopy。
  • refundableContribute(uint[] _amounts, StandardToken[] _tokens):虽然可以通过将这些代币转移到它所在的地址来向悬赏发送不可退款的捐款,但人们可能还希望捐款给悬赏,并可以选择退还其捐款,如果悬赏从未收到正确的提交并已支付。 refundContribution(uint _contributionId):如果悬赏尚未支付给任何正确的提交,并且已超过截止日期,则那些使用 refundableContribute 函数的人可以从合约中取回他们的资金。

模式 Persona 模式:

{
   name: // 可选 - 表示 persona 名称的字符串
   email: // 可选 - 表示 persona 首选联系电子邮件的字符串
   githubUsername: // 可选 - 表示 persona github 用户名的字符串
   address: // 必需 - persona 的字符串 web3 地址
}

悬赏发布 data 模式:

{
  payload: {
    title: // 表示悬赏标题的字符串
    description: // 表示悬赏描述的字符串,包括所有要求
    issuer: {
       // 悬赏发布者的 persona
    },
    funders:[
       // 那些资助发行的人的 personas 数组。
    ],
    categories: // 字符串数组,表示所请求的任务类别
    tags: // 标签数组,表示悬赏的各种属性
    created: // 创建悬赏时的秒级时间戳
    tokenSymbol: // 悬赏支付的代币符号
    tokenAddress: // 悬赏支付的代币地址(ETH 为 0x0)

    // ------- 在此处添加可选字段 -------
    sourceFileName: // 表示文件名的字符串
    sourceFileHash: // 与悬赏关联的文件的 IPFS 哈希
    sourceDirectoryHash: // 可用于访问文件的目录的 IPFS 哈希
    webReferenceURL: // 指向相关 Web 参考的链接(即 github 问题)
  },
  meta: {
    platform: // 表示原始发布平台的字符串(即“gitcoin”)
    schemaVersion: // 表示版本号的字符串(即“0.1”)
    schemaName: // 表示模式名称的字符串(即“standardSchema”或“gitcoinSchema”)
  }
}

悬赏 fulfillment 数据模式:

{
  payload: {
    description: // 一个字符串,表示完成的描述,以及任何与作品的必要链接
    sourceFileName: // 一个字符串,表示正在提交的文件的名称
    sourceFileHash: // 一个字符串,表示正在提交的文件的 IPFS 哈希
    sourceDirectoryHash: // 一个字符串,表示保存正在提交的文件的目录的 IPFS 哈希
    fulfillers: {
      // 正在提交其工作的人员的 personas
    }

    // ------- 在此处添加可选字段 -------
  },
  meta: {
    platform: // 表示原始发布平台的字符串(即“gitcoin”)
    schemaVersion: // 表示版本号的字符串(即“0.1”)
    schemaName: // 表示模式名称的字符串(即“standardSchema”或“gitcoinSchema”)
  }
}

理由

本标准的开发始于一年前,目的是鼓励以太坊上悬赏实现的互操作性。最初的版本有更多的限制:悬赏的 data 在发布后不能更改(对于悬赏 issuer 来说,在工作进行中更改要求似乎不公平),并且悬赏支付不能更改(所有资金都需要在悬赏合约中存入,然后才能接受提交)。

最初的版本的可扩展性也差得多,并且仅允许对给定的一组履行进行固定付款。这个新版本使资金可以在多个正确提交之间分配,提交可以在多个贡献者之间共享,并且付款不仅可以像以前一样以单个代币支付,而且可以根据悬赏问题的 issuer 的要求以尽可能多的代币支付。这些设计决策是在 Gitcoin、Bounties Network 和 Status Open Bounty 上线并在 Web3.0 生态系统中为存储库有意义地促进悬赏 8 个月之后做出的。

测试用例

我们实现的测试可以在这里找到:https://github.com/Bounties-Network/StandardBounties/tree/develop/test

实现

参考实现可以在这里找到:https://github.com/Bounties-Network/StandardBounties/blob/develop/contracts/StandardBounty.sol 虽然此代码已经过测试,但尚未经过审计或错误悬赏,因此我们无法对其正确性做出任何断言,也无法鼓励使用它在以太坊主网上持有资金。

版权

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

Citation

Please cite this document as:

Mark Beylin <mark.beylin@consensys.net>, Kevin Owocki <kevin.owocki@consensys.net>, Ricardo Guilherme Schmidt (@3esmit), "ERC-1081: 标准悬赏 [DRAFT]," Ethereum Improvement Proposals, no. 1081, May 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1081.