NEW

Join us at SmartCon 2023—where Web3 gets real. Get your ticket.

Using Data Feeds on EVM Chains

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 named AggregatorV3Interface. 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 function latestRoundData. You can see the complete code for the AggregatorV3Interface on GitHub.

  • The constructor() {} initializes an interface object named dataFeed that uses AggregatorV3Interface and connects specifically to a proxy aggregator contract that is already deployed at 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43. The interface allows your contract to run functions on that deployed aggregator contract.

  • The getLatestData() function calls your dataFeed object and runs the latestRoundData() function. When you deploy the contract, it initializes the dataFeed object to point to the aggregator at 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43, 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, but getLatestData() returns only the answer variable.

Compile, deploy, and run the contract

Deploy the DataConsumerV3 smart contract on the Sepolia testnet.

  1. Open the example contract in Remix. Remix opens and shows the contents of the smart contract.

  2. 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.

    Screenshot showing the Compiler tab and its settings.

  3. 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.

    Screenshot of the Compile button.

  4. 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.

    Screenshot showing the Injected Provider environment selected.

  5. Because the example contract has several imports, Remix might select another contract to deploy by default. In the Contract section, select the DataConsumerV3 contract to make sure that Remix deploys the correct contract.

    Screenshot showing DataConsumerV3 as the contract to deploy.

  6. 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.

    Screenshot of the Deploy button for DataConsumerV3.

  7. In the MetaMask prompt, click Confirm to approve the transaction and spend your testnet ETH required to deploy the contract.

    Screenshot showing Metamask asking you to confirm the transaction.

  8. 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.

    Remix Deployed Contracts Section

  9. Click getLatestData to show the latest answer from the aggregator contract. In this example, the answer is the latest price, which appears just below the button. The returned answer is an integer, so it is missing its decimal point. You can find the correct number of decimal places for this answer on the Price Feed addresses page by clicking the Show more details checkbox. The answer on the BTC / USD feed uses 8 decimal places, so an answer of 3030914000000 indicates a BTC / USD price of 30309.14. Each feed uses a different number of decimal places for answers.

    A screenshot showing the deployed contract and the latest answer.

What's next

Stay updated on the latest Chainlink news