Skip to main content

BNB Smart Chain Price Feeds from Chainlink

Introduction to Price Feeds

Chainlink Price Feeds provide a way to connect your smart contracts to the real-world market prices of assets. They enable smart contracts to retrieve the latest price of an asset in a single call.

Often, smart contracts need to act upon prices of assets in real-time. This is especially true in DeFi. For example, Synthetix use Price Feeds to determine prices on their derivatives platform. Lending and Borrowing platforms like AAVE use Price Feeds to ensure the total value of the collateral.

Get the Latest Price

This section explains how to get the latest price of BNB inside smart contracts using Chainlink Price Feeds, on the BNB Smart Chain.

Solidity Contract

To consume price data, your smart contract should reference AggregatorV3Interface, which defines the external functions implemented by Price Feeds.

pragma solidity ^0.6.7;

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

contract PriceConsumerV3 {

AggregatorV3Interface internal priceFeed;

/**
* Network: BNB Smart Chain
* Aggregator: BNB/USD
* Address: 0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE
*/
constructor() public {
priceFeed = AggregatorV3Interface(0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE);
}

/**
* Returns the latest price
*/
function getLatestPrice() public view returns (int) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();
return price;
}
}

Javascript Web3

const Web3 = require("web3");
const web3 = new Web3("https://data-seed-prebsc-1-s1.bnbchain.org:8545");
const aggregatorV3InterfaceABI = [{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}];
const addr = "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE";
const priceFeed = new web3.eth.Contract(aggregatorV3InterfaceABI, addr);
priceFeed.methods.latestRoundData().call()
.then((roundData) => {
// Do something with roundData
console.log("Latest Round Data", roundData)
});

Python Web3

from web3 import Web3
web3 = Web3(Web3.HTTPProvider('https://data-seed-prebsc-1-s1.bnbchain.org:8545'))
abi = '[{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]'
addr = '0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE'
contract = web3.eth.contract(address=addr, abi=abi)
latestData = contract.functions.latestRoundData().call()
print(latestData)

Get Historical Price Data

The most common use case for Price Feeds is to get the latest price. However, AggregatorV3Interface also exposes functions which can be used to retrieve price data of a previous round ID.

Solidity Contract

pragma solidity ^0.6.7;

import "https://github.com/smartcontractkit/chainlink/blob/master/evm-contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";

contract HistoricalPriceConsumerV3 {

AggregatorV3Interface internal priceFeed;

/**
* Network: BNB Smart Chain
* Aggregator: BNB/USD
* Address: 0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE
*/
constructor() public {
priceFeed = AggregatorV3Interface(0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE);
}

/**
* Returns historical price for a round id.
* roundId is NOT incremental. Not all roundIds are valid.
* You must know a valid roundId before consuming historical data.
* @dev A timestamp with zero value means the round is not complete and should not be used.
*/
function getHistoricalPrice(uint80 roundId) public view returns (int256) {
(
uint80 id,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = priceFeed.getRoundData(roundId);
require(timeStamp > 0, "Round not complete");
return price;
}
}

Javascript Web3


const Web3 = require("web3");

const web3 = new Web3("https://data-seed-prebsc-1-s1.bnbchain.org:8545");
const aggregatorV3InterfaceABI = [{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}];
const addr = "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE";
const priceFeed = new web3.eth.Contract(aggregatorV3InterfaceABI, addr);

// Valid roundId must be known. They are NOT incremental.
let validId = BigInt("18446744073709554130");

priceFeed.methods.getRoundData(validId).call()
.then((historicalRoundData) => {
// Do something with price
console.log("Historical round data", historicalRoundData);
})

Python Web3

from web3 import Web3

web3 = Web3(Web3.HTTPProvider('https://data-seed-prebsc-1-s1.bnbchain.org:8545'))
abi = '[{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]'
addr = '0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE'
contract = web3.eth.contract(address=addr, abi=abi)

# Valid roundId must be known. They are NOT incremental.
validRoundId = 18446744073709554130

historicalData = contract.functions.getRoundData(validRoundId).call()
print(historicalData)

API Reference

API reference for AggregatorV3Interface.

Functions

NameDescription
decimalsThe number of decimals in the response.
descriptionThe description of the aggregator that the proxy points to.
getRoundDataGet data from a specific round.
latestRoundDataGet data from the latest round.
versionThe version representing the type of aggregator the proxy points to.

decimals

Get the number of decimals present in the response value.

function decimals() external view returns (uint8)
  • RETURN: The number of decimals.

description

Get the description of the underlying aggregator that the proxy points to.

function description() external view returns (string memory)
  • RETURN: The description of the underlying aggregator.

getRoundData

Get data about a specific round, using the roundId.

function getRoundData(uint80 _roundId) external view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)

Parameters

  • roundId: The round ID

Return Values

  • roundId: The round ID.
  • answer: The price.
  • startedAt: Timestamp of when the round started.
  • updatedAt: Timestamp of when the round was updated.
  • answeredInRound: The round ID of the round in which the answer
    • was computed.

latestRoundData

Get the price from the latest round.

function latestRoundData() external view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)

Return Values

  • roundId: The round ID.
  • answer: The price.
  • startedAt: Timestamp of when the round started.
  • updatedAt: Timestamp of when the round was updated.
  • answeredInRound: The round ID of the round in which the answer
    • was computed.

version

The version representing the type of aggregator the proxy points to.

function version() external view returns (uint256)
  • RETURN: The version number.

Contract Addresses

Chainlink price feed contracts are updated on a regular basis by multiple Chainlink nodes. This section lists the contract addresses for Price Feeds on the BNB Smart Chain.

Mainnet

PairProxy
BNB / USD0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE
BTC / USD0x264990fbd0A4796A3E3d8E37C4d5F87a3aCa5Ebf
ETH / USD0x9ef1B8c0E4F7dc8bF5719Ea496883DC6401d5b2e

Original source is from Chainlink website