简体   繁体   English

有没有比通过节点单独调用多个 API 更简单的方法从 Chainlink 获取去中心化数据?

[英]Is there a simpler way to get decentralized data from Chainlink than doing separate multiple API calls through nodes?

I want to get price feed data of ETH in USD in my solidity project I'm testing in Remix.我想在我正在 Remix 中测试的 Solidity 项目中以美元获取 ETH 的价格馈送数据。 I'm using the Chainlink request data as a guide so that my data can be decentralized.我使用Chainlink请求数据作为指导,以便我的数据可以去中心化。

Right now, I make 3 chainlink requests to different nodes with different URLs and then calculate the median of the three responses to get a decentralized price.现在,我向具有不同 URL 的不同节点发出 3 个链链接请求,然后计算三个响应的中值以获得去中心化的价格。 It seems like this is a fairly tedious way to do this, is there a simpler way to get this?看起来这是一种相当乏味的方法,有没有更简单的方法来做到这一点?

 function requestEthereumPrice(address _address, bytes32 job_id, string url) 
    public
    onlyOwner
  {
    Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(JOB_ID), address(this), this.fulfill.selector);
    req.add("get", url);
    req.add("path", "USD");
    req.addInt("times", 100);
    sendChainlinkRequestTo(_address, req, ORACLE_PAYMENT);
  }

  function multipleData() public{
      requestEthereumPrice(ORACLE_ADDRESS, JOB_ID);
      requestEthereumPrice(ORACLE2_ADDRESS, JOB2_ID);
      requestEthereumPrice(ORACLE3_ADDRESS, JOB3_ID);
  }

 function fulfill(bytes32 _requestId, uint256 _price)
    public
    // Use recordChainlinkFulfillment to ensure only the requesting oracle can fulfill
    recordChainlinkFulfillment(_requestId)
  {
    currentPriceList[index] = _price;
    index = (index + 1) & 3
    currentPrice = median();
  }

Welcome to SO!欢迎来到 SO!

Your approach is the most "brute force" way to do this, which works.您的方法是执行此操作的最“蛮力”方法,它有效。 However there are currently two ways you can improve this.但是,目前有两种方法可以改善这一点。

1. Use the reference data contracts 1. 使用参考数据合约

A reference data contract is a contract that has multiple trusted decentralized Chainlink nodes sending price updates from different data providers to a point of reference on the blockchain for anyone to query.参考数据合约是一种合约,它具有多个受信任的去中心化 Chainlink 节点,将来自不同数据提供者的价格更新发送到区块链上的一个参考点,供任何人查询。 Your specific currency pair of ETH/USD is one of those pairs currently supported.您的特定货币对ETH/USD是当前支持的货币对之一。 The code to get that data looks like this:获取该数据的代码如下所示:

pragma solidity ^0.6.0;

import "github.com/smartcontractkit/chainlink/evm-contracts/src/v0.6/dev/AggregatorInterface.sol";

contract ReferenceConsumer {
  AggregatorInterface internal ref;

// Use 0xF79D6aFBb6dA890132F9D7c355e3015f15F3406F as the address of the ETH/USD pair
  constructor(address _aggregator) public {
    ref = AggregatorInterface(_aggregator);
  }

  function getLatestAnswer() public view returns (int256) {
    return ref.latestAnswer();
  }

  function getLatestTimestamp() public view returns (uint256) {
    return ref.latestTimestamp();
  }

You can find a list of currently supported feeds in there feeds documentation or the slightly nicer looking page of their feeds explorer .您可以在feeds 文档中找到当前支持的 feeds 列表,或者在他们的feeds explorer中看起来更好看的页面。

2. Use a precoordinator contract 2. 使用预协调器合约

Number 1 is great if you want a boxed solution, however, maybe you disagree with the node selection of Chainlink, and would like your own implementation (which increases decentralization.).如果你想要一个盒装的解决方案,第 1 个很好,但是,也许你不同意 Chainlink 的节点选择,并且想要你自己的实现(这增加了去中心化。)。 Your solution is one way to choose your own node network.您的解决方案是选择您自己的节点网络的一种方式。

A precoordinator contract allows you to make a normal buildChainlinkRequest as you do above, but fans it out to multiple nodes for you. precoordinator 合约允许您像上面那样进行正常的buildChainlinkRequest ,但会为您将其分散到多个节点。 To create this, first deploy a contract:要创建它,首先部署一个合约:

pragma solidity ^0.5.0;

import "github.com/smartcontractkit/chainlink/evm-contracts/src/v0.5/PreCoordinator.sol";

You can then call the createServiceAgreement from the contract, which takes the parameters uint256 _minResponses, address[] _oracles, address[]_jobIds, uint256[] _payments .然后,您可以从合约中调用createServiceAgreement ,该合约接受参数uint256 _minResponses, address[] _oracles, address[]_jobIds, uint256[] _payments You can use remix to deploy them.您可以使用 remix 来部署它们。 预协调员

Once you deploy a service agreement from your precoordinator contract, it will give you a service agreement ID.从预协调员合同部署服务协议后,它将为您提供服务协议 ID。 You can find this ID by checking the logs or looking at something like etherscan and going to topic 1 to see the ID.您可以通过检查日志或查看诸如 etherscan 之类的内容并转到topic 1以查看 ID 来找到此 ID。 Here is an example .这是一个例子

Once you have the address of the precoordinator and the service agreement, you can use the address of the precoordinator contract as the oracle address, and the service agreement at the jobId.有了precoordinator的地址和服务协议后,就可以使用precoordinator合约的地址为oracle地址,服务协议为jobId。 Meaning you can call a host of nodes with just:这意味着您可以调用大量节点:

function requestEthereumPrice(address precoordinator_address, bytes32 service_agreement, string url) 
    public
    onlyOwner
  {
    Chainlink.Request memory req = buildChainlinkRequest(service_agreement, address(this), this.fulfill.selector);
    req.add("get", url);
    req.add("path", "USD");
    req.addInt("times", 100);
    sendChainlinkRequestTo(precoordinator_address, req, ORACLE_PAYMENT);
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM