5/5
_Follow along with this video:_ --- ### Tracking participants Ok, our user paid the entrance fee, but how do we track his registration? We can't simply take the money and run! We need a storage structure that keeps track of all registered users from where to pick the winner. Take a moment and decide what would be the best from the following: 1. Mapping 2. Array 3. A bunch of address variables and limit the number of participants . . . Congratulations if you chose the **Array** option! To be more specific, a dynamic array that grows in size with each new participant. Mappings can't be looped through, and a bunch of address variables is not feasible. Add the array below the `i_entranceFee` declaration: `address payable[] private s_players;` We've made it `address payable` because one of the participants registered in this array will be paid the ETH prize, hence the need for the `payable` attribute. Back in the `enterRaffle` function, we need to add the address that paid into the `s_players` array: ```solidity function enterRaffle() external payable { if(msg.value < i_entranceFee) revert Raffle__NotEnoughEthSent(); s_players.push(payable(msg.sender)); } ``` The `.push` method is used to append an element to an array, increasing its length by 1. `s_players.push(payable(msg.sender));` performs a modification of the state by adding the payable address `msg.sender` in the array. It is customary to emit an **event** every time we perform a state modification. ### Events Events are a way for smart contracts to communicate with the outside world, primarily with the front-end applications that interact with these contracts. Events are logs that the Ethereum Virtual Machine (EVM) stores in a special data structure known as the blockchain log. These logs can be efficiently accessed and filtered by external applications, such as dApps (decentralized applications) or off-chain services. The logs can also be accessed from the blockchain nodes. Each emitted event is tied up to the smart contract that emitted it. Please click [here](https://docs.soliditylang.org/en/v0.8.25/contracts.html#events) to find out more about events. How can we use events? Imagine we have a more complex function that changes an important parameter, let's say we are recording the exchange rate of BTC/USDC. We change it by calling the function `changeER()`. After we perform the call and the exchange rate is changed we need to make sure this also gets picked up by our front-end. We make the front-end listen for the `BTCUSDCupdated` event. An example of that event could be this: ```solidity event BTCUSDCupdated( uint256 indexed oldER, uint256 indexed newER, uint256 timestamp, address sender ) ``` You will see that some of the emitted parameters are indexed and some are not. Indexed parameters, also called `topics`, are much more easy to search than non-indexed ones. For an event to be logged we need to emit it. Let's come back to our `Raffle` contract where we'll also learn how to emit them. First, we define the event (be mindful of where the events should go in terms of our defined layout) ```solidity event EnteredRaffle(address indexed player); ``` Then, we emit it in `enterRaffle`: ```solidity function enterRaffle() external payable { if(msg.value < i_entranceFee) revert Raffle__NotEnoughEthSent(); s_players.push(payable(msg.sender)); emit EnteredRaffle(msg.sender); } ``` Great! I know there is a possibility you don't quite understand the importance/usage of this event, but don't worry, we'll get back to it in the testing section. But before that, let's discuss randomness.
Follow along with this video:
Ok, our user paid the entrance fee, but how do we track his registration? We can't simply take the money and run! We need a storage structure that keeps track of all registered users from where to pick the winner.
Take a moment and decide what would be the best from the following:
Mapping
Array
A bunch of address variables and limit the number of participants
.
.
.
Congratulations if you chose the Array option! To be more specific, a dynamic array that grows in size with each new participant. Mappings can't be looped through, and a bunch of address variables is not feasible.
Add the array below the i_entranceFee
declaration: address payable[] private s_players;
We've made it address payable
because one of the participants registered in this array will be paid the ETH prize, hence the need for the payable
attribute.
Back in the enterRaffle
function, we need to add the address that paid into the s_players
array:
The .push
method is used to append an element to an array, increasing its length by 1.
s_players.push(payable(msg.sender));
performs a modification of the state by adding the payable address msg.sender
in the array. It is customary to emit an event every time we perform a state modification.
Events are a way for smart contracts to communicate with the outside world, primarily with the front-end applications that interact with these contracts. Events are logs that the Ethereum Virtual Machine (EVM) stores in a special data structure known as the blockchain log. These logs can be efficiently accessed and filtered by external applications, such as dApps (decentralized applications) or off-chain services. The logs can also be accessed from the blockchain nodes. Each emitted event is tied up to the smart contract that emitted it.
Please click here to find out more about events.
How can we use events?
Imagine we have a more complex function that changes an important parameter, let's say we are recording the exchange rate of BTC/USDC. We change it by calling the function changeER()
. After we perform the call and the exchange rate is changed we need to make sure this also gets picked up by our front-end. We make the front-end listen for the BTCUSDCupdated
event. An example of that event could be this:
You will see that some of the emitted parameters are indexed and some are not. Indexed parameters, also called topics
, are much more easy to search than non-indexed ones.
For an event to be logged we need to emit it.
Let's come back to our Raffle
contract where we'll also learn how to emit them.
First, we define the event (be mindful of where the events should go in terms of our defined layout)
Then, we emit it in enterRaffle
:
Great! I know there is a possibility you don't quite understand the importance/usage of this event, but don't worry, we'll get back to it in the testing section.
But before that, let's discuss randomness.
A state-managing guide to Tracking Raffle Players and Introducing Solidity Events - Learn to track raffle participants by storing player addresses in a `payable` array within your Solidity contract. Understand and implement Solidity events to signal state changes efficiently for off-chain applications and front-ends.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
Foundryup, Foundry Forge, and Anvil
Blockchain Oracles
How to create local Blockchain testnets
How to verify a smart contract
How to write and run smart contract tests
Security researcher
$49,999 - $120,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Guest lecturers:
Last updated on June 10, 2025
Duration: 2h 55min
Duration: 2h 56min
Duration: 26min
Duration: 5h 22min
Course Overview
About the course
Foundryup, Foundry Forge, and Anvil
Blockchain Oracles
How to create local Blockchain testnets
How to verify a smart contract
How to write and run smart contract tests
Security researcher
$49,999 - $120,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Guest lecturers:
Last updated on June 10, 2025