200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 蚂蚁区块链第18课 区块链预言机(ORACLE)的定义及在蚂蚁BAAS中的使用

蚂蚁区块链第18课 区块链预言机(ORACLE)的定义及在蚂蚁BAAS中的使用

时间:2018-08-28 14:40:29

相关推荐

蚂蚁区块链第18课 区块链预言机(ORACLE)的定义及在蚂蚁BAAS中的使用

1,摘要

本文主要讲解外部预言机ORACLE定义和原理,并讲解蚂蚁BAAS系统如何通过ORACLE预言机方式使用外部数据源的方法。

2,外部预言机ORACLE定义和原理

2.1 预言机(Oracle)是什么?

11 月 6 日,中国人民银行发布的《区块链能做什么?不能做什么?》报告中,是这样对预言机定义的。

区块链外信息写入区块链内的机制,一般被称为预言机 (oracle mechanism) 。

预言机的功能就是将外界信息写入到区块链内,完成区块链与现实世界的数据互通。它允许确定的智能合约对不确定的外部世界作出反应,是智能合约与外部进行数据交互的唯一途径,也是区块链与现实世界进行数据交互的接口。

听上去很难理解,我们举例来说。

大家会很形象的把公链比作操作系统(Windows、IOS、安卓),DAPP 类比的话就是 APP,那么预言机可以形象的比做 API 接口。API 是一组定义、程序及协议的集合,通过 API 接口实现计算机软件之间的相互通信。这样类比虽然不准确,但意思就是预言机是区块链和现实世界之间的纽带,可以实现数据互通的工具。

Oracle 为什么被中译为预言机?

跟别人提起预言机,很多人的反应都是预测市场,预言机这个名字确实容易想到预测。

Oracle 最初是来源于古希腊宗教,意为“神谕、先知、预言”。而在互联网领域,预言机(英语:oracle machine),又称谕示机,是一种抽象电脑,用来研究决定型问题。可以被视为一个多了个黑盒子(预言者)的图灵机,这个黑盒子的功能是可以在单一运算之内解答特定问题。

也许你会好奇这跟甲骨文公司有什么关系吗?其实没有关系。

Oracle 在中国叫甲骨文公司的原因可能是另一个故事。在中国商朝晚期,王室把在动物骨骼或龟甲上做占卜记事的文字叫甲骨文,甲骨文被英译为 Oracle bone script,后来 Oracle 公司到中国中译为了甲骨文公司。(很有道理的猜测 哈哈哈?)

2.2 区块链为什么需要预言机?

区块链是一个确定性的、封闭的系统环境,目前区块链只能获取到链内的数据,而不能获取到链外真实世界的数据,区块链与现实世界是割裂的。

一般智能合约的执行需要触发条件,当智能合约的触发条件是外部信息时(链外),就必须需要预言机来提供数据服务,通过预言机将现实世界的数据输入到区块链上,因为智能合约不支持对外请求。

具体原因是这样的。区块链是确定性的环境,它不允许不确定的事情或因素,智能合约不管何时何地运行都必须是一致的结果,所以虚拟机(VM)不能让智能合约有 network call(网络调用),不然结果就是不确定的。

也就是说智能合约不能进行 I/O(Input/Output,即输入/输出),所以它是无法主动获取外部数据的,只能通过预言机将数据给到智能合约。

我们通过一个例子来说明一下。假设现在我被关进了一个小黑屋里(不要多想,只是例子 =-=),我对外面的世界发生了什么几乎一无所知,不知道外面是否有人,即使呼叫也没有人回应,只有外面的人在门口把他看到的听到的都告诉我,我才可以得知外面的世界。

例子虽然不太恰当,但智能合约就像这个例子中的我一样,它无论何时何地,都无法主动向外寻求信息,只能外部把消息或数据给到里面。而预言机就是这个在外面输送消息和数据的人。

好像这么看来,智能合约并不是很智能呀,是的,智能合约其实是完成的不智能的事情,即写好了条件和结果,当给它条件的时候,就可以触发,但也不会马上执行,还需要合约相关的人进行私钥签署才可以执行。

所以,网上很多文章其实都有水分,比如智能合约某个时间或者触发某个条件就可以自动执行之类的,只能说这样的句子在逻辑上是有问题的。关于预言机的很多文章也有水分,描述的并不准确。

好了,上面就是区块链为什么需要预言机,因为智能合约无法主动去获取链外的数据,只能被动接受数据。

2.3 预言机怎么解决这个问题

