LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 行情分析 > 使用Chainlink预言机,十分钟开发一个DeFi项目(一)

使用Chainlink预言机,十分钟开发一个DeFi项目(一)

2020-06-22 Chainlink 来源:区块链网络

Chainlink 价格参考数据合约是可以在智能合约网络中值得依赖的真实价格数据的链上参考点。这些合约由多个 Chainlink 节点定时更新,提供高精度,高频率,可定制化的 DeFi 价格参考数据,可以方便的为 DeFi 项目的开发提供开箱即用的稳定基础设施。本文我们会教你如何使用这些合约。除此之外,Chainlink 还提供了通过获取链下数据的方式,从用户指定的 API 获取价格数据。我们下面就介绍一下这两种方式。

直接从 API 获取价格

首先我们先简单回顾一下,一般情况下我们如何使用 Chainlink 来获取真实世界中的价格数据。我们知道,价格是通过交易来产生的,所以最直接的方式是通过交易所提供的接口来获取某个交易所的某个加密货币的价格。但是这只是来自于一个交易所的数据,可能会有个体性的误差。有一些加密货币行情网站,他们会汇总多个交易所的数据,或者根据自己的指标来计算数据,得到一个偏离度比较小也就是更真实的数据。所以我们就采用从行情网站的接口获得数据,然后通过提交交易,将价格数据送到智能合约中。

我们选择的行情网站的cryptocompare,它提供了一些非常好用的API来提供各类交易市场上的信息。我们就以它文档上给出的一个 API 来作为例子:

https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD,JPY,EUR

访问这个接口,会返回一个 JSON 对象,提供当前时间,BTC 分别相对于美元、日元、欧元的价格。

{

"USD": 9460.99,

"JPY": 1018295.17,

"EUR": 8640.8

}

1 创建 truffle 项目

mkdir MyChainlinkedContract

cd MyChainlinkedContract

truffle init

如果您还没有安装 truffle suite, 可以通过npm install truffle -g来安装。

2 安装 Chainlink 开发库

npm install @chainlink/contracts --save

3 创建用户合约

您可以用您喜欢的编辑器工具,比如 VS Code, 打开项目目录。目录结构如下:

├── contracts

│ └── Migrations.sol

├── migrations

│ └── 1_initial_migration.js

├── test

└── truffle-config.js

我们在 contracts 目录中新建一个合约文件MyContract.sol,在文件中新建一个合约,继承自 ChainlinkClient 合约,并设置构造函数,参数分别是:

1. _link所使用网络环境下的 LINK token 地址

2. _oracle所使用的 Oracle 合约地址。如果您不知道选择什么哪个 Oracle,可以前往 Chainlink 市场 market.link 上选择。

3. _specId即 jobId,用于完成规范命令序列的任务 ID,同样可在 Chainlink 市场 market.link 上对应的 Oracle 下选择。

pragma solidity ^0.6.0;

import "@chainlink/contracts/src/v0.6/ChainlinkClient.sol";

// MyContract 通过继承 Chainlinked 合约获得了创建Chainlink请求的功能

contract MyContract is ChainlinkClient {

constructor(address _link, address _oracle, bytes32 _specId) public {

setChainlinkToken(_link);

setChainlinkOracle(_oracle);

specId = _specId;

}

bytes32 internal specId;

}

接下来我们就可以编写创建 Chainlink 请求的代码

function requestEthereumPrice(string memory _currency, uint256 _payment) public {

requestEthereumPriceByCallback(_currency, _payment, address(this));

}

function requestEthereumPriceByCallback(string memory _currency, uint256 _payment, address _callback) public {

Chainlink.Request memory req = buildChainlinkRequest(specId, _callback, this.fulfill.selector);

req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD,EUR,JPY");

string[] memory path = new string[](1);

path[0] = _currency;

req.addStringArray("path", path);

sendChainlinkRequest(req, _payment);

}

其中的主要语句就是通过buildChainlinkRequest创建了一个 Chainlink 请求,该请求会发起一次 LINK 的转账到 Oracle 地址,并附带请求数据。请求数据可以通过add的方法添加到请求中。请求数据可以包括:请求地址、解析路径、倍数等。

