Oracle-预言机

为什么需要预言机?

  1. EVM和智能合约没有内在的随机性来源
  2. 外部数据只能作为交易的数据载荷引入(而不能通过智能合约去查询)

为什么EVM和智能合约没有内在的随机性来源?

因为Pow共识,如果一个在EVM和智能合约内部真的有随机性的数据,并且智能合约使用了这些数据。那么极有可能无法达成共识,因为挖矿的矿工获得的随机数和其他验证者获得的随机数会不一样。

为什么外部数据只能作为交易的数据载荷引入?

如果在合约内部使用随机数,比如区块的高度,hash函数等伪随机数,那么矿工只打包有利于自己的随机结果即可。而从外部传入随机数据矿工就无法控制了。

预言机的应用场景和示例

理想情况下,预言机提供了一种无信任(即无需信任提供的数据的人或组织)的方式来获取链外信息。

应用场景

有些预言机是提供特定的私有数据源的数据,例如:

  • 大学毕业证书

  • 政府ID

  • 护照

  • 征信报告

以上这些这些数据是掌握在大学、政府部门等,你只能信任他们。(不信任也没办法,你无法证明他们提供的数据不正确)

其他可能由预言机提供的数据示例包括:

  • 物理随机数源或熵源:如在彩票智能合约中公平地选出获胜者
  • 与自然灾害相关的参数触发器:触发大型自然灾害债券智能合约
  • 汇率数据:例如让加密货币与法币精确挂钩
  • 资本市场数据:例如为一揽子代币化资产或证券定价(数字货币基金)
  • 指标引用数据:例如将利率纳入智能金融衍生品合约
  • 统计与准统计数据:安全标识、国家代码、货币代号等
  • 时间和间隔数据:基于精准的SI(国际单位制)时间度量的事件触发器
  • 天气数据:例如给予天气预报的保险费计算器
  • 政治事件:预测市场走势
  • 运动事件:预测市场走势以及体育博彩相关的合约
  • 地理定位数据:例如供应链跟踪
  • 损坏程度核验:保险合约
  • 其他区块链上发生的事件:可互操作函数
  • 以太币市场价格:例如gas价格预言机
  • 航班统计数据:例如用于团体和俱乐部的机票合同

预言机的设计模式

预言机的关键功能

根据定义,所有预言机都提供了一些关键功能。这些能力包括:

  • 从链外的数据源收集数据
  • 使用签名消息在链上传输数据
  • 将数据放入智能合约的存储空间,使数据可用

实现预言机的三种主要方式

设置预言机的三种主要方式可以分为请求/响应、发布于订阅和立即读取。

立即读取

  • 这种预言机提供及时决策所需的数据

  • 这种预言机的例子包括那些持有组织数据或有组织发布数据(例如学术证书、拨号代码、机构会员资格、机场标识符、自主ID等)的预言机

  • 这种预言机存储中的数据也可以通过区块链启用应用程序(Geth)直接在本地查找,不需要消耗gas

  • 这种预言机存储的数据和实际组织提供的数据可能不一样。(为了保密只需要在合约存储hash即可)

发布与订阅

  • 在这种预言机中,要对预期改变的数据提供有效的广播服务,预言机要么由链上的智能合约轮询,要么由链外的守护进程监视和更新
  • 这种预言机的示例包括价格推送、天气预报、经济或社会统计、交通数据等
  • 以太坊时间日志应用程序特别容易注意预言机更新
  • 但是如果使用智能合约去轮询可能会产生大量的gas支出

请求与响应

这是数据空间太大而无法存储在智能合约中的情况,并且用户每次只需要整个数据集的一小部分。它也是数据提供商业务的适用模型

请求与响应预言机的步骤可以总结如下:

  1. 接收来自DApp的查询
  2. 解析查询
  3. 检查是否提供了付款和数据访问权限
  4. 从链外数据源检索相关数据(并在必要时加密)
  5. 使用包含的数据对交易进行签名
  6. 将交易广播到网络
  7. 安排任何进一步必要的交易,例如通知等

数据认证

两种常见的数据认证方法:

  • 真实性证明(authenticity proof)
  • 可信执行环境(Trusted Execution Environment,TEE)

真实性证明

真实性证明是用密码学证据证明数据没有被篡改过。

TLSNotary:

img

可信执行环境

使用Intel SGX来保证对HTTPS查询的响应可以被验证为可信的。

  • SGK提供了完整性保证:使得在安全区中运行的应用程序收到CPU保护。不被其他进程篡改
  • SGK提供了机密性:保证应用程序在安全区中运行时,其状态对其他进程来说是不可知的
  • SGK通过生成应用程序确定在安全区中运行的数字签名,让证明成为可能,只要验证这个签名就能够确认程序在SGK安全区内安全地运行

计算性的预言机

智能合约因为有gas费限制的原因,并不适合做非常复杂的计算。部分提供计算性预言机如下:

去中心化预言机

Solidity中的预言机客户端接口

轮询ETH/USD价格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
pragma solidity ^0.4.22;
import "github.com/provable-things/ethereum-api/provableAPI_0.4.25.sol";

contract ExampleContract is usingProvable {

string public ETHUSD;
event LogConstructorInitiated(string nextStep);
event LogPriceUpdated(string price);
event LogNewProvableQuery(string description);

function ExampleContract() payable {
LogConstructorInitiated("Constructor was initiated. Call 'updatePrice()' to send the Provable Query.");
}

function __callback(bytes32 myid, string result) {
if (msg.sender != provable_cbAddress()) revert();
ETHUSD = result;
LogPriceUpdated(result);
updatePrice();
}

function updatePrice() payable {
if (provable_getPrice("URL") > this.balance) {
LogNewProvableQuery("Provable query was NOT sent, please add some ETH to cover for the query fee");
} else {
LogNewProvableQuery("Provable query was sent, standing by for the answer..");
provable_query(60, "URL", "json(https://api.pro.coinbase.com/products/ETH-USD/ticker).price");
}
}