Introduction Raffle draws are a popular way to randomly select a winner or winners from a group of participants. In this tutorial, we'll take a look at how to create a smart contract that can be used to conduct a raffle draw on the Ethereum blockchain. We'll discuss the functions and state variables that make up the smart contract and look at the sample code for each function. If you enjoy working on Web3 projects, for all sorts of videos for learning web3 development. You can if you want to connect with me. subscribe to my channel check out my services here Now, let’s jump into the tutorial… Creating a Raffle Draw Smart Contract //SPDX-License-Identifier: MIT pragma solidity ^0.8.7; contract RaffleDraw { address public owner; mapping(address => bool) public players; mapping(uint256 => address) public playerNumber; mapping(address => bool) erasePlayers; mapping(uint256 => address) eraseNo; uint256 public ticketPrice; uint256 public totalPlayers; uint256 public totalPot; address[] winners; constructor() { owner = msg.sender; ticketPrice = 1 ether; } function enter() public payable { require(msg.value == ticketPrice, "Not upto the ticket price"); require(!players[msg.sender], "Player already entered"); players[msg.sender] = true; playerNumber[totalPlayers] = msg.sender; totalPlayers++; totalPot += msg.value; } function draw() public { require(msg.sender == owner, "Caller must be the owner"); require(totalPlayers > 0, "Total players must be more than zero"); address\[] memory eligible = new address[\](totalPlayers); for (uint256 i = 0; i < totalPlayers; i++) { address player = playerNumber[i]; eligible[i] = player; } uint256 winnerCount = thirtyPercent(totalPlayers) > 0 ? thirtyPercent(totalPlayers) : 1; for (uint256 i = 0; i < winnerCount; i++) { uint256 randIndex = uint256( keccak256(abi.encodePacked(block.timestamp, block.difficulty)) ) % totalPlayers; winners.push(eligible[randIndex]); players[winners[i]] = true; eligible = removeAddress(eligible, eligible[randIndex]); } } function shareMoney() public { require(msg.sender == owner, "Caller must be the owner"); for (uint256 i = 0; i < winners.length; i++) { payable(winners[i]).transfer(ticketPrice * 2); } } function getWinners() public view returns (address[] memory) { return winners; } function resetRaffle() public returns (bool) { require(msg.sender == owner, "Caller must be the owner"); for (uint256 i = 0; i < winners.length; i++) { delete winners[i]; } for (uint256 i = 0; i < totalPlayers; i++) { delete players[playerNumber[i]]; delete playerNumber[i]; } totalPlayers = 0; totalPot = 0; return true; } function thirtyPercent(uint256 x) public pure returns (uint256) { return (x * 3) / 10; } function removeAddress(address[] memory addresses, address toRemove) public pure returns (address[] memory) { address\[] memory newAddresses = new address[\](addresses.length - 1); uint256 index = 0; for (uint256 i = 0; i < addresses.length; i++) { if (addresses[i] != toRemove) { newAddresses[index] = addresses[i]; index++; } } return newAddresses; } } Check out one of my videos on how to code an NFT Marketplace below, you can use it to accelerate your web3 development skill. https://www.youtube.com/watch?v=fJIiqeevqoU&embedable=true The smart contract above is called RaffleDraw. It starts with several state variables that are used to keep track of the players, the ticket price, and the total pot of ether collected. See the code block below: address public owner; mapping(address => bool) public players; mapping(uint256 => address) public playerNumber; mapping(address => bool) erasePlayers; mapping(uint256 => address) eraseNo; uint256 public ticketPrice; uint256 public totalPlayers; uint256 public totalPot; address[] winners; constructor() { owner = msg.sender; ticketPrice = 1 ether; } The first function we'll look at is the function. Players use this function to enter the raffle by sending a certain amount of ether to the smart contract. The function checks that the amount of ether sent is equal to the ticket price and that the player has not already entered the raffle. If the checks pass, the player is added to the mapping and the and totalPot variables are incremented. See the snippet below: enter() players totalPlayers function enter() public payable { require(msg.value == ticketPrice, "Not upto the ticket price"); require(!players[msg.sender], "Player already entered"); players[msg.sender] = true; playerNumber[totalPlayers] = msg.sender; totalPlayers++; totalPot += msg.value; } The next function is the function. This function is used by the contract owner to conduct the raffle draw. It first checks that the caller is the owner of the contract and that there are more than zero players. It then creates a new address array called eligible that is the same size as the variable. This array is used to store all the eligible players for the draw. The draw is then conducted by selecting a random index from the eligible array and adding the player at that index to the array. The selected player is also removed from the eligible array using the function to prevent repeat winners. Observe the code below: draw() totalPlayers winners removeAddress() function draw() public { require(msg.sender == owner, "Caller must be the owner"); require(totalPlayers > 0, "Total players must be more than zero"); address\[] memory eligible = new address[\](totalPlayers); for (uint256 i = 0; i < totalPlayers; i++) { address player = playerNumber[i]; eligible[i] = player; } uint256 winnerCount = thirtyPercent(totalPlayers) > 0 ? thirtyPercent(totalPlayers) : 1; for (uint256 i = 0; i < winnerCount; i++) { uint256 randIndex = uint256( keccak256(abi.encodePacked(block.timestamp, block.difficulty)) ) % totalPlayers; winners.push(eligible[randIndex]); players[winners[i]] = true; eligible = removeAddress(eligible, eligible[randIndex]); } } The function is used by the owner of the contract to distribute the winnings to the winners. This function iterates through the array and sends each winner 2 times the ticket price in ether. See the code below: shareMoney() winners function shareMoney() public { require(msg.sender == owner, "Caller must be the owner"); for (uint256 i = 0; i < winners.length; i++) { payable(winners[i]).transfer(ticketPrice * 2); } } The function is a view function that returns the array. This function is useful for displaying the winners to users after the raffle has been conducted. See the snippet below: getWinners() winners function getWinners() public view returns (address[] memory) { return winners; } The function is used by the contract owner to reset the raffle. This function deletes all the players, , and resets the and totalPot variables to zero. resetRaffle() winners totalPlayers function resetRaffle() public returns (bool) { require(msg.sender == owner, "Caller must be the owner"); for (uint256 i = 0; i < winners.length; i++) { delete winners[i]; } for (uint256 i = 0; i < totalPlayers; i++) { delete players[playerNumber[i]]; delete playerNumber[i]; } totalPlayers = 0; totalPot = 0; return true; } I f you want to understand the nitty-gritty of smart contract development, check out the book below to become an in-demand smart contract developer. Grab a copy of my book titled, to become an in-demand smart contract developer. ” “capturing smart contract development The last two functions are helper functions. The function is a pure function that takes in an argument and returns of that argument. The function is used to remove an address from an address array. See the code below: thirtyPercent() 30% removeAddress() function thirtyPercent(uint256 x) public pure returns (uint256) { return (x * 3) / 10; } function removeAddress(address[] memory addresses, address toRemove) public pure returns (address[] memory) { address\[] memory newAddresses = new address[\](addresses.length - 1); uint256 index = 0; for (uint256 i = 0; i < addresses.length; i++) { if (addresses[i] != toRemove) { newAddresses[index] = addresses[i]; index++; } } return newAddresses; } Conclusion In this tutorial, we looked at how to create a smart contract for conducting a raffle draw on the Ethereum blockchain. We discussed the various functions and state variables that make up the contract and looked at sample codes for each function. With this solid understanding of the smart contract, you can now use it as a starting point for your own raffle draw projects or customize it to suit your specific needs. Keep in mind that this is just a basic example, and it is always important to thoroughly test and audit smart contracts before deploying to a live chain. Don’t forget to for all sorts of web3 development videos. Till next time, all the best. subscribe to my channel About the Author Gospel Darlington is a full-stack blockchain developer with years of experience in the software development industry. 6+ By combining Software Development, writing, and teaching, he demonstrates how to build decentralized applications on EVM-compatible blockchain networks. For more information about him, kindly visit and follow his page on , , , or on his . Twitter Github LinkedIn website Also Published Here