这就是理想中预言机的工作流程,即用户的智能合约把请求给链上 Oracle 合约,通过链下的 API 接口获得外部数据,更确切的说是外部把数据给链上的 Oracle 合约,然后 Oracle 合约再把数据给用户的智能合约。

或许很难理解,因为在互联网中,调用数据是非常容易的,只需要在程序中写调用的代码就可以了。但是区块链与外部世界的数据交互,确实不能进行这样的操作。

2.4 预言机的应用场景有哪些?

预言机作为区块链与现实世界进行数据交互的桥梁,应用场景非常多,可以说一切需要与链下进行数据交互的DApp都需要预言机。比如金融衍生品交易平台、借贷平台、快递追踪/IoT、稳定币、博彩游戏、保险、预测市场等等。

我们还是举例来说。

**先说最近币圈比较火热的博彩游戏为什么需要预言机。**博彩游戏的核心是不可预测、可验证的随机数,从而决定赌注的最终结果,但是在链上是无法生成随机数的或者说在链上的随机数是可以被预测和破解的,这时候就需要预言机从外部给智能合约安全的、不可预测的随机数。

现在的大多数博彩游戏都是在链上生成随机数,所以很容易被预测和破解,导致资产被盗,大家有兴趣的可以去看一下DApp被盗的相关研究报告,很多因为随机数问题被盗的。比如 BetDice、Dice2Win。

如果大家很感兴趣,可以看一下我男神 DOS Network 创始人@nrekjonny 关于《智能合约中的随机数》的分享。

