Getting Started with Data Feeds
Chainlink Data Feeds are the fastest way to connect your smart contracts to real-world data such as asset prices, reserve balances, and L2 sequencer health. Each feed is aggregated by many independent Chainlink node operators and published onchain through a decentralized oracle network, giving your contracts a reliable, manipulation-resistant source of data.
Each price feed has an onchain address and functions that enable contracts to read pricing data from that address, for example the ETH / USD feed.
This guide walks you through reading a Data Feed end-to-end using the Remix IDE. You'll deploy a consumer contract on the Sepolia testnet and read the BTC / USD price feed onchain.
What you'll do
- Deploy a Solidity consumer contract that reads the BTC / USD price feed on Sepolia.
- Retrieve the latest price onchain by calling the consumer contract.
- Learn the key safety checks to apply before moving to production.
The code for reading Data Feeds on Ethereum and other EVM-compatible blockchains is the same for every chain and every feed type. You choose different feeds for different use cases, but the request and response format is always the same. The answer's decimal length and expected value range may differ depending on the feed.
Guide Versions
This guide is available in multiple versions. Choose the one that matches your needs.
Before you begin
If you are new to smart contract development, complete the Deploy Your First Smart Contract quickstart first. It walks you through installing and funding a MetaMask wallet and using Remix, which this guide assumes you already know.
You will need:
- A funded wallet on the Sepolia testnet (chain ID
11155111). Get testnet ETH from a Sepolia faucet. - The Remix IDE open in your browser. No local installation required.
- MetaMask configured for Sepolia.
Step 1: Examine the sample contract
The example contract below reads the latest answer from the BTC / USD feed on Sepolia. It targets Solidity ^0.8.7. You can modify it to read any of the Types of Data Feeds.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/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 getChainlinkDataFeedLatestAnswer() public view returns (int256) {
// prettier-ignore
(
/* uint80 roundId */
,
int256 answer,
/*uint256 startedAt*/
,
/*uint256 updatedAt*/
,
/*uint80 answeredInRound*/
) = dataFeed.latestRoundData();
return answer;
}
}
The contract has the following components:
- The
importline brings inAggregatorV3Interface— the Solidity interface that every Chainlink v3 price feed proxy implements. It exposeslatestRoundData(),getRoundData(),decimals(), andversion(). The sample useslatestRoundDatato fetch the current price. - The
constructor()initializes adataFeedobject that usesAggregatorV3Interfacepointing at the proxy aggregator deployed at0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43. This is the proxy address for the SepoliaBTC / USDfeed. The proxy lets the aggregator be upgraded without breaking consumer contracts. - The
getChainlinkDataFeedLatestAnswer()function calls yourdataFeedobject and runs thelatestRoundData()function and returns theanswervariable. When you deploy the contract, it initializes thedataFeedobject to point to the aggregator at0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43, which is the proxy address for the SepoliaBTC / USDdata 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, butgetChainlinkDataFeedLatestAnswer()returns only theanswervariable. The full response includesroundId,startedAt,updatedAt, andansweredInRound— see the API Reference for details.
Step 2: Compile the contract in Remix
-
Open the example contract in Remix. Remix loads the file and its imports automatically.
-
On the left sidebar, click the Solidity Compiler tab.
-
Keep the default compiler settings and click Compile DataConsumerV3.sol. Remix auto-detects the compiler version from the
pragmastatement. You can ignore warnings about unused local variables — the example destructureslatestRoundData()but only usesanswer.
Step 3: Deploy to Sepolia
-
Open MetaMask and switch to the Sepolia network. If you don't have it configured, you can find the chain ID and RPC details on the LINK Token Contracts page.
-
In Remix, open the Deploy & Run Transactions tab and set the Environment to Injected Provider - MetaMask. This contract must run in a Web3 context because it reads from another onchain contract. Running in the JavaScript VM will not work.
-
Because the example has several imports, Remix may default to a different contract. In the Contract dropdown, explicitly select
DataConsumerV3. -
Click Deploy. MetaMask opens and asks you to confirm the deployment transaction. Verify the network is Sepolia before confirming — onchain transactions are irreversible.
-
In the MetaMask prompt, click Confirm to approve the transaction and spend the testnet ETH required to deploy.
-
After a few seconds, the transaction completes and your contract appears under Deployed Contracts in Remix. Click the contract dropdown to expand its variables and functions.
Step 4: Read the latest price onchain
-
Click getChainlinkDataFeedLatestAnswer to call the function. The latest answer from the aggregator appears just below the button.
-
The returned answer is an integer with no decimal point. The BTC / USD feed uses 8 decimals, so an answer of
3030914000000represents a BTC / USD price of30309.14. Each feed uses a different number of decimals — you can find the exact value on the Price Feed Addresses page by enabling Show more details.
Step 5: Read the same feed offchain (addendum)
You can also read Data Feeds directly from the feed proxy without deploying a consumer contract. This is useful for backends, bots, dashboards, and pre-trade checks. No consumer contract is required — the feed proxy is a public contract and latestRoundData() is a view function, so anyone can call it directly from a script or CLI.
The lowest-friction offchain read is a single cast call (requires Foundry installed):
cast call 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 "latestRoundData()(uint80,int256,uint256,uint256,uint80)" --rpc-url $SEPOLIA_RPC_URL
Before you go to production
The example intentionally omits the safety checks a production integration needs. Before shipping, review the following points and the Developer Responsibilities page.
Check updatedAt and staleness
latestRoundData() returns updatedAt (the timestamp of the latest round) and answeredInRound (the round in which the answer was finalized). Always verify the feed is fresh:
(uint80 roundId, int256 answer, , uint256 updatedAt, uint80 answeredInRound) = dataFeed.latestRoundData();
require(answeredInRound >= roundId, "Stale price");
require(block.timestamp - updatedAt < TIMEOUT, "Stale price");
Choose a TIMEOUT that matches your application's risk tolerance — shorter for trading, longer for less time-sensitive use cases.
Use the right feed for your asset
Not all feeds are equal. Low-liquidity assets are more exposed to market manipulation. Review Selecting Quality Data Feeds and the Data Feed Categories before choosing a feed.
Handle L2 sequencer risk
On L2s, a sequencer outage can cause stale or incorrect prices. Always pair L2 price feeds with a check on the L2 Sequencer Uptime Feed. The DataConsumerWithSequencerCheck sample shows the pattern. Try it out in Remix below:
Audit your integration
The sample code is unaudited and hardcodes values for clarity. Before production, complete your own audit, review your dependencies, and apply the risk-mitigation practices described in Developer Responsibilities.
FAQ
Do I need a consumer contract to read a Data Feed?
Only if another smart contract needs the price onchain. A consumer contract exists to wrap a feed read in your own contract's logic so that your other contracts can use the price onchain — for collateral checks, settlements, circuit breakers, and so on. The read is atomic with your onchain action and verifiable on the blockchain.
If you only need the price in an offchain system (a backend, bot, dashboard, or pre-trade check), you do not need a consumer contract. The feed proxy is a public contract and latestRoundData() is a view function — anyone can call it directly from a script using cast, ethers.js, or viem. See Step 5: Read the same feed offchain on this page, or the Foundry and Hardhat offchain read sections.
| Consumer contract (onchain) | Direct read (offchain) | |
|---|---|---|
| Who needs the price? | Another smart contract | A script, backend, bot, or dashboard |
| Gas cost? | Pay to deploy + gas for onchain reads | Free (view calls from a script) |
| Deployment required? | Yes | No |
| Atomic with onchain action? | Yes | No |
Remix says "contract not found" when deploying
In the Contract dropdown on the Deploy & Run Transactions tab, explicitly select DataConsumerV3. When a file has multiple imports, Remix defaults to the first contract alphabetically, which may not be the one you want to deploy.
The MetaMask transaction reverted on deployment
Make sure MetaMask is set to the Sepolia network (chain ID 11155111) before confirming. If you're on another network, the deployment will revert or land on the wrong chain. Also confirm your wallet has enough testnet ETH to cover gas — check a Sepolia faucet if needed.