π’ Live Demo Deployed at: https://imaginative-creponne-075b15.netlify.app/
This is a fully decentralized lottery smart contract built with Solidity and Hardhat. It allows users to buy lottery tickets and automatically picks a random winner using Chainlink VRF (Verifiable Random Function) and Chainlink Automation (Keepers).
β
Users can buy tickets by paying a fixed entrance fee
β
Random winner picked using Chainlink VRF
β
Automated winner selection using Chainlink Automation (no need for manual trigger)
β
Fund transfer to the winner
β
Built for Ethereum-compatible testnets (e.g., Sepolia)
| Technology | Use |
|---|---|
| Solidity | Smart Contract |
| Hardhat | Development Framework |
| Chainlink VRF | Verifiable Randomness |
| Chainlink Automation (Keepers) | Automated execution |
| Ethers.js | Web3 Interactions (optional frontend) |
.
βββ ChainWin/
β βββ frontend/ # Contains the Next.js frontend application.
β β βββ public/ # Static assets for the frontend.
β β βββ src/ # Source code for the Next.js application.
β β β βββ app/ # Main application pages and components.
β β β βββ constants/ # ABI and contract addresses.
β β β βββ lib/ # Wagmi configuration.
β β βββ .next/ # Next.js build output.
β β βββ node_modules/ # Frontend dependencies.
β β βββ ... # Configuration files (tailwind, postcss, etc.)
β β
β βββ smart-contracts/ # Contains the Hardhat smart contracts project.
β βββ contracts/ # Solidity smart contracts (Lottery.sol).
β βββ deploy/ # Scripts for deploying contracts.
β βββ deployments/ # Deployment artifacts for different networks.
β βββ script/ # Helper scripts for interacting with contracts.
β βββ test/ # Contract tests (unit and staging).
β βββ artifacts/ # Contract compilation artifacts.
β βββ cache/ # Hardhat cache.
β βββ node_modules/ # Backend dependencies.
β βββ ... # Configuration files (hardhat.config.js, etc.)
β
βββ .git/ # Git version control directory.
βββ README.md # This file.
Anyone can call buyTicket() and send the required ETH. Their address is added to the players list.
The contract uses Chainlink VRF to request a random number. This happens automatically using Chainlink Keepers (Automation).
- How to Use VRF in This Project:
- Deploy your contract and note the address.
- Go to Chainlink VRF Subscription Manager
- Create a subscription and fund it with Sepolia ETH or LINK.
- Add your deployed contract as a consumer.
- Get your Subscription ID, Key Hash, and VRF Coordinator Address (from Chainlink docs).
- Update your contract or deployment scripts with these values.
-
Chainlink Keepers (Automation) regularly call
checkUpkeep()off-chain to check:- Enough time passed (e.g., 1 min)
- At least 1 player entered
- Contract has ETH balance
-
If true, it triggers
performUpkeep(), which requests a random number from VRF. -
How to Use Automation in This Project:
- Visit Chainlink Automation App
- Register your contract as a Keeper job.
- Provide your contract address, gas limit, and time interval (e.g., 60 sec).
- Keep your subscription funded.
- Chainlink VRF gets triggered by
requestRandomWords() - After a few blocks, it calls
fulfillRandomWords()with a random number - A random player is selected and sent the prize.
| Function | Description |
|---|---|
buyTicket() |
Pay and enter the lottery |
requestRandomWinner() |
Internal: Called by performUpkeep() |
fulfillRandomWords() |
Called by Chainlink VRF with randomness |
checkUpkeep() |
Called by Chainlink Keeper to check conditions |
performUpkeep() |
Calls requestRandomWinner() if needed |
The lottery operates in a cyclical, automated fashion. Hereβs a step-by-step breakdown of the process from a player entering to a winner being chosen.
A user calls the buyTicket() function and sends the required entranceFee in ETH. Their address is then added to the list of players for the current round.
Chainlink Automation (Keepers) continuously monitor the contract off-chain by calling checkUpkeep(). The upkeep is performed if the following conditions are met:
- The lottery state is
OPEN. - A specific time interval has passed since the last draw.
- There is at least one player in the lottery.
- The contract has a balance to pay the winner.
When these conditions are true, the Keeper calls performUpkeep(), which begins the process of selecting a winner.
The performUpkeep() function requests one or more random numbers from the Chainlink VRF Coordinator. This is a secure, on-chain request for verifiable randomness.
After a few blocks, the Chainlink VRF Coordinator responds by calling the fulfillRandomWords() function in our contract, delivering the random number. This function then performs the final steps:
- Uses the random number to select a
recentWinnerfrom the array of players. - Transfers the entire contract balance (the prize pool) to the winner.
- Resets the lottery state, clearing the players list and opening it for a new round.
git clone https://github.com/HAMZOO0/lottery-dapp
cd lottery-dapp
npm installπ .env Setup
Create a .env file in the root directory:
PRIVATE_KEY=your_private_key
SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/your_project_id
ETHERSCAN_API_KEY=your_etherscan_key
npx hardhat compile
npx hardhat run scripts/deploy.js --network sepolia- Go to Chainlink VRF Subscription Manager
- Create a subscription and fund it with Sepolia ETH or LINK
- Add your deployed contract as a consumer
- Get:
- Subscription ID
- Key Hash (from docs)
- VRF Coordinator Address
- Update your contract/deployment scripts with these values
- Visit Chainlink Automation App
- Register your contract
- Provide:
- Your contract address
- Gas limit
- Time interval (e.g., 60 sec)
- Keep your subscription funded
The following scripts are available in the package.json for managing and testing your smart contracts:
| Script | Description |
|---|---|
npm test |
Run all unit tests with Hardhat |
npm run test:staging |
Run tests on the Sepolia testnet |
npm run test:local |
Run tests on a local Hardhat/localhost node |
npm run coverage |
Generate a Solidity code coverage report |
You can run these scripts from the root of your project. For example:
npm run test:stagingYou can add your frontend code in the frontend/ directory. Use JavaScript libraries like ethers.js or web3.js to connect to the deployed contract.
Feel free to contribute or open issues for improvements!