另外我们还需要定义一个回调函数来接收 Oracle 获取到的结果,这个函数需要作为参数在构建 Chainlink 请求时传入到函数buildChainlinkRequest中:

event RequestFulfilled(

bytes32 indexed requestId, // User-defined ID

bytes32 indexed price

);

function fulfill(bytes32 _requestId, bytes32 _price)

public

recordChainlinkFulfillment(_requestId)

{

emit RequestFulfilled(_requestId, _price);

currentPrice = _price;

}

这样其实一个最简单的 Chainlink 消费者合约就创建完成了,下面是一段完整的代码,当然你也可以在此之上添加一些其他函数,比如提取 LINK、取消请求等等。

pragma solidity ^0.6.0;

import "@chainlink/contracts/src/v0.6/ChainlinkClient.sol";

contract MyContract is ChainlinkClient {

constructor(address _link, address _oracle, bytes32 _specId) public {

setChainlinkToken(_link);

setChainlinkOracle(_oracle);

specId = _specId;

}

bytes32 internal specId;

bytes32 public currentPrice;

event RequestFulfilled(

bytes32 indexed requestId, // User-defined ID

bytes32 indexed price

);

function requestEthereumPrice(string memory _currency, uint256 _payment) public {

requestEthereumPriceByCallback(_currency, _payment, address(this));

}

function requestEthereumPriceByCallback(string memory _currency, uint256 _payment, address _callback) public {

Chainlink.Request memory req = buildChainlinkRequest(specId, _callback, this.fulfill.selector);

req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD,EUR,JPY");

string[] memory path = new string[](1);

path[0] = _currency;

req.addStringArray("path", path);

sendChainlinkRequest(req, _payment);

}

function fulfill(bytes32 _requestId, bytes32 _price)

public

recordChainlinkFulfillment(_requestId)

{

emit RequestFulfilled(_requestId, _price);

currentPrice = _price;

}

}

4 将用户合约部署到 Ropsten 测试网络上

我们配置好 truffle 的 config 文件中的 Ropsten network 字段和相关的 provider,添加一个 migration 文件,通过下面的命令,将我们的用户合约部署到 Ropsten 测试网络上。

truffle migrate --network ropsten

5 向合约地址转入 LINK

由于发起 Chainlink 请求需要向 Oracle 支付 LINK 作为费用,所以我们的用户合约需要拥有 LINK 才能成功获取数据。所以我们需要向刚刚部署好的 MyContract 合约转入一部分 LINK。每次请求的费用可以根据所选择的 Oracle 要求的费用来支付。

6 编写测试脚本

接下来我们就可以调用合约来获取我们想要的数据了。我们可以使用 truffle 给我们提供的控制台,也可以自己编写脚本文件来测试。脚本文件的编写也非常简单,我们写一个请求的文件和一个读取的文件

request.js

const MyContract = artifacts.require('MyContract')

module.exports = async callback => {

const mc = await MyContract.deployed()

const tx = await mc.requestEthereumPrice('USD', '1000000000000000000')

callback(tx.tx)

}

read.js

const MyContract = artifacts.require('MyContract')

module.exports = async callback => {

const mc = await MyContract.deployed()

const data = await mc.currentPrice.call()

callback(console.log(parseInt(data)))

}

通过以下命令来调用请求脚本:

npx truffle exec scripts/request.js --network ropsten

成功之后稍等一段时间,因为需要以太坊网络对交易的确认,然后再通过以下命令读取 Oracle 获取到的数据。

npx truffle exec scripts/read.js --network ropsten

顺利的话,控制台上会打出当前 BTC 的价格9352

这样,我们就以一个非常直接的方式,通过一个我们指定的 API,完成了一个在合约中获取 BTC 价格数据的用例。

(未完待续,下篇将讲一下Chainlink 价格参考数据合约应该怎么来使用)

Chainlink官方渠道

QQ群: 6135525

微博:https://weibo.com/chainlinkofficial

币乎:https://bihu.com/people/1869894547

合作联系:[email protected]

GitHub:https://github.com/smartcontractkit/chainlink

Discord: https://discord.gg/aSK4zew

Twitter:https://twitter.com/chainlinkofficial

Telegram:https://t.me/chainlinkofficial

—-

编译者/作者:Chainlink

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...