By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
Oracles are services that fetch real‑world information (price feeds, weather, sports scores, etc.) and deliver it to smart contracts on the blockchain. They break the “closed‑world” limitation of on‑chain code, enabling decentralized applications to react to off‑chain events—think a DeFi loan that automatically liquidates when the collateral’s price drops, or an NFT mint that only opens when a celebrity’s tweet hits a certain number of likes.
requestData
fulfillData
// Minimal request function requestPrice() external { Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector); req.add("get", "https://api.coinbase.com/v2/prices/ETH-USD/spot"); req.add("path", "data.amount"); sendChainlinkRequest(req, fee); }
fulfill.selector
fee
0.1 LINK
jobId
LINK Token
function fulfill(bytes32 _requestId, uint256 _price) public recordChainlinkFulfillment(_requestId) { price = _price; }
recordChainlinkFulfillment
fulfill
Oracle.sol
request
ChainlinkClient
npm i --save-dev hardhat @chainlink/contracts @openzeppelin/contracts ethers
npx hardhat compile
MockV3Aggregator
bash npx hardhat run scripts/deploy.js --network goerli
The script should also transfer a small amount of LINK to the deployed contract (link.transfer(contract.address, fee)). 5. Trigger a request – From a front‑end (Ethers.js) call contract.requestPrice(). Watch the transaction receipt; the Chainlink node will later call fulfill. 6. Read the result – Query contract.price() to see the on‑chain value that originated off‑chain.
link.transfer(contract.address, fee)
contract.requestPrice()
contract.price()
Mistake: Forgetting to fund the contract with LINK. Correction: Always await link.transfer(contract.address, fee) before the first request; otherwise the transaction reverts with “Insufficient LINK”.
await link.transfer(contract.address, fee)
Mistake: Using tx.origin for access control in the fulfill function. Correction: Rely on the recordChainlinkFulfillment modifier (or onlyOwner from OpenZeppelin) because tx.origin can be spoofed through a malicious contract chain.
tx.origin
onlyOwner
Mistake: Hard‑coding a single node address, thinking it’s “decentralized”. Correction: Deploy with a list of authorized node addresses (setAuthorizedSenders) or use Chainlink’s decentralized oracle network to avoid a single point of failure.
setAuthorizedSenders
Mistake: Ignoring the possibility of stale data (price feed not updated). Correction: Add a timestamp check (block.timestamp - lastUpdated < maxAge) and fallback logic (e.g., revert or use a secondary oracle).
block.timestamp - lastUpdated < maxAge
Mistake: Over‑paying LINK on testnets, leading to unnecessary expense. Correction: Use the fee constant from the Chainlink docs for each network; on Goerli it’s 0.1 LINK, on Sepolia 0.05 LINK.
0.05 LINK
requestDataMultiple
Scenario: A DeFi contract calls requestPrice() but never receives a callback. Answer: The contract will keep its previous price value; you should implement a timeout/retry mechanism because oracle responses are asynchronous.
requestPrice()
Scenario: An attacker tries to front‑run the fulfill transaction by sending a higher‑gas transaction that calls fulfill with a fake price. Answer: The call will revert because recordChainlinkFulfillment checks the requestId against the stored sender address; only the authorized Chainlink node can succeed.
requestId
Scenario: You need a price feed that updates every 30 seconds. Which Chainlink feature helps? Answer: Use a Chainlink Automation (Keepers) job that automatically triggers requestPrice() on a schedule, eliminating manual calls.
uint256
transferAndCall
bytes32 private constant JOB_ID = "0x...";
oracle
setOracle(address)
require(block.timestamp - lastUpdated < 15 minutes, "Stale");
@chainlink/contracts/src/v0.8/tests/
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.