By now you've probably heard of Chainlink. Maybe you are even participating the current hackathon? In any case adding their new contracts to retrieve price feed data is surprisingly simple. But how does it work?
Oracles and decentralization
If you're confused about oracles, you're not alone. The term is so overused these days for literally anything, probably because it sounds fancy. But almost anything could call itself an oracle technically. So what is an oracle?
It's nothing more than some form of bringing off-chain data on to a blockchain. Think of an external API call or the weather forecast for tomorrow. You can't have Ethereum nodes retrieve this data directly, because it has to be deterministic. Just imagine one node requesting an API to ask if it's going to rain tomorrow. The answer right now is no, but only 5 minutes later, the next node validates the transaction, requests the weather API and now it says: yes, it will rain tomorrow. That's not going to work, a transaction has to be able to be validated by anyone at anytime with the same result.
So now think of a contract that stores the weather forecast for tomorrow. In the simplest form the design would be- smart contract with functions to read and write the forecast data
- server fetching forecast from an API and regularly updating the smart contract
That's all we need for a simple oracle. By sending a transaction to our smart contract with the forecast data, it becomes available on-chain for other contracts. But only one server that updates this? You can see the problem...

So clearly with only one node an oracle wouldn't be very much decentralized. Chainlink encourages to use many sources of truth and their price feeds all have several nodes that are participating. The pick the median value (safer than the average) from all the values they receive from nodes in each round. Chainlink is a generalized oracle protocol meaning you could use it for any kind of data, but let's focus on the price feeds as they are really easy to use and often needed.
Receiving price feed data
While the Chainlink protocol is a general system for any kind of data, Chainlink specifically provides price feeds for many cryptos, fiats and stocks. The best thing about it? It's currently free to use and requires almost no setup. Simply pick a price feed and read the current price.
A normal off-chain read may be free from the chosen RPC provider, but a contract reading the feed during a transaction consumes gas. Verify the specific feed’s access and integration requirements.
The original example used the ETH/USD feed on Kovan: USD per ETH, not ETH per USD. Kovan is retired. Select the supported network and feed proxy from the current address directory; the reader below accepts that address explicitly.
Reading the current price
First let's install the chainlink interfaces via:
$ npm install @chainlink/contracts --saveAggregatorV3Interface exposes latestRoundData and getRoundData; getLatestPrice and getHistoricalPrice are names of our wrappers. The returned answer uses the feed’s decimals(), and updatedAt matters for freshness. answeredInRound is a deprecated field.
For this ETH/USD-style positive price, reject nonpositive answers, unset or future update times and data older than a maximum age chosen for the feed and application. A timestamp check is only part of the integration: on relevant L2s, also apply the documented sequencer-uptime and recovery rules.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
contract EthUsdOracle {
AggregatorV3Interface public immutable priceFeed;
uint256 public immutable maxAge;
constructor(address feed, uint256 acceptableAge) {
require(feed != address(0) && acceptableAge != 0, "Invalid configuration");
priceFeed = AggregatorV3Interface(feed);
maxAge = acceptableAge;
}
function getLatestPrice() public view returns (int256 price, uint8 decimals) {
uint256 updatedAt;
(, price,, updatedAt,) = priceFeed.latestRoundData();
require(price > 0, "Invalid price");
require(updatedAt != 0 && updatedAt <= block.timestamp, "Invalid timestamp");
require(block.timestamp - updatedAt <= maxAge, "Stale price");
decimals = priceFeed.decimals();
}
}
Retrieving historical price feed data
You can also use this feed to get historical data via the getHistoricalPrice function. Call it with the round id that you're interested in. You'll receive a similar response as before
- the current round id
- the ETH price in USD in that round
- the timestamp of when the current round started
- the timestamp when the current round was completed
- the id of the round in which the current ETH price was set
But this time you might care about the timestamp when the round was completed to figure out the exact the corresponding time for that price. You could do this off-chain in some cases to figure out the correct round id.
The historical-data helper below is a separate excerpt to place in the reader contract if needed. An old round is intentionally old: do not treat its value as a current price merely because updatedAt is nonzero. Some feeds or phases may not expose every historical round.
function getHistoricalPrice(
uint80 roundId
) public view returns (
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) {
(
roundID,
price,
startedAt,
timeStamp,
answeredInRound
) = priceFeed.getRoundData(roundId);
require(timeStamp > 0, "Round not complete");
}Price feeder markets
A nice visual overview of price feeds is available at: https://feeds.chain.link/. For example the ETH/USD oracle at https://feeds.chain.link/eth-usd.

Use the feed’s documented proxy address. Its underlying aggregator can change, so the old 0xf79d... address is a historical example, not a current backend guarantee. AggregatorV3Interface provides the stable read interface through the proxy; choose addresses separately for each chain.

We need oracles
There you have it. I think the price feeds are a great way to get started with Chainlink. You might want to combine it with some other solutions not to rely solely on Chainlink including your own price feed.
And in case I don't see you, good afternoon, good evening and good night!




Join the conversation
Comments are hosted by Disqus and load only when you choose to enable them.