Lesson 23 of 25
Oracles & Chainlink
Bring real-world data on-chain with decentralized oracles and price feeds.
AdvancedThe Oracle Problem
Smart contracts can only access on-chain data. To get real-world information (ETH price, weather, sports scores), you need an oracle — a trusted off-chain data source. Chainlink is the most widely used decentralized oracle network.
Chainlink Price Feeds
Chainlink Data Feeds provide aggregated, tamper-resistant price data for hundreds of asset pairs. Use them to get reliable on-chain prices.
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface AggregatorV3Interface {
function latestRoundData() external view returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function decimals() external view returns (uint8);
}
contract PriceFeedConsumer {
AggregatorV3Interface internal priceFeed;
// Mainnet ETH/USD feed: 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
constructor(address feedAddress) {
priceFeed = AggregatorV3Interface(feedAddress);
}
function getLatestPrice() public view returns (int256 price, uint8 decimals) {
(, int256 answer,,,) = priceFeed.latestRoundData();
return (answer, priceFeed.decimals());
}
function getETHUSDPrice() public view returns (uint256) {
(int256 price, uint8 dec) = getLatestPrice();
require(price > 0, "Invalid price");
return uint256(price) / (10 ** dec); // price in USD
}
}
Chainlink VRF — Verifiable Randomness
Generating truly random numbers on-chain is hard — block hashes are predictable. Chainlink VRF provides cryptographically verifiable randomness.
Solidity
// Simplified VRF consumer example
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
contract RandomNFT is VRFConsumerBaseV2 {
uint256 public randomResult;
constructor(address vrfCoordinator)
VRFConsumerBaseV2(vrfCoordinator) {}
function requestRandomNumber(
bytes32 keyHash,
uint64 subscriptionId
) external returns (uint256 requestId) {
// Requests random number — callback comes later
requestId = COORDINATOR.requestRandomWords(
keyHash, subscriptionId,
3, // confirmations
100000, // gas limit
1 // number of random words
);
}
// Chainlink calls this with the random result
function fulfillRandomWords(
uint256, /* requestId */
uint256[] memory randomWords
) internal override {
randomResult = (randomWords[0] % 100) + 1; // 1-100
}
}