Consuming Data Feeds
When you connect a smart contract to real-world services or off-chain data, you create a hybrid smart contract. For example, you can use Chainlink Data Feeds to connect your smart contracts to asset pricing data like the ETH / USD feed. These data feeds use the data aggregated from many independent Chainlink node operators. Each price feed has an on-chain address and functions that enable contracts to read pricing data from that address.
The code for reading Data Feeds is the same across all EVM-compatible blockchains and Data Feed types. You choose different types of feeds for different uses, but the request and response format are the same.
Examine the sample contract
This example contract obtains the latest price answer from the BTC / USD feed on the Sepolia testnet, but you can modify it to read any of the different Types of Data Feeds.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED
* VALUES FOR CLARITY.
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
/**
* If you are reading data feeds on L2 networks, you must
* check the latest answer from the L2 Sequencer Uptime
* Feed to ensure that the data is accurate in the event
* of an L2 sequencer outage. See the
* https://docs.chain.link/data-feeds/l2-sequencer-feeds
* page for details.
*/
contract DataConsumerV3 {
AggregatorV3Interface internal dataFeed;
/**
* Network: Sepolia
* Aggregator: BTC/USD
* Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
*/
constructor() {
dataFeed = AggregatorV3Interface(
0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
);
}
/**
* Returns the latest answer.
*/
function getLatestData() public view returns (int) {
// prettier-ignore
(
/* uint80 roundID */,
int answer,
/*uint startedAt*/,
/*uint timeStamp*/,
/*uint80 answeredInRound*/
) = dataFeed.latestRoundData();
return answer;
}
}
The contract has the following components:
-
The
import
line imports an interface namedAggregatorV3Interface
. Interfaces define functions without their implementation, which leaves inheriting contracts to define the actual implementation themselves. In this case,AggregatorV3Interface
defines that all v3 Aggregators have the functionlatestRoundData
. You can see the complete code for theAggregatorV3Interface
on GitHub. -
The
constructor() {}
initializes an interface object namedpriceFeed
that usesAggregatorV3Interface
and connects specifically to a proxy aggregator contract that is already deployed at0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
. The interface allows your contract to run functions on that deployed aggregator contract. -
The
getLatestPrice()
function calls yourpriceFeed
object and runs thelatestRoundData()
function. When you deploy the contract, it initializes thepriceFeed
object to point to the aggregator at0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
, which is the proxy address for the Sepolia BTC / USD data feed. Your contract connects to that address and executes the function. The aggregator connects with several oracle nodes and aggregates the pricing data from those nodes. The response from the aggregator includes several variables, butgetLatestPrice()
returns only theprice
variable.
Compile, deploy, and run the contract
Deploy the DataConsumerV3
smart contract on the Sepolia testnet.
-
Open the example contract in Remix. Remix opens and shows the contents of the smart contract.
-
Because the code is already written, you can start the compile step. On the left side of Remix, click the Solidity Compiler tab to view the compiler settings.
-
Use the default compiler settings. Click the Compile DataConsumerV3.sol button to compile the contract. Remix automatically detects the correct compiler version depending on the
pragma
that you specify in the contract. You can ignore warnings about unused local variables in this example. -
On the Deploy tab, select the Injected Provider environment. This contract specifically requires Web3 because it connects with another contract on the blockchain. Running in a JavaScript VM will not work.
-
Because the example contract has several imports, Remix might select another contract to deploy by default. In the Contract section, select the
PriceConsumerV3
contract to make sure that Remix deploys the correct contract. -
Click Deploy to deploy the contract to the Sepolia testnet. MetaMask opens and asks you to confirm payment for deploying the contract. Make sure MetaMask is set to the Sepolia network before you accept the transaction. Because these transactions are on the blockchain, they are not reversible.
-
In the MetaMask prompt, click Confirm to approve the transaction and spend your testnet ETH required to deploy the contract.
-
After a few seconds, the transaction completes and your contract appears under the Deployed Contracts list in Remix. Click the contract dropdown to view its variables and functions.
-
Click getLatestPrice to show the latest price from the aggregator contract. The latest price appears just below the button. The returned price is an integer, so it is missing its decimal point.
You can run your own oracle networks that provide data to smart contracts similar to the AggregatorV3Interface
, but first, you should learn how to configure your contracts to pay oracles using LINK tokens. Follow the Generate Random Numbers to learn how.