DEV Community

Cover image for Create a Raffle Draw Smart Contract Using Foundry 2024 (Part 1)
Scofield Idehen
Scofield Idehen

Posted on • Originally published at blog.learnhub.africa

Create a Raffle Draw Smart Contract Using Foundry 2024 (Part 1)

Smart contracts allow conducting transparent raffles on the blockchain by enforcing rules in code. We will build a decentralized Ethereum raffle that takes Ether entries, picks a random winner, and sends the prize money automatically.

This article will guide you through building and understanding a Raffle smart contract using Foundry step-by-step.

Prerequisites

Before we start coding, you need a basic understanding of Solidity and working with Remix IDE. No prior experience building smart contracts is required, as we will explore all the concepts along the way.

For this tutorial, we will be using Foundry, and to set that up on Vscode, I wrote a guide to help you get started.

The full code blocks can be found here; fork it and follow along.

Setting Your Environment

Open your Vscode and create a folder, run a forge init to set up dependencies for Foundry, and then delete all the counter.sol files in src, script, and test. We will not need them going forward.

Setting up the Raffle Contract

Create a file in src. I will call mine raffle.sol next. We will define the version of Solidity and add NatSpec comments to document our contract properly.

The SPDX license identifier ensures the open-source licensing of our code. We target Solidity version 0.8.18 to use the latest features. The NatSpec comments provide a title, description, author, and usage notice for our Raffle contract.

Defining State Variables

Next, we define state variables to store essential contract data.

The i_ticketPrice will store the ticket price set at deployment. We make it immutable  so it can never change.

An error Raffle__InsufficientETH() will be thrown when the Ether sent is less than the ticket price. Finally, we use a dynamic array s_participants to store the addresses of all players.

Setting the Ticket Price

The contract needs to know the ticket price, so we add a constructor that sets it.

Anyone deploying the contract must pass ticketPrice, which gets stored in the immutable state variable. i_ticketPrice

Adding the Enter Function

We now need a way for players to enter the raffle by paying the entrance fee.

We first use an if statement to check that the Ether sent is greater than the ticket price. If not, we revert with a custom error that gets caught on the front end.

note we could have used the required require(msg.value >= i_ticketPrice, "Raffle: Insufficient amount");

I discovered it would cost more gas using require when we tested it on remix.

To understand these two lines of code properly, we must first understand Event

Events on the Blockchain

Blockchain-based applications generate data that we sometimes want external services to be aware of. For example, our Raffle contract must be able to perform randomness to pick a winner, but as we are aware, blockchain is deterministic.

We must rely on a decentralized oracle leveraging Verifiable Random Function, and we would use the Chainlink VRF to connect our smart contracts to verifiable randomness.

Defining Events

Events are a way for smart contracts to emit messages to interested external listeners. Here is an event definition in our contract:

event RafflesEntered(address indexed player);

This RafflesEntered event contains one parameter named player of type address. The indexed keyword allows efficient filtering for that address later.

Emitting Events

We can trigger events from within functions. For example, when a player enters the raffle:

The emit keyword triggers the event, passing the player's address captured from the global msg.sender.

Listening for Events Using Chainlink VRF

Chainlink nodes listen for our event via the Chainlink VRF oracle. When detected, the oracle uses the key to track the request and provide a verifiable random number corresponding to that key.

We can access the random number by implementing a fulfillRandomness callback in our contract. Chainlink VRF triggers it automatically once randomness generation is complete.

Events are powerful for decoupling smart contract logic from notifications. Defining, emitting, and listening for events unlocks reactive application possibilities on Ethereum.

Conclusion

That concludes our tutorial on building a transparent Raffle contract on Ethereum! We learned about storing state, accepting payments, generating randomness and sending funds,

In our follow-up series, we will dive into how randomness works using Chainlink VRF and how to get the withdrew function to work.

If you find this article thrilling, discover extra thrilling posts like this on Learnhub Blog; we write a lot of tech-related topics from Cloud computing to Frontend Dev, Cybersecurity, AI, and Blockchain. Take a look at How to Build Offline Web Applications. 

Resource

Gift us a cup of coffee if you are so kind.  

Top comments (0)