EOS [EOS DAPP 开发进阶] 01 - 使用 Oracle (预言机) 为 DAPP 引入链外数据

pendingauth · 2019年09月06日 · 19 次阅读

本文转载自币乎,作者松果,原文链接: https://bihu.com/article/1016917169

这个系列是【从零开始DAPP开发】的续集,不定期更新一些DAPP开发中的进阶功能。

如何在智能合约中获取链外数据?

在浏览巴比特的文章时,会发现每篇文章下方都有显示发文时比特币的价格:

如果微文DAPP也想实现这样的功能:记录发文时EOS的价格,该怎么做呢?

对于传统的Web应用,这是一个非常简单的功能,调用交易所提供的API即可;

但对于智能合约却很困难,因为区块链和现有的互联网是隔离开的,无法从区块链中直接获取互联网上的信息。

也许你会想到,给智能合约增加一个表示EOS价格的参数,调用合约Action时,把价格传给智能合约;

但这样从客户端传递信息,无法保证数据是真实可信的,因为智能合约还可以通过命令行调用;

如何在智能合约中获取真实可信的链外数据,就是Oracle(预言机)要实现的功能。

Oracle - 连接区块链和现实世界的桥梁

Oracle,中文翻译成“预言机”,但它并不能预测什么,它的作用是连接区块链和现实世界,为区块链提供可信的链外数据;

Oracle本身也是一种智能合约,它允许区块链连接到任何现有的API来获取互联网上的数据。

可以看出,Oracle和“预言”并没有什么关系,它是一种区块链外信息写入区块链内的机制,为什么会被翻译成“预言机”(Oracle Mechanism)呢?

Oracle这个词最初来源于古希腊宗教,意为“神谕、先知、预言”,区块链中原本取的这个词的含义是“神谕”,即人们向神祇询问问题得到的解答;

神祇的回答是绝对可信的,因此区块链中Oracle原本的含义是可信,而中文翻译时直接取了“预言”这个含义。

EOS智能合约接入Oracle服务

Provable(以前叫oraclize)是一个Oracle服务提供商,同时支持以太坊和EOS,官方文档介绍了如何在EOS智能合约集成Oracle服务:https://docs.oraclize.it/#eos

Provable提供的oraclize服务本身也是由智能合约现实,合约名为:provableconn,支持EOS主网Jungle测试网,下面介绍EOS智能合约接入oraclize服务的方法。

首先,从oraclize的Github克隆eos-api.hpp头文件到本地:

git clone https://github.com/oraclize/eos-api.git

把克隆下来的eos-api.hpp文件放到智能合约目录中,文件结构如下:

oracles55555.cpp中编写如下合约代码,使用#include引入eos_api.hpp,关键函数是oraclize_query,用来查询链外数据:

#include <eosio/eosio.hpp>
#include <eosio/print.hpp>

#include "eos_api.hpp"

using namespace eosio;

CONTRACT oracles55555 : public eosio::contract
{
  public:
    using contract::contract;

    ACTION getprice()
    {
        oraclize_query("URL", "json(https://api.binance.com/api/v3/ticker/price?symbol=EOSUSDT).price");
        print("Oraclize query was sent, standing by for the answer...");
    }

    ACTION callback(checksum256 queryId, std::vector<unsigned char> result, std::vector<unsigned char> proof)
    {
        require_auth(provable_cbAddress());

        std::string result_str = vector_to_string(result);
        print("EOSUSD:", result_str);
    }
};

Jungle测试网创建oracles55555账号:

编译合约:

cd oracles55555
eosio-cpp -I . -o oracles55555.wasm oracles55555.cpp --abigen

会报出警告:

需要到eosio_api.hpp中指定宏ORACLIZE_NETWORK_NAME和CONTRACT_NAME的值,分别表示合约部署的EOS网络和合约名:

这里指定网络为"eosio_testnet_jungle",合约名为"oracles55555",再次编译成功。

部署合约到Jungle测试网:

cd ..
cleos -u http://jungle2.cryptolions.io set contract oracles55555 oracles55555 -p oracles55555

因为要调用内联Action,还需要给oracles55555添加eosio.code权限:

cleos -u http://jungle2.cryptolions.io set account permission oracles55555 active --add-code

测试:

cleos -u http://jungle2.cryptolions.io push action oracles55555 getprice '[]' -p songguo12345

调用oracles55555::getprice Action,会调用eos_api的oraclize_query函数发起请求,从binance的API获取EOS价格数据;

拿到数据后会内联调用oracles55555::callback Action,获取到请求结果。

区块浏览器中可以查看调用结果:

result是字节流数据,callback中使用eos_api的vector_to_string函数把字节流转成字符串,就能获取到真正的结果。

小结

这篇文章介绍了如何引入Provable(oraclize)预言机到EOS智能合约,下一步会把它整合进微文DAPP

Provable(oraclize)目前可以在EOS主网和Jungle测试网免费使用,未来在EOS主网使用会以EOS形式对每条请求收取费用。

更多内容

EOS开发系列目录

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册