Alert Source Discuss
🛑 Withdrawn Standards Track: ERC

ERC-1154: Oracle 接口

Authors Alan Lu (@cag)
Created 2018-06-13
Discussion Link https://github.com/ethereum/EIPs/issues/1161

简单概要

一个用于 Oracle 的标准接口。

摘要

为了使以太坊智能合约与链下系统交互,必须使用 Oracle。这些 Oracle 报告通常是链下的值,允许智能合约对链下系统的状态做出反应。本文对基于推送和拉取的 Oracle 系统进行了区分和选择。此外,本文描述了一个用于 Oracle 的标准接口,允许不同的 Oracle 实现可以互换。

动机

以太坊生态系统目前有许多不同的 Oracle 实现可用,但它们没有提供统一的接口。智能合约系统将被锁定到一组 Oracle 实现中,或者它们将要求开发人员编写特定于给定项目中选择的 Oracle 系统的适配器/端口。

除了命名差异之外,还存在 Oracle 报告解析事务是_推送_状态更改(通过调用受影响的合约),还是更改 Oracle 状态(允许依赖合约从 Oracle _拉取_更新的值)的问题。这些不同的系统语义可能会在它们之间进行适配时引入效率低下。

最终,不同 Oracle 系统的价值来自其底层解析机制,并且这些系统几乎相同的地方应该标准化。

这些 Oracle 可用于回答有关“真实事件”的问题,其中每个 ID 都可以与问题及其答案的规范相关联(因此很可能用于预测市场,基本上)。

另一个用例可能是决策过程,其中 Oracle 给出的结果代表 Oracle 做出的决策(例如未来政体)。DAO 可能需要在决策过程中使用它们。

ID 和结果都有意地非结构化,以便可以表示诸如时间序列数据(通过拆分 ID)和不同类型的结果(如几个中的一个、最多 256 个的任何子集或高达 256 位粒度的范围内的某个值)。

规范

Oracle
一个向区块链报告数据的实体。
Oracle consumer
一个从 Oracle 接收数据的智能合约。
ID
一种索引 Oracle 报告的数据的方式。可以从数据提供答案的问题中导出或与之关联。
Result
与 Oracle 报告的 ID 相关联的数据。此数据通常是与 ID 相关联的问题的答案。已使用的其他等效术语包括:答案、数据、结果。
Report
Oracle 发送到 Oracle consumer 的一对 (ID, result)。
interface OracleConsumer {
    function receiveResult(bytes32 id, bytes result) external;
}

如果 msg.sender 不是被授权为该 id 提供 result 的 Oracle,则 receiveResult 必须 revert。

如果之前已经使用相同的 id 调用过 receiveResult,则 receiveResult 必须 revert。

如果 consumer 无法处理 idresult,则 receiveResult 可能会 revert。

Consumers 必须与 Oracles 协调,以确定如何将结果编码/解码为 bytes 和从 bytes 解码。例如,abi.encodeabi.decode 可用于在 Solidity 中实现结果的编解码器。如果 consumer 从 Oracle 收到意外的结果格式,则 receiveResult 应该 revert。

Oracle 可以是任何以太坊帐户。

理由

这些规范目前与 ChainLink(可以使用任何任意命名的回调)和 Oraclize(使用 __callback)的实现非常相似。

有了这个规范,Oracle 将状态_推送_到 consumer,后者必须对更新后的状态做出相应的反应。可以规定一个替代的基于_拉取_的接口,如下所示:

替代的基于拉取的接口

以下是基于 Gnosis 预测市场合约 v1 的替代规范。Reality Check 也暴露了一个类似的端点(getFinalAnswer)。

interface Oracle {
    function resultFor(bytes32 id) external view returns (bytes result);
}

如果 id 的结果尚不可用,则 resultFor 必须 revert。

在结果可用之后,resultFor 必须为 id 返回相同的结果。

推送 vs 拉取

请注意,基于推送的接口可以适应为基于拉取的接口。只需部署一个 Oracle consumer,它存储收到的结果并相应地实现 resultFor

同样,每个基于拉取的系统都可以适应为基于推送的系统:只需在 Oracle 智能合约上添加一个方法,该方法接受 Oracle consumer 地址并在该地址上调用 receiveResult

在这两种情况下,都必须执行额外的事务,因此选择使用推送还是拉取应基于这些 Oracle 的主要用例。

在单个帐户有权决定 Oracle 问题结果的简单情况下,无需部署 Oracle 合约并将结果存储在该 Oracle 合约上。同样,如果结果归结为投票,则可以将现有的多重签名钱包用作授权的 Oracle。

多个 Oracle Consumers

如果许多 Oracle consumers 依赖于单个 Oracle 结果,并且所有这些 consumers 都希望将结果推送给他们,那么如果不能信任推送 Oracle 将相同的结果发送给每个 consumer,则可以将前面提到的推送和拉取适配结合起来(从某种意义上说,这会将信任转发给 Oracle 适配器实现)。

在基于拉取的系统中,必须调用每个 consumer 以从 Oracle 合约中拉取结果,但在提议的基于推送的系统中,必须调用适配的 Oracle 以将结果推送到每个 consumer。

在事务方面,这两个系统在这种情况下在效率上大致相当,但在基于推送的系统中,Oracle consumers 需要再次存储结果,而在基于拉取的系统中,consumers 可以继续引用 Oracle 来获取结果。虽然这可能效率稍低,但要求 consumers 存储结果也可以提供安全保证,尤其是在结果不变性方面。

结果不变性

在提议的规范和替代规范中,结果一旦确定就不可变。这是因为期望典型的 consumers 将要求结果是不可变的,以便一致地确定结果状态。在提议的基于推送的系统中,consumer 强制执行结果不变性要求,而在替代的基于拉取的系统中,要么必须信任 Oracle 正确实施规范并强制执行不变性要求,要么 consumer 也必须处理结果不变性。

对于随时间变化的数据,可以构造 id 字段以指定数据的“什么”和“什么时候”(使用 128 位来指定“什么时候”对于许多个千年来说仍然是安全的)。

实现

版权

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

Citation

Please cite this document as:

Alan Lu (@cag), "ERC-1154: Oracle 接口 [DRAFT]," Ethereum Improvement Proposals, no. 1154, June 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1154.