Getting External Data with Chainlink

In this article, I’m going to show you how to code a contract that has access to the conversion rate between ETH and USD using the Chainlink decentralized oracle.

Blockchains are deterministic systems. This means that there is no room for variability amongst the data in nodes; each node should have the same exact data.

In order to maintain a blockchain’s deterministic nature, smart contracts on the blockchain are unable to connect with external systems, data feeds, APIs, existing payment systems or any other off-chain resources on their own.

In order to get data from the real world, smart contracts need to use an oracle. An oracle is a trusted third-party that interacts with the off-chain world to provide external data or computation to smart contracts. In other words, oracles are the bridges between blockchains and the real world.

Oracles can provide blockchains with information about currency prices, the weather, political results, and much more.

An oracle cannot be centralized because then we would have the same problem: nodes in a blockchain could end up with different data. Instead, oracles must be decentralized.

Chainlink is the most popular decentralized oracle provider.

Writing the Code

I created my contract on Remix IDE and I am using Remix to test my contract. I won’t be explaining how to use Remix in this article.

In order to work with the Chainlink oracle, we need to import their code into our contract using this line:

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

What exactly is this line doing, though? Basically, we are importing code from the chainlink/contracts npm module. If you go to the project’s Github (here), and follow the path in the import statement (here), you will get to the code where they define the AggregatorV3Interface interface. So, basically, we are importing the AggregatorV3Interface interface into our project so we can work with it.

Interfaces are similar to abstract contracts. As you can see, the interface defines a function but it cannot define its implementation.

Interfaces tell your Solidity contract how it can interact with another contract. So, since we will be accessing Chainlink contracts, this interface tells our contract what functions we can use from the Chainlink contract.

We made a contract call to another contract from our contrat using interfaces. Interfaces are a minimalistic view into another contract.

We work with interfaces and other contracts the same way that we work with variables or structs within our own contracts.

Make Function to Get Interface Version

Now, we will access some information from the Chainlink blockchain using the interface. We will create a function to get the version of the interface.

function getVersion() public view returns (uint256){
}

First, we create an instance of the interface:

function getVersion() public view returns (uint256){
    AggregatorV3Interface priceFeed = AggregatorV3Interface()
}

In order to find where the ETH / USD price feed contract is located on the Chainlink Rinkeby blockchain, we can go to the Ethereum Price Feeds documentation:

It has a bunch of different price feeds. Find the ETH / USD price feed contract address and put the address in the parameter of the interface:

AggregatorV3Interface priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e)

So, basically this line is saying that we have a contract that has these functions defined in the interface located at the address 0x8A753747A1Fa494EC906cE90E9f37563A8AF630e.

If this is true, we should be able to call the version method on priceFeed:

AggregatorV3Interface priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
return priceFeed.version();

The full function:

Now, you can deploy your contract and see if it works. In my case, using Remix IDE, I was able to access the getVersion function through the IDE, so it was successful!

Make Function to Get Latest Price

Now, we will create a function to get the current price of ETH in terms of USD from Chainlink.

We start by defining the function and creating another instance of the interface:

function getPrice() public view returns(uint256){
        AggregatorV3Interface priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
}

We are trying to access the answer return variable from the latestRoundData method of the interface (see interface code above).

The latestRoundData method returns 5 items. Since we only need answer, we can ignore the other variables and just add commas for them:

(,int256 answer,,,) = priceFeed.latestRoundData();

Then, convert answer to uint256 and return it:

return uint256(answer);

The full function code:

Summary

Here is the final code:

In this tutorial, you learned what oracles are and why they are important. You learned how to use the Chainlink oracle in your own smart contract to access real-world data on the blockchain.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s