Create a Raffle Draw Smart Contract Using Foundry 2024 (Part 1)
Tags: web3, smartcontract, ethereum, blockchain
Published: 2023-12-27 15:20:25

<p data-pm-slice="1 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.</p>
This article will guide you through building and understanding a Raffle smart contract using Foundry step-by-step.
<h2>Prerequisites</h2>
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 <a class="attrlink" href="https://blog.learnhub.africa/2023/12/19/getting-started-with-foundry-for-beginners-in-2024/" target="_blank" rel="noreferrer nofollow noopener">get started</a>.

The full code blocks can be found <a class="attrlink" href="https://github.com/Scofield-Idehen/Smart_Lottery.git" target="_blank" rel="noreferrer nofollow noopener">here</a>; fork it and follow along.
<h2>Setting Your Environment</h2>
Open your Vscode and create a folder, run a forge init to set up dependencies for Foundry, and then delete all the <code>counter.sol</code> files in src, script, and test. We will not need them going forward.

<img src="https://paper-attachments.dropboxusercontent.com/s_17A7C40E8A46B031FACCA9C93595528BFC73E47C8F2531C6D9FF3BD36D2FB2C6_1703685769613_Screenshot+2023-12-27+at+15.02.44.png" align="left" />
<h2>Setting up the Raffle Contract</h2>
Create a file in src. I will call mine <code>raffle.sol</code> next. We will define the version of Solidity and add <a class="attrlink" href="https://docs.soliditylang.org/en/latest/natspec-format.html" target="_blank" rel="noreferrer nofollow noopener">NatSpec</a> comments to document our contract properly.

<img src="https://paper-attachments.dropboxusercontent.com/s_17A7C40E8A46B031FACCA9C93595528BFC73E47C8F2531C6D9FF3BD36D2FB2C6_1703689350431_image.png" align="left" />

The SPDX license identifier ensures the open-source licensing of our code. We target <code>Solidity version 0.8.18</code> to use the latest features. The NatSpec comments provide a title, description, author, and usage notice for our Raffle contract.
<h2>Defining State Variables</h2>
Next, we define state variables to store essential contract data.

<img src="https://paper-attachments.dropboxusercontent.com/s_17A7C40E8A46B031FACCA9C93595528BFC73E47C8F2531C6D9FF3BD36D2FB2C6_1703689409676_image.png" align="left" />

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

An error <code>Raffle__InsufficientETH()</code> will be thrown when the Ether sent is less than the ticket price. Finally, we use a dynamic array <code>s_participants</code> to store the addresses of all players.
<h2>Setting the Ticket Price</h2>
The contract needs to know the ticket price, so we add a constructor that sets it.

<img src="https://paper-attachments.dropboxusercontent.com/s_17A7C40E8A46B031FACCA9C93595528BFC73E47C8F2531C6D9FF3BD36D2FB2C6_1703689459622_image.png" align="left" />

Anyone deploying the contract must pass <code>ticketPrice</code>, which gets stored in the immutable state variable. i_ticketPrice
<h2>Adding the Enter Function</h2>
We now need a way for players to enter the raffle by paying the entrance fee.

<img src="https://paper-attachments.dropboxusercontent.com/s_17A7C40E8A46B031FACCA9C93595528BFC73E47C8F2531C6D9FF3BD36D2FB2C6_1703689498573_image.png" align="left" />

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 <code>required require(msg.value &gt;= i_ticketPrice, "Raffle: Insufficient amount");</code>

I discovered it would cost more gas using <code>require</code> when we tested it on remix.

To understand these two lines of code properly, we must first understand <code>Event</code>
<h2>Events on the Blockchain</h2>
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 <strong>Verifiable Random Function,</strong> and we would use the <a class="attrlink" href="https://docs.chain.link/vrf/v2/subscription/supported-networks" target="_blank" rel="noreferrer nofollow noopener">Chainlink VRF</a> to connect our smart contracts to verifiable randomness.
<h2>Defining Events</h2>
Events are a way for smart contracts to emit messages to interested external listeners. Here is an event definition in our contract:

<code>event RafflesEntered(address indexed player);</code>

This RafflesEntered event contains one parameter named player of type address. The indexed keyword allows efficient filtering for that address later.
<h2>Emitting Events</h2>
We can trigger events from within functions. For example, when a player enters the raffle:

<img src="https://paper-attachments.dropboxusercontent.com/s_17A7C40E8A46B031FACCA9C93595528BFC73E47C8F2531C6D9FF3BD36D2FB2C6_1703689558486_image.png" align="left" />

The emit keyword triggers the event, passing the player's address captured from the global <code>msg.sender</code>.
<h2>Listening for Events Using Chainlink VRF</h2>
Chainlink nodes listen for our event via the <a class="attrlink" href="https://docs.chain.link/vrf/v2/subscription/supported-networks" target="_blank" rel="noreferrer nofollow noopener">Chainlink VRF oracle</a>. 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 <code>fulfillRandomness</code> callback in our contract. Chainlink VRF triggers it automatically once randomness generation is complete.

<img src="https://paper-attachments.dropboxusercontent.com/s_17A7C40E8A46B031FACCA9C93595528BFC73E47C8F2531C6D9FF3BD36D2FB2C6_1703689595220_image.png" align="left" />

Events are powerful for decoupling smart contract logic from notifications. Defining, emitting, and listening for events unlocks reactive application possibilities on Ethereum.
<h2>Conclusion</h2>
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 <a class="attrlink" href="https://blog.learnhub.africa/" target="_blank" rel="noreferrer nofollow noopener">Learnhub Blog</a>; we write a lot of tech-related topics from <a class="attrlink" href="https://blog.learnhub.africa/category/cloud-computing/" target="_blank" rel="noreferrer nofollow noopener">Cloud computing</a> to <a class="attrlink" href="https://blog.learnhub.africa/category/frontend/" target="_blank" rel="noreferrer nofollow noopener">Frontend Dev</a>, <a class="attrlink" href="https://blog.learnhub.africa/category/security/" target="_blank" rel="noreferrer nofollow noopener">Cybersecurity</a>, <a class="attrlink" href="https://blog.learnhub.africa/category/data-science/" target="_blank" rel="noreferrer nofollow noopener">AI</a>, and <a class="attrlink" href="https://blog.learnhub.africa/category/blockchain/" target="_blank" rel="noreferrer nofollow noopener">Blockchain</a>. Take a look at <a class="attrlink" href="https://blog.learnhub.africa/2023/02/16/how-to-build-offline-web-applications/" target="_blank" rel="noreferrer nofollow noopener">How to Build Offline Web Applications. </a>
<h2>Resource</h2>
<ul>
 	<li><a class="attrlink" href="https://blog.learnhub.africa/2023/12/19/getting-started-with-foundry-for-beginners-in-2024/" target="_blank" rel="noreferrer nofollow noopener">Getting Started with Foundry for Beginners in 2024</a></li>
 	<li><a class="attrlink" href="https://blog.learnhub.africa/2023/09/25/what-are-smart-contracts/" target="_blank" rel="noreferrer nofollow noopener">What are Smart Contracts?</a></li>
</ul>
<a class="attrlink" href="https://www.buymeacoffee.com/Scofield" target="_blank" rel="noreferrer nofollow noopener">Gift us a cup of coffee if you are so kind.  </a>