Skip to content

Band Protocol预言机

Band Protocol Moonbeam Diagram

概览

开发者可通过两种方法从Band预言机获取价格。第一,可以通过Moonbeam上的Band智能合约在固定时间段或价格滑点大于目标值(不同代币的目标值不同)时获取链上最新数据。第二,使用JavaScript辅助库,该库绕过区块链直接从Band Protocol API(与智能合约相似的函数)中获取数据。如果DApp前端需要直接获取数据,则可以使用这种方法。

聚合合约地址可以在以下列表找到:

网络 聚合合约地址
Moonbase Alpha 0xDA7a001b254CD22e46d3eAB04d937489c93174C3

支持的代币

只要是平台支持的基础货币和报价货币(报价对显示方式:基础货币代码/报价货币代码),您都可以获取其报价。例如:

  • BTC/USD
  • BTC/ETH
  • ETH/EUR

您可通过此链接查看平台已支持的代币种类。撰写本文时,已有超过146对货币对可查询。

获取报价

如上所述,开发者可以通过两种方法从Band预言机获取报价:

  • Moonbeam上的Band智能合约(目前已部署在Moonbase Alpha测试网上)
  • Javascript辅助库

通过智能合约获取数据

Moonbeam上的Band Protocol智能合约可通过实现StdReference合约接口从而查询链上数据(例如代币价格),该接口公开了getReferenceDatagetReferenceDataBulk函数。

第一个函数getReferenceData输入两串字符(基础货币和报价货币的代码),通过向StdReference合约发送请求来获取这两种货币之间的最新汇率,并以ReferenceData结构返回。

ReferenceData结构由以下元素组成:

  • 汇率:基础货币/报价货币汇率,返回值是真实汇率的 1018
  • 基础货币价格最后更新时间(UNIX时间戳)
  • 报价货币价格最后更新时间(UNIX时间戳)
struct ReferenceData {
   uint256 rate; 
   uint256 lastUpdatedBase; 
   uint256 lastUpdatedQuote;
}

第二个函数getReferenceDataBulk输入数据阵列信息。例如,基础货币输入['BTC','BTC','ETH'],报价货币输入['USD','ETH','EUR']ReferenceData函数就会返回包含以下货币对的数据阵列:

  • BTC/USD
  • BTC/ETH
  • ETH/EUR

合约示例

以下智能合约代码以简单的示例展示了StdReference合约和getReferenceData函数。合约仅为举例,不作实际之用。IStdReference.sol接口明确了ReferenceData结构和可用于获取报价的函数。

pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;

interface IStdReference {
    /// A structure returned whenever someone requests for standard reference data.
    struct ReferenceData {
        uint256 rate; // base/quote exchange rate, multiplied by 1e18.
        uint256 lastUpdatedBase; // UNIX epoch of the last time when base price gets updated.
        uint256 lastUpdatedQuote; // UNIX epoch of the last time when quote price gets updated.
    }

    /// Returns the price data for the given base/quote pair. Revert if not available.
    function getReferenceData(string memory _base, string memory _quote)
        external
        view
        returns (ReferenceData memory);

    /// Similar to getReferenceData, but with multiple base/quote pairs at once.
    function getReferenceDataBulk(string[] memory _bases, string[] memory _quotes)
        external
        view
        returns (ReferenceData[] memory);
}
接下来可以使用DemoOracle脚本。该脚本含有4个函数:

  • getPrice:请求单一基础货币报价的_视图_函数。在此示例中,BTCUSD为报价单位
  • getMultiPrices:请求多个基础货币报价的_视图_函数。在此示例中,BTCETH均以USD为报价单位
  • savePrice:请求_基础货币/报价货币_对数据的_公有_函数。不同元素作为字符串输入,如 _base = "BTC", _quotes = "USD"。函数将发送交易并修改储存在合约中的price变量
  • saveMultiPrices:一个请求多个_基础货币/报价货币_对数据的_公有_函数。不同元素作为字符串阵列输入,如_bases = ["BTC","ETH"], _quotes = ["USD","USD"]。函数将发送交易并修改储存在合约中的prices阵列,阵列将按照输入顺序显示每个报价对的价格。

部署时,构造函数需要聚合合约地址以连接到目标网络。

pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;

import "./IStdReference.sol";

