travis.media

How To Retrieve The Latest Crypto Prices From A Smart Contract

Using Chainlink Data Feeds, you can retrieve the latest price of a crypto asset from your smart contract in real-time. In this post, I'll show you step-by-step how to retrieve price data in Solidity using the Remix IDE.

Why Can't We Call Off-Chain APIs?

What’s the problem with calling APIs from a smart contract?

Well, the whole point of the blockchain is immutability and consistency. All nodes in the network should be able to replay transactions with the same results.

APIs introduce the possibility of variable data which is the enemy to the blockchain. When I make a query for a price, it will differ 30 minutes from now and will return different results day to day.

Well, Chainlink has introduced the concept of oracles to solve this problem, and they do so by posting data on the blockchain itself. They do the API calls for you periodically, and post the results on the blockchain for you, and others, to reference without any difference. Essentially, it’s an on-chain API.

The decentralized oracle handles the security of these calls as well, which is obviously a concern when calling out from an immutable smart contract.

And one, of many, popular use cases for using oracles is to retrieve up-to-date crypto price feeds from your smart contracts.

That’s what we will tackle today.

You can read more about Chainlink oracles here.

How To Get The Latest Prices From Your Smart Contract

Thankfully, documentation for getting the latest price from a Chainlink Data Feed is well written.

Well…. until you try it out in your Remix IDE and it gives you the following error:

“The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information."

Ugh. I wrestled with this one for about an hour.

The (now obvious) problem is that you cannot use Remix’s JavaScript VM Environment to virtually deploy your contract and then expect it to reach out to Chainlink’s provided Price Feed’s addresses on particular chains. You can only call this from a mainnet or a testnet of some sort, where the prices are posted regularly.

Thus, you need to use the Injected Web3 Environment with Metamask.

Here are the steps:

1. Add a Testnet to your MetaMask wallet.

This can be ETH (Kovan or Rinkeby), Binance Smart Chain (Testnet), etc.

Google how to add the one you need, it’s all over the web.

I’ll be using the Binance Smart Chain Testnet for my example today. If you open Metamask, click on the Networks and choose ‘Add Network.’ Then add this Testnet with the following values:

Now switch to that network.

Also, add grab some test BNB from this faucet.

2. Find the Data Feed Address For Your Chain and Crypto Pair

Let’s say I want the ETH/USD price on the Kovan Testnet. I would look at the Ethereum addresses here and find the address of the price pair that I want.

Let’s say I want the BNB/USD price on the Binance Smart Chain Testnet. I would look at the BNB chain addresses here and find my address. We’ll be using (at the time of this writing), 0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526 which is the BNB / USD pair.

3. Add the code to your Solidity smart contract

Then, integrate the following code into your smart contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

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

contract PriceConsumerV3 {

    AggregatorV3Interface internal priceFeed;

    /**
     * Network: BSC Testnet
     * Aggregator: BNB/USD
     * Address: 0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526
     */
    constructor() {
        priceFeed = AggregatorV3Interface(0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526);
    }

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

Remember, you can deploy your ETH contract on the Binance Smart Chain.

4. Deploy To Metamask and Test

Now choose Injected Web3 as your Environment in Metamask and deploy your contract to the BSC Testnet.

Now choose the getLatestPrice() function and voila!!

42727000000

Uh, wait… what is this long number??

Well, remember that BSC uses an 8 decimal system (ETH uses 18), so to see the number we are used to, we need to fix that by dividing by 10 ** 8:

return price / 10 ** 8

…which will get you 427:

There you have it!

Conclusion

Chainlink oracles provide a safe and blockchain-compatible way to access off chain data. Be sure to read up on it’s other use cases like generating a verified random number (VRF) or properly requesting and receiving ANY data off chain.

Hope you found this tutorial helpful. Let’s discuss below.

----------

** This article may contain affiliate links. Please read the affiliate disclaimer for more details.

About Me Author

Travis of

Travis Media

Who Am I? I was 34 years old in a job I hated when I decided to learn to code. Read More
Explore

You May Also Like