通过预言机获取任意链下数据 - Chainlink Any API 代码解析

智能合约对链下数据的兼容会大大增加开发复杂度,Chainlink 通过 AnyAPI 使开发者的智能合约可以通过去中心化预言机网络(Decentralized Oracle Network:DON)获取外部数据。这样在使用 Chainlink AnyAPI 的时候,开发人员可以投入最少的开发资源,获得最大的自由度,因此可以更加专注在智能合约的功能性上,而非怎么样去获取数据上。

虽然 Chainlink Data Feed 可以给链上智能合约提供由 DON 聚合以后的通证价格,但是在很多场景下,尤其是非 DeFi 应用中,dApp 除了价格以外还需要多种多样的数据来实现自己的业务逻辑。比如在保险领域,智能合约需要天气数据来计算参保方的赔付金额,在合成资产协议中,外部股票市场的数据是必不可少的,除此以外,随着 web3 的场景越来越丰富,会越来越多地依赖于链下数据,比如说链下的交通运输,房地产,身份信息等等多种多样的数据。

如果你的智能合约需要依赖于这些数据,Chainlink AnyAPI 都可以作为一个工具让你从指定的外部数据源获取到特定数据。接下来,就让我们看看 Chainlink AnyAPI 的工作原理是什么。

使用 Chainlink AnyAPI 服务

发送 Chainlink 请求

在从 Chainlink 预言机节点获得数据之前,我们首先需要创建一个用户合约,然后在用户合约中给 Chainlink 预言机节点发送一个请求。下面的代码将展示如何通过用户合约给预言机节点发送请求:

function requestVolumeData() public returns (bytes32 requestId) {
 Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
 req.add('get', 'https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD');
 req.add('path', 'RAW,ETH,USD,VOLUME24HOUR');
 int256 timesAmount = 10**18;
 req.addInt('times', timesAmount);
 return sendChainlinkRequest(req, fee);
}

Chainlink AnyAPI 获取的数据的方式一般是通过预言机节点给外部数据源发送 RESTful 请求,所以节点在发送请求之前需要知道要请求的数据的 API 和参数。为了给 Any API 提供必要的数据,在智能合约的 ChainlinkRequest 中,我们需要通过函数 buildChainlinkRequest 加入这些相关信息。buildChainlinkRequest 这个函数定义在 ChainlinkClient.sol,代码展示如下:

function buildChainlinkRequest(
 bytes32 specId,
 address callbackAddr,
 bytes4 callbackFunctionSignature)
internal
pure
returns (Chainlink.Request memory)
{
    Chainlink.Request memory req;
    return req.initialize(specId, callbackAddr, callbackFunctionSignature);
}

buildChainlinkRequest 函数中,所有与请求相关的信息都会加入到 Request 这个结构体中,并且调用函数 initialize 来完成初始化。

Struct Request is defined in Chainlink.sol as below:
struct Request {
 bytes32 id;
 address callbackAddress;
 bytes4 callbackFunctionId;
 uint256 nonce;
 Buffe

你可能感兴趣的:(智能合约,预言机,Chainlink,区块链,智能合约,以太坊,web3)