contract DemoOracle {
    IStdReference ref;

    uint256 public price;
    uint256[] public pricesArr;

    constructor(IStdReference _ref) public {
        ref = _ref; // Aggregator Contract Address
                    // Moonbase Alpha 0xDA7a001b254CD22e46d3eAB04d937489c93174C3

    }

    function getPrice(string memory _base, string memory _quote) external view returns (uint256){
        IStdReference.ReferenceData memory data = ref.getReferenceData(_base,_quote);
        return data.rate;
    }

    function getMultiPrices(string[] memory _bases, string[] memory _quotes) external view returns (uint256[] memory){
        IStdReference.ReferenceData[] memory data = ref.getReferenceDataBulk(_bases,_quotes);

        uint256 len = _bases.length;
        uint256[] memory prices = new uint256[](len);
        for (uint256 i = 0; i < len; i++) {
            prices[i] = data[i].rate;
        }

        return prices;
    }

    function savePrice(string memory _base, string memory _quote) external {
        IStdReference.ReferenceData memory data = ref.getReferenceData(_base,_quote);
        price = data.rate;
    }

    function saveMultiPrices(
        string[] memory _bases,
        string[] memory _quotes
    ) public {
        require(_bases.length == _quotes.length, "BAD_INPUT_LENGTH");
        uint256 len = _bases.length;
        IStdReference.ReferenceData[] memory data = ref.getReferenceDataBulk(_bases,_quotes);
        delete pricesArr;
        for (uint256 i = 0; i < len; i++) {
            pricesArr.push(data[i].rate);
        }

    }
}

在Moonbase Alpha上进行测试

我们已经在Moonbase Alpha测试网部署了一个合约(地址为0xf15c870344c1c02f5939a5C4926b7cDb90dEc655),方便开发者查看Band Protocol预言机的喂价信息。为此,您需要部署以下接口合约:

pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;

interface TestInterface {
    function getPrice(string memory _base, string memory _quote) external view returns (uint256);

    function getMultiPrices(string[] memory _bases, string[] memory _quotes) external view returns (uint256[] memory);
}

通过这一合约将创建两个视图函数,以下示例与上述示例非常相似:

  • getPrice: 根据函数中对应输入的数据,提供单一基础货币/报价货币对喂价,即BTC/USD
  • getMultiPrices: 根据函数中对应输入的数据,提供多种基础货币/报价货币对喂价,即BTC/USD、ETH/USD、ETH/EUR

例如,使用Remix接口可以方便地获取BTC/USD价格对。

创建文档及编译合约后,点击“Deploy and Run Transactions”标签,输入合约地址(0xf15c870344c1c02f5939a5C4926b7cDb90dEc655)并点击“At Address”。请确保已将“Environment”设置为“Injected Web3”,只有在该设置下才能与Moonbase Alpha连接。

Band Protocol Remix deploy

通过这一方法,你将创建一个可以进行交互的合约实例。使用getPrice()getMultiPrices()函数即可请求相应报价对的数据。

Band Protocol Remix check price

BandChain.js Javascript辅助库

辅助库也支持相似的getReferenceData函数。使用此方法,首先要根据以下指令安装辅助库:

npm install @bandprotocol/bandchain.js

该辅助库提供了需要一个可以指向终端的构造函数。这将返回一个实例,支持所有必要的方法,如 getReferenceData函数。在获取信息时,向函数输入数据阵列,阵列中每个元素就是需要报价的基础货币/报价货币对。例如:

getReferenceData(['BTC/USD', 'BTC/ETH', 'ETH/EUR'])

然后,函数将返回以下结构的数据阵列:

[
  {
    pair: 'BTC/USD',
    rate: rate,
    updated: { base: lastUpdatedBase, quote: lastUpdatedQuote}
  },
  {
    pair: 'BTC/ETH',
    rate: rate,
    updated: { base: lastUpdatedBase, quote: lastUpdatedQuote}
  },
  {
    pair: 'ETH/EUR',
    rate: rate,
    updated: { base: lastUpdatedBase, quote: lastUpdatedQuote}
  }
]
lastUpdatedBaselastUpdatedQuote显示的是基础货币和报价货币各自价格的最后更新时间(UNIX时间戳)。

应用示例

下面这个Javascript脚本是getReferenceData函数的一个简单示例。

const BandChain = require('@bandprotocol/bandchain.js');

const queryData = async () => {
  const endpoint = 'https://poa-api.bandchain.org';

  const bandchain = new BandChain(endpoint);
  const dataQuery = await bandchain.getReferenceData(['BTC/USD', 'BTC/ETH', 'ETH/EUR']);
  console.log(dataQuery);
};

queryData();

这段代码可以通过节点来执行,其dataQuery输出值应该如下所示:

Band Protocol JavaScript Library

请注意,与通过智能合约获取报价相比,通过这种方法获得的返回结果将直接在正确的单位中显示。

本网站的所有信息由第三方提供,仅供参考之用。Moonbeam Foundation不保证网站信息的准确性、完整性或真实性。如使用或依赖本网站信息,需自行承担相关风险,Moonbeam Foundation不承担任何责任和义务。这些材料的所有陈述和/或意见由提供方个人或实体负责,与Moonbeam Foundation立场无关,概不构成任何投资建议。对于任何特定事项或情况,应寻求专业权威人士的建议。此处的信息可能会包含或链接至第三方提供的信息与/或第三方服务(包括任何第三方网站等)。这类链接网站不受Moonbeam Foundation控制。Moonbeam Foundation对此类链接网站的内容(包括此类链接网站上包含的任何信息或资料)概不负责也不认可。这些链接内容仅为方便访客而提供,Moonbeam Foundation对因您使用此信息或任何第三方网站或服务提供的信息而产生的所有责任概不负责。