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, so no single node can manipulate the price your contract reads.

Each price feed has an onchain address and functions that enable contracts to read pricing data from that address.

In this guide you will fetch the pricing data from a price feed, for example the BTC / USD feed.

Guide Versions

This guide is available in multiple versions. Choose the one that matches your needs.

What you'll do

  • Retrieve latest pricing data from the BTC / USD price feed offchain directly from the feed proxy. (Offchain methods are useful for backends, bots, dashboards, and pre-trade checks)
  • Deploy and retrieve the latest price onchain using a Solidity consumer contract that reads the BTC / USD price feed on Sepolia. (Onchain methods are useful for when you need to apply smart contract logic in your application based on the pricing data.)
  • Learn the key safety checks to apply before moving to production.

Note: 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.

Before you begin

If you are new to smart contract development, complete the Deploy Your First Smart Contract quickstart first.

You will need:

  • Foundry installed (forge, cast).
  • A funded wallet with its private key on the Sepolia testnet that will be used as your deployer. Get testnet ETH from a Sepolia faucet.
  • A Sepolia RPC URL (e.g. from a node provider).

Getting the feed address

The Price Feed Addresses page lists all the feeds available on each network. This guide uses the BTC / USD feed on Sepolia, with the proxy address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43

Retrieving the price data from the feed

1 Fetching price data offchain

You can read Data Feeds directly from the feed proxy without deploying any consumer contract. This is useful for backends, bots, dashboards, and pre-trade checks.

With Foundry, read the latest answer with a single cast call against the feed proxy at 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43:

cast call 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 "latestRoundData()(uint80,int256,uint256,uint256,uint80)" --rpc-url $SEPOLIA_RPC_URL

Read the decimals so you can scale the answer:

cast call 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 "decimals()(uint8)" --rpc-url $SEPOLIA_RPC_URL

The BTC / USD feed returns 8 for decimals. To convert the raw integer answer into a human-readable price, pass it together with the decimals to cast format-units:

cast format-units 3030914000000 8

This prints 30309.14000000 which is the human-readable price in USD.

2 Fetching price data onchain using a consumer contract
2.1 Examine the sample contract

The example contract below reads the latest answer from the BTC / USD feed on Sepolia. You can modify it to read any of the Types of Data Feeds.

src/DataFeeds/DataConsumerV3.sol
// 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 import line brings in AggregatorV3Interface
    • It exposes latestRoundData(), getRoundData(), decimals(), and version(). The sample uses latestRoundData to fetch the current price.
  • The constructor()
    • Initializes a dataFeed object that uses AggregatorV3Interface pointing at the proxy aggregator deployed at 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43.
    • This is the proxy address for the Sepolia BTC / USD feed. The proxy lets the aggregator be upgraded without breaking consumer contracts.
  • The getChainlinkDataFeedLatestAnswer() function
    • Calls latestRoundData() on the dataFeed object and returns the answer variable.
    • The full response from latestRoundData() includes roundId, startedAt, updatedAt, and answeredInRound. See the API Reference for details.
2.2 Set up a Foundry project
  1. Create a new Foundry project and add the Chainlink contracts dependency:

    forge init data-feeds-quickstart
    cd data-feeds-quickstart
    forge install smartcontractkit/chainlink-evm@contracts-v1.5.0
    
  2. Add this remapping to remappings.txt so Solidity can resolve @chainlink/contracts:

    @chainlink/contracts/=lib/chainlink-evm/contracts/
    

    You can write the file with a single command:

    echo '@chainlink/contracts/=lib/chainlink-evm/contracts/' > remappings.txt
    

    The contract imports the @chainlink/contracts package, but forge install places the package at lib/chainlink-evm/contracts/. A remapping tells the Solidity compiler to rewrite the import path to where the files actually lives. Without it, forge build fails with an Unable to resolve imports error.

  3. Create the directory for the sample consumer contract:

    mkdir -p src/DataFeeds
    
  4. Create src/DataFeeds/DataConsumerV3.sol and paste in the contract from Step 2.1: Examine the sample contract.

    Make sure the filename matches exactly: Foundry looks for the contract in src/.

  5. Verify the project compiles:

    forge build
    

    You should see Compiler run successful. If you see an import error, double-check the remappings.txt line from step 2.

  6. Import your deployer private key into Foundry's encrypted keystore. Replace my-account with a name of your choice and 0xYOUR_PRIVATE_KEY with your deployer key:

    cast wallet import my-account --private-key 0xYOUR_PRIVATE_KEY
    
    • cast prompts for a password to encrypt the key. The encrypted keystore file is saved to ~/.foundry/keystores/my-account, and the key is never written to disk in plaintext.
    • Run cast wallet list to confirm the account is stored.
2.3 Deploy the contract with forge create

Deploy DataConsumerV3 to Sepolia with forge create. Replace $SEPOLIA_RPC_URL with your own value and my-account with the keystore account name from the previous step:

forge create src/DataFeeds/DataConsumerV3.sol:DataConsumerV3 \
  --rpc-url $SEPOLIA_RPC_URL \
  --account my-account \
  --broadcast

forge prompts for the keystore password, then simulates the deployment and prints the transaction it would send. The --broadcast flag signs and submits that transaction. On success, the output looks like this:

Deployed to: 0xCONSUMER_ADDRESS

Save the deployed contract address for the next step.

2.4 Read the latest price onchain

Use cast call to read the latest answer through your deployed consumer. Replace $CONSUMER_ADDRESS with the address from the previous step:

cast call $CONSUMER_ADDRESS "getChainlinkDataFeedLatestAnswer()(int256)" --rpc-url $SEPOLIA_RPC_URL

Read the feed's decimals directly to scale the answer yourself:

cast call 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 "decimals()(uint8)" --rpc-url $SEPOLIA_RPC_URL

The BTC / USD feed returns 8 for decimals. Convert the raw answer to a human-readable price with cast format-units <answer> <decimals>.

cast format-units 3030914000000 8

This prints 30309.14000000 which is the human-readable price in USD.

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.

Consider Data Streams for latency-sensitive applications

Data Feeds push updates onchain at set intervals or when price thresholds are met. If your application needs market data faster than those update cadences, such as a perps DEX or real-time liquidation engine, Chainlink Data Streams delivers low-latency market data offchain that you verify onchain only when your application needs it. See Front Running Risk for how latency requirements factor into choosing a data source.

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: 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 or ethers.js. See Step 1: Fetching price data offchain on this page, or the Hardhat guide.

Consumer contract (onchain)Direct read (offchain)
Who needs the price?Another smart contractA script, backend, bot, or dashboard
Gas cost?Pay to deploy + gas for onchain readsFree (view calls from a script)
Deployment required?YesNo
Atomic with onchain action?YesNo

What's next

Get the latest Chainlink content straight to your inbox.