How to Fetch the Current Price of Ethereum, Bitcoin, and Other Cryptocurrencies in Solidity
Updated November 5, 2021
Fetching price data into a Solidity smart contract is a common requirement of DeFi applications. To get the current price of Ethereum, Bitcoin, or other cryptocurrencies in Solidity, you can either:
- Fetch price data using Chainlink Price Feeds
- Fetch price data using an external API via a Chainlink oracle
In this technical tutorial, we’ll walk through both approaches and share code examples to help you build, deploy, and test your smart contract. First, let’s quickly cover the importance of data quality and end-to-end decentralization when feeding external inputs into your smart contracts.
The Need for Accurate and Reliable Prices in Smart Contracts
This year has seen explosive growth in DeFi protocols, with the total value locked (TVL) in DeFi skyrocketing from $26B in January to now over $100B. These DeFi protocols rely on outside price data as their data source, because a blockchain cannot natively access external data. In addition to this, these applications need to provide data quality guarantees to protect their applications from exploits such as price oracle attacks.
Chainlink Price Feeds mitigate the risk of these attacks by providing aggregated data from various high-quality data providers, fed on-chain by decentralized oracles on the Chainlink Network. Chainlink’s decentralized oracle mechanism ensures the final price values reflect broad market coverage, meaning the final price is determined after aggregating a diverse set of prices across the entire market, rather than just a small subset, while also taking into account other aspects such as volume and liquidity.
Now that we understand the need for accurate and reliable price data in Solidity smart contracts and the important role that Chainlink Price Feed oracles play, we’ll go through an example of using a Chainlink Price Feed to obtain the latest price of Ethereum in a Solidity smart contract. The steps below also apply to Bitcoin and other cryptocurrencies.
Using Chainlink Price Feeds on Ethereum
Chainlink Price Feeds use multiple high-quality data inputs and aggregate them through a decentralized network of Chainlink oracles that feed price data into reference contracts, where the results are again aggregated in an Aggregator Smart Contract as the latest, trusted answer. By using multiple sources of data aggregated by multiple nodes, we can ensure our price data is of the highest quality, and not subject to exploits or price oracle attacks.
Creating the Smart Contract
The first step is to obtain testnet ETH to use as gas in your smart contract. Once you have some ETH, the easiest way to start building a smart contract that uses Chainlink Price Feeds is to begin with the standard Price Consumer contract. This is a basic contract for initiating requests to Chainlink Price Feeds. For the purposes of this demo we will use the ETH/USD Price Feed already defined in the standard Price Consumer contract, but we’ll walk through each section of code so you understand how it works.
First, we can see the AggregatorV3Interface contract interface was imported. This allows our smart contract to reference the on-chain Price Feeds on the Kovan testnet. An instance of it is then created in a local variable.
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
AggregatorV3Interface internal priceFeed;
Next, we can see a Price Feed reference contract was initialized in our constructor. The ETH/USD Price Feed reference contract on the Kovan Testnet is deployed at the address 0x9326BFA02ADD2366b30bacB125260Af641031331.
priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
We can then see a function has been defined to obtain the latest price from the Price Feed Aggregator contract that was instantiated in the constructor above. To do this, a new function was defined that calls the latestRoundData function from the Aggregator proxy contract. This is the function that returns the current state of the proxy contract, and in this case we are taking the current price and returning it in our consuming function.
function getLatestPrice() public view returns (int) { ( uint80 roundID, int price, uint startedAt, uint timeStamp, uint80 answeredInRound ) = priceFeed.latestRoundData(); return price; }
Deploying and Testing the Smart Contract
Now we are ready to deploy and test our contract. Compile the contract in Remix, then on the deployment tab, change the environment to “Injected Web3”, and ensure the wallet address below is the one in your MetaMask wallet that contains some ETH obtained earlier, press the deploy button, and follow the steps. The end result is you have your smart contract deployed to the Kovan testnet. You should take note of the deployed contract address via the transaction output in the Remix console.
Once deployed, we simply need to execute the “getLatestPrice” function. The result should be that the function returns the latest price from the ETH/USD proxy contract, which can then be used on-chain in our smart contract. Take note we didn’t need to send any LINK for the request, and we didn’t even have to spend any ETH either, the transaction is a pure read of the data in the on-chain ETH-USD Aggregator contract.
Fetching Other Price Data in Solidity
Chainlink Price Feeds offer a vast array of price data for top DeFi price pairs. If you need to get price data into your Solidity smart contract for an asset that isn’t covered by an existing price feed, such as the price of a particular stock, you can customize Chainlink oracles to call any external API.
The easiest way to get external price data using Chainlink oracles is to begin with a standard Chainlink APIConsumer contract. This is a standardized contract for initiating requests for external data via a Chainlink oracle.
Once you have created an APIConsumer contract, you can then find the API that you want to obtain price data from.
Once you have your API endpoint, you simply need to set the correct parameters in your contract and send the request off to a Chainlink oracle. More information on this and how the standard APIConsumer contract is used can be found in the Chainlink documentation.
Keep in mind, you’ll want to decentralize this method when you go to production, or get this specific data on a price feed itself.
Summary
Chainlink Price Feeds provide a reliable way to get high-quality Bitcoin, Ethereum, and other cryptocurrency price data into Solidity smart contracts. In addition to this, Chainlink’s oracle framework provides the flexibility to quickly and easily fetch other price data for stocks, commodities, and other assets.
If you’re a developer and want to quickly get your application connected to Chainlink Price Reference Data, visit the developer documentation and join the technical discussion in Discord.