其实,早在 Fomo3D 这个游戏出来之前,以太坊的 Team Leader 就在推特上说过链上是无法生成随机数的。Dear devs… you can`t generate random numbers on chain!

我们再来看一个关于快递追踪的例子。

假设当我通过某个 DApp 购物平台购买某件物品快递过来的时候,真实世界中的快递寄送或到达信息,就可以通过 Oracle 把数据传递到链上,然后触发链上的智能合约,我用自己的私钥确认收到了快递,并完成付款。

大家发现了吗?这里的智能合约不能自动执行,而是需要我用自己的私钥进行确认,智能合约保证的是没有第三方机构做担保和资金周转(比如支付宝),这就是智能合约的价值。

其他的案例就不细说了,比如稳定币需要链下的利率,保险需要链下的病例或车况等,具体可以看这篇文章《Oracle—区块链与现实世界的纽带》。

2.5 目前公链上的预言机项目

目前在预言机领域探索的项目还不是很多,每一个项目的预言机解决方案都略有差异,我找了几家典型的预言机项目,做一个简单的阐述。

Oraclize:为以太坊提供中心化预言机服务

Oraclize 依托亚马逊 AWS 服务和 TLSNotary 技术,是一个可证明的诚实的预言机服务,不过它是中心化的,目前只能在以太坊网络使用,而且gas费较高。但是不妨碍它是目前很受欢迎的预言机服务,也可能是因为还没有更好的选择吧。这里有 Oraclize 详细的使用说明:Oraclize Documentation

ChainLink:以太坊上第一个去中心化预言机解决方案

ChainLink 的解决方案是通过在链上的智能合约和链下的数据节点,通过奖惩机制和聚合模型的方式,进行数据的请求和馈送。不过也有一些不足,比如链式聚合成本较高,拓展性差,基于声誉系统容易集中化。他们更关注支付场景的应用,比如帮助银行与企业之间建立智能合约。

欧链 OracleChain:EOS 上的第一个去中心化预言机解决方案

欧链很早就提出了预言机的想法和方案,采用自主的 PoRD 机制(Proof-of-Reputation&Deposit),本质上是一种抵押代币奖惩机制的声誉系统,奖励数据节点惩罚作恶节点,可以实现 Augur、Gnosis 等预测市场应用的功能,还能支撑对链外数据有更高频率访问需求的智能合约业务。预测市场的结果本身有时也可以作为 Oracle 的输入数据源,欧链更像是预测市场,而且不足是单纯的声誉系统容易集中化。目前欧链只在 EOS 上开发。

DOS Network:支持多条主流公链的去中心化预言机服务网络

DOS Network 是一个 Layer-2 的预言机解决方案,它通过在链上部署一个轻量级智能合约,链下是一个 p2p 网络,服务节点的选取和数据验证采用 VRF+阈值签名等技术,保证了去中心化和数据安全,并达到快速反应。可以适配所有主流公链,比如以太坊、EOS、Tron、Thunder。目前已在以太坊测试网发布 alpha 版本https://dosnetwork.github.io/docs。

我们也期待预言机技术的不断成熟,进而促进更多区块链与现实世界进行数据交互的 DApp 落地。

3,蚂蚁BAAS实现外部预言机的技术概述

区块链预言机(Oracle)是区块链与外部世界交互的一种实现机制,它通过可信计算技术或者其他建立信任的约束关系,在区块链与外部世界间建立一种可信任的桥接机制,使得外部数据可以安全可靠地进入区块链。

外部数据源服务是基于可信执行环境(Trusted Execution Environment,TEE)技术实现的区块链预言机服务,该服务旨在为区块链智能合约提供可信访问外部数据源能力。

外部数据源服务会在智能合约平台部署一个外部数据源服务合约,用户合约通过调用该服务合约发送外部数据源请求,链下的 TEE 外部数据源服务对接该服务合约,监听用户的请求,然后去对应的外部数据源取数据,最后将结果返回给用户合约。

3.1 实现原理

外部数据源服务使用 TEE 技术实现,对于每笔外部数据请求都将在可信硬件环境中执行。可信硬件环境会验证外部数据源的 TLS 通讯证书以确认数据源的身份,通过 TLS 协议确保拿到的数据没有被第三方篡改。可信硬件环境得到数据后,会使用硬件私钥对数据进行签名,并返回给智能合约,智能合约将自动验证可信硬件的签名,确保数据是可信硬件执行结果,没有被第三方篡改,从而安全可靠地获取来自指定外部数据源的数据。

3.2 功能特性

数据安全可信

区块链预言机底层使用 TEE 技术实现,TEE 是一个安全隔离的执行环境,提供隔离执行、可信应用的完整性、可信数据的机密性、安全存储等安全特征,使预言机服务数据服务安全可信。

支持 HTTPS 协议

通过 HTTPS 协议,区块链预言机会与目标数据源建立端到端的安全通行通道,并且可以完成对数据源的证书校验以确定身份,从而安全、可靠地获取来自指定外部数据源的数据。

支持 JSON API

JSON 是一种轻量级的数据交换格式,广泛地被采用为 API 的数据交换格式。区块链预言机内置 JSON 解析器,如果请求的 URL 响应格式是 JSON 格式,可以在请求命令中设置 jsonpath 命令,使区块链预言机根据 jsonpath 读取部分 JSON 数据,只返回这部分数据上链。

支持访问要权限认证的 API

一些 API 需要认证授权访问,例如使用 OAuth 2.0 协议实现的 API,需要在请求中携带服务端认证鉴权需要的参数,但这些参数属于私密信息不可泄露。这种情况下,利用 TEE 技术提供的机密性,与区块链预言机的 TEE 环境建立端到端的加密信封,使得请求只在 TEE 硬件可信执行环境里面解密,从而不会泄露请求机密。

高可用预言机集群

区块链预言机服务使用集群架构实现,为合约提供高可用的数据访问服务。

3.3 使用场景

外部数据源服务适用于以下任意场景:

智能合约需要可信访问 Web 数据。智能合约通过调用 Open API 使用互联网服务。智能合约需要与外部系统交互。智能合约依赖公共现实事件,如天气、赛事信息、航班信息等。

4,蚂蚁BAAS的外部数据源服务(实现ORACLE预言机)接口

外部数据源服务在区块链上部署了区块链预言机(Oracle)合约,提供异步查询互联网数据接口(CURL)供用户合约使用。正常情况下,用户合约调用预言机合约发起查询请求后,预言机合约在 1~3 个区块内就能得到外部数据源服务取回的数据,然后回调用户合约传入数据。

4.1 开发流程

通过外部数据源服务,让智能合约获取指定外部数据源数据的开发流程如下:

在 BaaS 平台上获得预言机合约 ID(进入联盟,选择联盟内的链> 目标合约链 >管理>跨链管理可查看合约 ID)。获取合约 API 定义(OracleInterface.sol)。在用户合约中引入合约 API 定义(OracleInterface.sol)。用户合约实现回调接口,用于异步接收请求结果。用户请求需要使用 CURL 命令构建外部数据源请求。用户合约向预言机合约发送查询请求,具体参考合约 API 说明。

4.2 合约 API 使用流程

用户的智能合约调用预言机合约的 CURL 接口发起查询请求,预言机合约同步返回查询结果,即请求单据号(reqeust_id)。预言机合约获取到查询结果数据后,会异步回调查询用户合约的回调接口。

4.3 合约 API接口详解

合约 API 定义

OracleInterface.sol 中定义了用户合约与预言机合约的通信接口,其中用户通过 curlRequest 接口调用预言机合约。用户合约需要实现 oracleCallbackCurlResponse 接口,用于接收预言机合约的请求结果回调。

// OracleInterface.solpragma solidity ^0.4.22;// 使用预言机 API 需要在用户合约中开启 ABIEncoderV2 特性pragma experimental ABIEncoderV2; interface OracleInterface {/*** function: 发送 CURL 请求* parameters:* _biz_id : 用户自定义的业务请求 ID* _curl_cmd: CURL 命令,参考 CURL 命令使用文档进行构造* _if_callback : 是否需要预言机将请求结果回调用户合约* _callback_identity : 预言机请求结果回调的合约 ID,可以是发送请求的合约,也可以是其他合约* _delay_time : 该特性未激活,填 0 即可* return value: : 预言机请求 ID,是预言机合约为本次请求生成的唯一请求 ID*/function curlRequestDefault(bytes32 _biz_id, string _curl_cmd, bool _if_callback, identity _callback_identity, uint256 _delay_time) external returns (bytes32);/*** function: oracleCallbackCurlResponse* parameters:* _request_id : 预言机合约请求 ID(在发送请求时预言机合约会返回此 ID)* _biz_id : 用户合约的业务请求 ID* _error_code : 请求结果码,如果值是 0,则表示预言机请求处理成功;如果是其他值,则为请求处理失败,详见合约错误码表* _resp_status : HTTP 响应的状态码,一般 200 表示 HTTP 请求处理成功,5xx 表示服务端处理错误,调用者可根据自己的使用场景做判断* _resp_header : HTTP 响应的 header,如果 CURL 中指定了要返回 HTTP 响应的 header,则回调时会返回对应的值* _resp_body : http 响应的 body* _call_identity: 发起该请求的合约 ID* return value : 无*/function oracleCallbackCurlResponse (bytes32 _request_id, bytes32 _biz_id, uint32 _error_code, uint32 _resp_status, bytes _resp_header, bytes _resp_body, identity _call_identity) external;}

请求接口

curlRequestDefault

curlRequestDefault是业务合约向预言机合约发送请求的接口。

函数原型

function curlRequestDefault(bytes32 _biz_id, string _curl_cmd, bool _if_callback, identity _callback_identity, uint256 _delay_time) external returns (bytes32);

请求参数

返回字段

回调接口

oracleCallbackCurlResponse

回调接口需要业务合约实现,用于接收预言机合约的请求结果回调,如果未能正确实现该合约,则将无法接收请求结果。

业务合约通过 oracleCallbackCurlResponse 来接收预言机合约的 CURL 请求结果回调。

函数原型

function oracleCallbackCurlResponse (bytes32 _request_id, bytes32 _biz_id, uint32 _error_code, uint32 _resp_status, bytes _resp_header, bytes _resp_body, identity _call_identity) external;

请求参数

返回字段

无返回字段。

示例

pragma solidity ^0.4.22;// 使用预言机 API 需要在用户合约中开启 ABIEncoderV2 特性pragma experimental ABIEncoderV2; import "./OracleInterface.sol";// 实现一个demo合约contract BizContract {// 业务 ID 与预言机请求 ID 的关联关系mapping(bytes32 => bytes32) request_id;// 调用预言机合约的 CURL 接口function rawCURLRequest(identity oracle_address, bytes32 biz_id, string cmd) public{// 1. 跨合约调用,需要通过合约 API 定义及合约 ID 生成一个合约对象OracleInterface oracle = OracleInterface(oracle_address);// // 2. 发送 CURL 请求// (例如查询股票行情信息,cmd 参数的值可以是“/list=hk00941”)bytes32 request_id = oracle.curlRequest(service_id, biz_id, cmd, true, this, 0);// 3. 记录预言机返回的request idrequest_id[biz_id] = request_id;// 4. 请求阶段结束,等待回调return;}// 业务合约用于接收预言机合约的 CURL 请求结果回调function oracleCallbackCurlResponse (bytes32 _request_id, bytes32 _biz_id, uint32 _error_code, uint32 _web_status, bytes _resp_header, bytes _resp_body, identity _call_identity) external {// 业务处理回调结果}}

4.4 CURL 命令使用说明

本文主要对外部数据源服务涉及到的 CURL 命令的用法进行说明。

说明:当前外部数据源服务版本暂不支持 HTTP 分块传输编码,即不支持 HTTP 响应的 Transfer-Encoding 为 chunked,后续版本会支持该特性。

NAMEcurlVERSION1.0.0_BETASYNOPSIScurl https://address[:port][/path][?args] [options]DESCRIPTION CURL 命令是预言机提供的 Web API 接口必要传入参数之一。CURL 命令描述了指定预言机访问目的互联网资源的 URI,以及其他可选配置项。当前外部数据源服务版本暂不支持 HTTP 分块传输编码,即不支持 HTTP 响应的 Transfer-Encoding 为 chunked,后续版本会支持该特性。OPTIONS--request <GET|POST>HTTP 访问的方法,支持 GET 和 POST。缺省使用 GET 方法。e.g. --request GET--request POST--header <header:value>指定 HTTP 请求中附带的 header 信息。header 名和 header 值使用冒号分割。如果 header 名或者值包含空格,应该使用单引号将其作为整体包起来,譬如 --header 'content-type:plain text'。--header 选项可以重复使用多次来配置多对 header,最多不超过 100 对。以下为保留 header,用户配置不生效:"Host"、"Accept"、"User-Agent"、"Connection"、"Content-Length"。e.g.--header SomeHeader:SomeValue--header 'Some Header:Some Value' --header k2:v2--data <value>HTTP 使用 POST 方法时附带的 body 信息,建议使用单引号包起来。e.g.--data 'Hello world!'--json-path <value> 指定了对 HTTP 原始响应 body 进行 JSONPath 处理。JSONPath 语法说明:/articles/JsonPath/目前支持:$.[]*e.g.--json-path '$.obj' 取子对象--json-path '$[0]' 从数组取下标--json-path "$['obj']" 取子对象--json-path '$[0,1].obj' 取多个对象--body-plain-text 指定了返回正文内容格式,缺省 --body-plain-text。--resp-header <header>指定了从 HTTP 原始响应 header 全集中返回给查询方的子集。如果指定的 header 不在原始响应 header 全集中,则返回 value 为空字符串。可以指定多次 --resp-header 来指定返回多个 header。--header-plain-text指定了返回 HTTP 响应 header 的格式,缺省 --header-plain-text。具体格式为每个"header:value"占一行,使用 \r\n 换行。--header-to-json指定了返回 HTTP 响应 header 使用 JSON 格式组织,每个 header:value 为顶层 kv。--encrypted-envelope <value>加密信封字段,传递机密信息给预言机 TEE 实例。加密信封为以下 JSON 格式字符串的 BASE64 编码:{ "cipher_text": "", // 机密信息密文,使用 aes-256-gcm 加密"aes_iv":"", // 对称加密 iv"gcm_aad": "", // 对称加密 add"gcm_tag": "" // 对称加密 tag"encrypted_aes_key": "" // 经过 TEE 公钥加密后的对称加密 key"rsa_key": "", // TEE 实例的 RSA 公钥}其中 cipher_text 字段为机密信息,值为以下固定结构的 JSON 字符串:{"macro_replacement":{}, "content_hash":"", "nonce_str":"", "timestamp":"", "time_to_live":""}其中 macro_replacement 存放宏替换内容,可以在 URL path、body、header 中嵌入宏,然后将替换值写在macro_replacement 中,只对 TEE 可见。合法宏只能从 'ORACLE_SUB_MACRO_0' ~ 'ORACLE_SUB_MACRO_4' 选择,并且替换值中不能包括合法宏。content_hash 存放 CURL 命令明文部分内容计算的哈希值,锁定加密信封只能与锁定的明文一起使用。nonce_str、timestamp、time_to_live 暂未启用。机密信息使用 AES/GCM/NoPadding 加密,再用 TEE 的公钥使用(TEE 的公钥在跨链服务页面中查询)RSA/None/OAEPPadding 加密 AES 密钥。

4.5 预言机合约错误码

5. 参考

(1)外部数据源服务

/docs/2/108575

(2)预言机(oracle)2.0:用完即走,为智能合约可信地与外部世界交互提供必要条件(上)

/p/35007714

(3)什么是区块链预言机(BlockChain Oracle)

/p/52369816

截止.04.10,针对创新大赛的TEE硬件隐私合约链的外部预言机功能还未开放出来,但是标准合约链的外部预言机ORACLE功能已开放。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。