# Chainlink VRF, Automation & Functions ☀️ – Week 13 Update at Blockfuse
Gm gm, this week we looked into **Chainlink** and explored its powerful oracle services — **VRF (Verifiable Random Function)**, **Automation (Keepers)**, and **Functions** for external API calls. Let’s break down what we did 👇
---
## 🎰 Mini Lottery with Chainlink VRF & Automation
We built a decentralized lottery system where users can enter by paying a small ETH fee, and a random winner is picked automatically every few minutes.
### 🔄 How It Works
1. Users enter the lottery by depositing ETH.
2. Every 5 minutes, Chainlink Automation checks if it's time to pick a winner.
3. The contract requests a random number from Chainlink VRF.
4. Once received, it selects a winner from the players.
5. The winner is automatically sent the entire prize pool.
### 🧠 What We Practiced
- Using **Chainlink Automation** for time-based logic.
- Fetching random numbers using **Chainlink VRF**.
- Managing contract state, players, and winners.
- Solidity best practices: `immutable`, `constructor`, `events`, and `require`.
---
### 📦 Chainlink VRF + Automation Smart Contract

This contract is built on two key Chainlink modules:
**VRFConsumerBaseV2:** This is used to interact with Chainlink’s VRF, enabling us to request and receive random numbers.
**AutomationCompatibleInterface:** This allows us to use Chainlink Keepers to automatically trigger certain functions in the contract based on specific conditions.
**Entering the Lottery**
```solidity
function enterLottery() public payable {
require(msg.value >= i_entranceFee, "Not enough ETH to enter lottery");
s_players.push(msg.sender);
emit LotteryEnter(msg.sender);
}
```
Here, users can participate in the lottery by sending at least the entranceFee (in ETH). When they enter, their address is added to the list of players, and an event is emitted.
**. Chainlink Keeper: Checking Upkeep**
```solidity
function checkUpkeep(bytes calldata /* checkData */) external view override returns (bool upkeepNeeded, bytes memory /* performData */) {
bool timeHasPassed = (block.timestamp - s_lastTimeStamp) >= i_interval;
bool hasPlayers = s_players.length > 0;
bool hasBalance = address(this).balance > 0;
upkeepNeeded = timeHasPassed && hasPlayers && hasBalance;
return (upkeepNeeded, "");
}
```
Chainlink Keepers are used to automate the process. The checkUpkeep function checks if certain conditions are met (such as if enough time has passed since the last lottery drawing, if there are players in the pool, and if the contract has a balance). If these conditions are true, the Keeper will trigger the next step.
**Performing the Upkeep: Requesting Random Numbers**
```solidity
function performUpkeep(bytes calldata /* performData */) external override {
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_gasLane,
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emit RequestedLotteryWinner(requestId);
}
```
Once the checkUpkeep function returns true, the performUpkeep function is called, which makes a request to Chainlink’s VRF for a random number. The request ID is emitted so we can track the request.
**Selecting the Winner: Fulfill Random Words**
```solidity
function fulfillRandomWords(uint256 /* requestId */, uint256[] memory randomWords) internal override {
uint256 winnerIndex = randomWords[0] % s_players.length;
address winner = s_players[winnerIndex];
s_recentWinner = winner;
(bool success, ) = winner.call{value: address(this).balance}("");
require(success, "Transfer failed");
s_players = new address ;
s_lastTimeStamp = block.timestamp;
emit WinnerPicked(winner);
}
```
Once the random number is received, we use it to select a winner. The winner’s address is then paid out the entire balance of the contract. The players list is reset, and the timestamp is updated for the next lottery.
### 🌐 Consuming External APIs with Chainlink Functions
We also learned how to make our smart contracts interact with real-world data from an external API using Chainlink Functions.
**Example**: Fetch Data from jsonplaceholder.typicode.com
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/functions/contracts/dev/0_0_1/FunctionsClient.sol";
import "@chainlink/functions/contracts/dev/0_0_1/Functions.sol";
contract ExternalAPICall is FunctionsClient {
using Functions for Functions.Request;
string public latestData;
bytes32 public lastRequestId;
constructor(address oracle) FunctionsClient(oracle) {}
function requestData(string calldata endpoint, string calldata sourceCode) external {
Functions.Request memory req;
req.initializeRequest(Functions.Location.Inline, Functions.CodeLanguage.JavaScript, sourceCode);
req.addQuery(string(abi.encodePacked("https://jsonplaceholder.typicode.com/", endpoint)));
lastRequestId = sendRequest(req, 100000, 1); /
}
function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory) internal override {
latestData = string(response);
}
}
```
**JavaScript Source (Inline JS for Chainlink Functions)**
```js
const endpoint = args[0];
const response = await Functions.makeHttpRequest({
url: `https://jsonplaceholder.typicode.com/${endpoint}`,
});
if (!response || !response.data) {
throw Error("Failed to fetch from API");
}
return Functions.encodeString(JSON.stringify(response.data));
```
**Conclusion**
Week 13 introduced us to the power of Chainlink in creating decentralized applications. By utilizing Chainlink’s VRF for verifiable randomness and Keepers for automation, we were able to build a fair and automated lottery system. Additionally, the integration of Chainlink with external APIs provided valuable insights into how smart contracts can interact with real-world data.
Feel free to check out the full project on GitHub and try it out yourself:
🔹 GitHub Repository: [https://github.com/Anuoluwapo25/Lottery_chainlink]