Alert Source Discuss
🚧 Stagnant Standards Track: ERC

ERC-1620: 资金流

Authors Paul Berg (@PaulRBerg)
Created 2018-11-24
Discussion Link https://github.com/ethereum/EIPs/issues/1620

简单概要

资金流代表了在有限的时间内连续支付的想法。区块号被用作时间的代理来连续更新余额。

摘要

以下描述了一个标准,其中时间是使用区块号来衡量的,并且资金流是主合约中的映射。

  1. 提供者设置资金流合约。
  2. 潜在的付款人可以与合约交互,并通过存入所选期间所需的资金立即开始资金流。
  3. 收款人能够根据其持续的偿付能力从合约中提取资金。 也就是说:支付率 * (当前区块高度 - 起始区块高度)
  4. 如果双方都承诺签名,则可以随时更新资金流条款(支付率、时长、元数据)。
  5. 资金流可以在任何时间点被任何一方停止,而无需链上共识。
  6. 如果资金流期间结束且之前未被任何一方停止,则收款人有权提取所有存入的资金。

动机

这个标准化接口旨在改变我们对长期财务承诺的思考方式。 感谢区块链,付款无需分批发送(例如,每月工资),因为按需支付的开销要少得多。 作为时间函数的资金可以更好地协调许多场景中的激励措施。

用例

这只是用例的初步列表。 还有其他有趣的、值得探索的想法,例如与时间相关的反激励措施,但为简洁起见,我们在此处不包括它们。

  • 工资
  • 订阅
  • 咨询
  • CDPs
  • 租金
  • 停车

众筹

RICOs,或称可逆 ICO,由 @frozeman 在 Devcon4 上推出。 其想法是通过允许投资者根据项目的演变“逆转”投资,从而赋予投资者更多的权力和安全保障。 我们之前在这个研究帖子中讨论了一个类似的概念,称为 SICOs,或可流动 ICO。

资金不是一次性投资并交给项目开发者,而是保存在智能合约中,该合约根据时间的推移分配资金。 项目开发者可以在资金流保持活动状态时提取资金,而如果项目停止,投资者有权收回很大一部分初始承诺。

规格

结构体

stream 的结构应如下所示:

  • stream
    • sender:资助资金流的实体的 address
    • recipient:资金交付到的 address
    • tokenAddress:用作支付资产的 ERC20 代币的 address
    • balance:资金流中剩余的总资金
    • timeframe:如下定义
    • rate:如下定义
  struct Stream {
    address sender;
    address recipient;
    address tokenAddress;
    uint256 balance;
    Timeframe timeframe;
    Rate rate;
  }
  • timeframe
    • start:资金流的起始区块号
    • stop:资金流的停止区块号
struct Timeframe {
    uint256 start;
    uint256 stop;
}
  • rate
    • payment:从 sender 转移到 recipient 的金额
    • intervalpaymentsender 转移到 recipient 的频率
struct Rate {
  uint256 payment;
  uint256 interval;
}

方法

balanceOf

返回给定资金流 id 和地址的可用资金。

function balanceOf(uint256 _streamId, address _addr)

getStream

如果 id 指向有效的资金流,则返回完整的资金流数据。

function getStream(uint256 _streamId) returns (address sender, address recipient, address tokenAddress, uint256 balance, uint256 startBlock, uint256 stopBlock, uint256 payment, uint256 interval)

create

msg.sender_recipient 之间创建一个新的资金流。

必须允许发送者并行创建多个资金流。 不应接受 Ether,而仅使用 ERC20 兼容的代币。

触发事件LogCreate

function create(address _recipient, address _tokenAddress, uint256 _startBlock, uint256 _stopBlock, uint256 _payment, uint256 _interval)

withdraw

提取全部或部分可用资金。

必须允许只有收款人才能执行此操作。

触发事件LogWithdraw

function withdraw(uint256 _streamId, uint256 _funds)

redeem

通过将资金分配给发送者和收款人来赎回资金流。

应允许任何一方赎回资金流。

触发事件LogRedeem

function redeem(uint256 _streamId)

confirmUpdate

表示一方愿意更新资金流

应允许任何一方执行此操作,但必须未经所有相关方同意不得执行。

触发事件LogConfirmUpdate

触发事件:当最后一个相关方调用此函数时 LogExecuteUpdate

function update(uint256 _streamId, address _tokenAddress, uint256 _stopBlock, uint256 _payment, uint256 _interval)

revokeUpdate

撤销由相关方之一提出的更新。

必须允许任何一方执行此操作。

触发事件LogRevokeUpdate

function confirmUpdate(uint256 _streamId, address _tokenAddress, uint256 _stopBlock, uint256 _payment, uint256 _interval)

事件

LogCreate

必须在成功调用 create 时触发。

event LogCreate(uint256 indexed _streamId, address indexed _sender, address indexed _recipient, address _tokenAddress, uint256 _startBlock, uint256 _stopBlock, uint256 _payment, uint256 _interval)

LogWithdraw

必须在成功调用 withdraw 时触发。

event LogWithdraw(uint256 indexed _streamId, address indexed _recipient, uint256 _funds)

LogRedeem

必须在成功调用 redeem 时触发。

event LogRedeem(uint256 indexed _streamId, address indexed _sender, address indexed _recipient, uint256 _senderBalance, uint256 _recipientBalance)

LogConfirmUpdate

必须在成功调用 confirmUpdate 时触发。

event LogConfirmUpdate(uint256 indexed _streamId, address indexed _confirmer, address _newTokenAddress, uint256 _newStopBlock, uint256 _newPayment, uint256 _newInterval);

LogRevokeUpdate

必须在成功调用 revokeUpdate 时触发。

event LogRevokeUpdate(uint256 indexed _streamId, address indexed revoker, address _newTokenAddress, uint256 _newStopBlock, uint256 _newPayment, uint256 _newInterval)

LogExecuteUpdate

必须在所有相关方批准更新时触发。

event LogExecuteUpdate(uint256 indexed _newStreamId, address indexed _sender, address indexed _recipient, address _newTokenAddress, uint256 _newStopBlock, uint256 _newPayment, uint256 _newInterval)

理由

此规范旨在作为资金作为时间函数的古怪概念的入口点,并且绝对不是一成不变的。 还考虑了其他几种设计,包括支付通道和 Plasma 链,但最终认为它们假设过于密集,对于初始版本而言没有必要。

区块时间是区块链上时间的合理、无需信任的代理。 在 2016 年至 2018 年期间,以太坊区块时间的平均值徘徊在 14 秒左右,不包括 2017 年的最后两个季度。 从数学上讲,理想的情况是标准差尽可能接近 0,但现实世界并非如此。 这对本 ERC 的可行性具有巨大的影响,我们将在下面进行调查。

GCD

在设置资金流时,付款人和收款人可能希望使总的流式传输持续时间成为他们所运营的链的“最大公约数”(GCD)的倍数; 也就是说,平均区块时间。 这本身在智能合约中不是强制性的,但是为了创建健全且公平的支付机制,需要有一个链下流程将资金流映射到真实世界的时间单位。

区块时间

由于区块时间存在不确定性,因此资金流可能无法像最初计划的那样在区块链上结算。 设 $d 是以秒为单位测量的总流式传输持续时间,$t 是资金流开始之前的平均区块时间,$t' 是资金流开始后 $d 上实际的平均区块时间。 我们区分两种不良情况:

  1. $t < $t': 收款人将比预期更晚收到他们的资金

  2. $t > $t': 收款人将比预期更早收到他们的资金

如果组合的误差增量小于支付率(create 方法的第五个参数,以 wei 为单位),则根本没有问题。 相反,我们遇到了信任问题,因为真实世界的时间范围与资金流条款不符。 例如,如果一名员工通常有权在月底从资金流中提取所有资金,但是区块时间导致发生上述情况 1,则该员工在经济上处于不利地位,因为他们的持续努力没有得到承诺的补偿。

仅将问题范围限制在以太坊,我们提出两种补救措施:

  1. 就调用 update 函数以更正流式传输条款达成共识。 这听起来可能很荒谬,但是在大多数情况下,风险很低,并且资金流参与者参与长期财务承诺。 拒绝合作会产生很高的负激励作用。

  2. 自动修复重大误差增量。 从理论上讲,我们可以使用先前区块的时间戳来实现此目的,即在预定义数量的区块中“检查点”一次资金流。 由于潜在的高 gas 成本开销,这仍然是一个积极的研究领域。

尽管如此,重要的是要注意到,这仍然是对传统模型的重大改进,在传统模型中需要绝对的信任。

侧链

在独立的侧链(如 POA 网络xDai)上实施此标准可能更有效 - 这要归功于它们相当可预测的特性。 诚然,安全性是以可扩展性为代价的,但是适当的密码经济权益可以缓解潜在的问题。

此外,探索特定于资金流的侧链的前景非常有趣。

预言机

拟议的规范使用区块号来代理时间,但这不必是唯一的方法。 尽管这会暗示不同的信任假设,但可以使用预言机来提供时间戳的馈送。 结合上述特定于资金流的侧链的想法,预言机可以有效地解决 区块时间 中概述的问题。

多跳流

此标准的未来或升级版本可能会描述“多跳”流。 如果:

  1. A 和 B 之间存在资金流
  2. B 和 C 之间存在另一个资金流

可以有一种方法可以避免并行运行两个不同的资金流。 也就是说,正在从 A 流向 B 的资金的一部分或全部可以自动连接到 C。一个有趣的用例是税收。 无需手动转移资金,主动计算出您欠多少钱,然后转移资金,资金流可以原子地为您执行这些操作。

实现

其他参考

最终说明

非常感谢 @mmilton41 进行了无数次的头脑风暴会议。 在 @ChronosProtocol 的背景下,我们已经对资金流的主题进行了相当长一段时间的研究。 今年 8 月,我们发布了白皮书的第一个版本,描述了一种 Plasma 方法。 但是,与此同时,我们意识到在以太坊本身和像 xDai 这样的侧链上从小处着手会更加有趣和容易。

版权

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

Citation

Please cite this document as:

Paul Berg (@PaulRBerg), "ERC-1620: 资金流 [DRAFT]," Ethereum Improvement Proposals, no. 1620, November 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1620.