<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Charles Jones</title>
    <description>The latest articles on Forem by Charles Jones (@charlesj_dev).</description>
    <link>https://forem.com/charlesj_dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1610023%2F193cc693-0ac2-456a-b22c-5e75249fb753.jpg</url>
      <title>Forem: Charles Jones</title>
      <link>https://forem.com/charlesj_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/charlesj_dev"/>
    <language>en</language>
    <item>
      <title>Building Randomness with Chainlink VRF: Part 2</title>
      <dc:creator>Charles Jones</dc:creator>
      <pubDate>Sun, 16 Jun 2024 13:47:45 +0000</pubDate>
      <link>https://forem.com/charlesj_dev/building-randomness-with-chainlink-vrf-part-2-1aff</link>
      <guid>https://forem.com/charlesj_dev/building-randomness-with-chainlink-vrf-part-2-1aff</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1q02ozne7erxiep23q1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1q02ozne7erxiep23q1.png" alt="Image description" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“In the game of innovation, like in sports, every function plays a crucial role; it’s not just about having star players, but how every part works together seamlessly.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Welcome to the digital arena, where the players are smart contracts, and the game is as strategic as any sport you’ve ever seen. Today, we’re diving into the playbook (functions) of our MVP, RandomTeamSelector.sol, dissecting its moves and strategies to understand how it scores points in the blockchain league. If you missed &lt;a href="https://charliej.hashnode.dev/building-randomness-with-chainlink-vrf-1"&gt;part 1, you can read it here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine a football coach picking players for a dream team, but instead of athletes, we’re drafting functions, each with a unique role that contributes to the victory of our smart contract. From the kickoff with &lt;code&gt;requestRandomTeamNames&lt;/code&gt;to the final whistle with &lt;code&gt;chooseTeam&lt;/code&gt;, we’ll explore how each function interacts, strategizes, and executes plays that would make even the most seasoned sports analysts take notes.&lt;/p&gt;

&lt;p&gt;So, lace up your cleats, don your jerseys, and let’s get ready to rumble through the code, play by play, ensuring you understand the Xs and Os of our smart contract’s game plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Draft Pick: Initiating the Random Team Selection
&lt;/h2&gt;

&lt;p&gt;In the grand league of smart contracts, the &lt;code&gt;requestRandomTeamNames&lt;/code&gt;function is the first-round draft pick, setting the stage for a fair and unpredictable selection process. It’s the crucial coin toss, the unbiased referee, ensuring that every team manager gets a shot at glory in the blockchain championship.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s the play-by-play:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Positioning the Players: The function takes an address manager as its input, which is akin to selecting the team manager who’s calling the shots.&lt;/p&gt;

&lt;p&gt;Checking the Field: It checks if the manager has already made a team selection. If so, it throws a flag on the play with &lt;code&gt;RandomTeamSelector__AlreadySelected()&lt;/code&gt;, stopping the action right there.&lt;/p&gt;

&lt;p&gt;The Kickoff: If the coast is clear, it makes a call to &lt;code&gt;s_vrfCoordinator.requestRandomWords&lt;/code&gt;, which is like passing the ball to the referee (the VRF Coordinator) to ensure a fair and random kickoff.&lt;/p&gt;

&lt;p&gt;Setting the Strategy: The function sets up the request for random words with specific parameters like keyHash, subId, and callbackGasLimit, ensuring the play adheres to the game rules.&lt;/p&gt;

&lt;p&gt;Executing the Play: Once the request is made, it records the requestId and associates it with the manager, marking the selection as ongoing with &lt;code&gt;SELECTION_ONGOING&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Celebrating the Move: Finally, it announces the play to the spectators (other contracts and listeners) with the &lt;code&gt;SelectionMade&lt;/code&gt;event.&lt;/p&gt;

&lt;p&gt;Let’s break down each line of the requestRandomTeamNames function for clarity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function requestRandomTeamNames(
    address manager
) public onlyOwner returns (uint256 requestId) {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line declares the function &lt;code&gt;requestRandomTeamNames&lt;/code&gt;, which takes one parameter: the address of the manager. It’s a public function, meaning it can be called by anyone, but with the &lt;code&gt;onlyOwner&lt;/code&gt;modifier, it restricts access so only the contract owner can execute it. The function is set to return a uint256 variable named &lt;code&gt;requestId&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (s_managerSelections[manager].teamOptions.length &amp;gt; 0) {
        revert RandomTeamSelector__AlreadySelected();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we’re checking if the manager has already selected a team. If the &lt;code&gt;teamOptions&lt;/code&gt;array for this manager is not empty (length &amp;gt; 0), the function will stop and revert the transaction with a custom error &lt;code&gt;RandomTeamSelector__AlreadySelected&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;requestId = s_vrfCoordinator.requestRandomWords(
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line assigns a new &lt;code&gt;requestId&lt;/code&gt;by calling the &lt;code&gt;requestRandomWords&lt;/code&gt;function from the &lt;code&gt;s_vrfCoordinator&lt;/code&gt;, which is a reference to a Chainlink VRF Coordinator contract that provides secure and verifiable randomness. More specifically, you can see the &lt;code&gt;requestRandomWords&lt;/code&gt;function directly in VRFCoordinatorV2.5.sol . It's in the lib folder&lt;/p&gt;

&lt;p&gt;/lib/chainlink/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VRFV2PlusClient.RandomWordsRequest({
            keyHash: s_keyHash,
            subId: s_subscriptionId,
            requestConfirmations: requestConfirmations,
            callbackGasLimit: callbackGasLimit,
            numWords: numWords,
            extraArgs: VRFV2PlusClient._argsToBytes(
                VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
            )
        })
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This section is constructing a &lt;code&gt;RandomWordsRequest&lt;/code&gt;struct with various parameters:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;keyHash&lt;/code&gt;: A unique identifier for the VRF key against which randomness is requested.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;subId&lt;/code&gt;: The subscription ID for billing purposes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;requestConfirmations&lt;/code&gt;: The number of confirmations the VRF Coordinator requires before responding.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;callbackGasLimit&lt;/code&gt;: The maximum amount of gas to use for the callback.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;numWords&lt;/code&gt;: The number of random words requested.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;extraArgs&lt;/code&gt;: Additional arguments, here converted to bytes, indicating no native token payment is required with this request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;s_requestToManager[requestId] = manager;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line maps the &lt;code&gt;requestId&lt;/code&gt;to the manager’s address, storing the association in a state variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;s_managerSelections[manager].selectedTeam = SELECTION_ONGOING;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the function sets the &lt;code&gt;selectedTeam&lt;/code&gt;status to &lt;code&gt;SELECTION_ONGOING&lt;/code&gt; for the manager, indicating that the selection process is currently underway.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;emit SelectionMade(requestId, manager);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the function emits an event &lt;code&gt;SelectionMade&lt;/code&gt;with the &lt;code&gt;requestId&lt;/code&gt;and manager’s address, signaling to the blockchain that a selection process has been initiated.&lt;/p&gt;

&lt;p&gt;This function sets up the initial request for randomness, which is the first step in the process of selecting a random team. It ensures that the selection is fair and hasn’t been tampered with by using a verifiable source of randomness.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Playmaker: fulfillRandomWords Function
&lt;/h2&gt;

&lt;p&gt;In the playbook of our smart contract, the &lt;code&gt;fulfillRandomWords&lt;/code&gt;function is the playmaker, the one who receives the pass (randomness) and makes the strategic moves (assigns team options). Here’s how it orchestrates the play:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Receiving the Pass&lt;/strong&gt;: The function is triggered by a callback from the VRF Coordinator, carrying the &lt;code&gt;requestId&lt;/code&gt;and an array of &lt;code&gt;randomWords&lt;/code&gt;—the unpredictable elements that keep the game fair.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting Up the Play&lt;/strong&gt;: It retrieves the manager’s address associated with the &lt;code&gt;requestId&lt;/code&gt;and prepares an array &lt;code&gt;teamOptions&lt;/code&gt;to hold the potential team picks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Executing the Strategy&lt;/strong&gt;: A loop runs through the &lt;code&gt;randomWords&lt;/code&gt;, using modulo arithmetic to ensure the team options fall within a specified range (in this case, 1 to 40), representing the pool of available teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recording the Stats&lt;/strong&gt;: The manager’s selection is updated with these new team options, and the &lt;code&gt;selectedTeam&lt;/code&gt;status is set to SELECTION_ONGOING, indicating the play is in progress.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Announcing the Outcome&lt;/strong&gt;: Finally, the &lt;code&gt;SelectionRevealed&lt;/code&gt;event is emitted, broadcasting the manager’s team options to all participants.&lt;/p&gt;

&lt;p&gt;This function is the core of the selection process, taking the randomness provided by the VRF and translating it into actionable choices for the manager. It’s the moment when the crowd holds its breath as the playmaker weaves through the opposition, setting up for a score.&lt;/p&gt;

&lt;p&gt;Let's take a deeper look at the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function fulfillRandomWords(
    uint256 requestId,
    uint256[] calldata randomWords
) internal override {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function is an internal callback that is called by the VRF Coordinator when randomness is delivered. It overrides a function from the inherited VRFConsumerBaseV2Plus contract. The parameters are the ID of the request for randomness and the array of random numbers provided by the VRF.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; address manager = s_requestToManager[requestId];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line retrieves the manager’s address that is associated with the given &lt;code&gt;requestId&lt;/code&gt;from a mapping called &lt;code&gt;s_requestToManager&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint256[] memory teamOptions = new uint256;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, a new temporary array called &lt;code&gt;teamOptions&lt;/code&gt;is created in memory to store the team IDs that will be generated from the random words.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for (uint256 i = 0; i &amp;lt; numWords; i++) {
        teamOptions[i] = (randomWords[i] % 40) + 1;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This loop goes through each of the random numbers provided, uses modulo operation to ensure each number is within the range of 1 to 40, and assigns the result to the &lt;code&gt;teamOptions&lt;/code&gt;array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; s_managerSelections[manager] = ManagerSelection({
        teamOptions: teamOptions,
        selectedTeam: SELECTION_ONGOING
    });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;s_managerSelections&lt;/code&gt;mapping is updated for the manager with a new &lt;code&gt;ManagerSelection&lt;/code&gt;struct, which includes the &lt;code&gt;teamOptions&lt;/code&gt;array and sets the &lt;code&gt;selectedTeam&lt;/code&gt;status to &lt;code&gt;SELECTION_ONGOING&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;emit SelectionRevealed(requestId, teamOptions);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the &lt;code&gt;SelectionRevealed&lt;/code&gt;event is emitted, which includes the &lt;code&gt;requestId&lt;/code&gt;and the &lt;code&gt;teamOptions&lt;/code&gt; array, indicating that the selection options have been successfully generated and revealed.&lt;/p&gt;

&lt;p&gt;Let’s proceed with the next function, teamName, which retrieves the name of the team chosen by a player.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Selector: teamName Function
&lt;/h2&gt;

&lt;p&gt;In the arena of our smart contract, the &lt;code&gt;teamName&lt;/code&gt;function is like the referee announcing the chosen player to the eager crowd. It’s the moment of truth where the selection is revealed and the anticipation turns into reality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Play by Play:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Announcement&lt;/strong&gt;: This function is called upon to reveal the chosen team’s name, much like a referee would announce the selected player.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Verification&lt;/strong&gt;: Before the reveal, it ensures that a selection has indeed been made, akin to checking the roster before making the call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Reveal&lt;/strong&gt;: Once confirmed, it retrieves and announces the team’s name, finalizing the player’s choice in the draft.&lt;/p&gt;

&lt;p&gt;Line by Line Code Breakdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function teamName(address player) public view returns (string memory) {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line declares the function &lt;code&gt;teamName&lt;/code&gt;, which is a public function that anyone can call. It’s a view function, meaning it doesn’t modify the state on the blockchain. It takes one parameter, the address of the player, and returns a string representing the name of the team.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ManagerSelection storage selection = s_managerSelections[player];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the function retrieves the &lt;code&gt;ManagerSelection&lt;/code&gt;struct from the &lt;code&gt;s_managerSelections&lt;/code&gt;mapping for the given player address and stores it in a local variable selection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (selection.selectedTeam == 0) {
        revert RandomTeamSelector__SelectionNotMade();
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line checks if the &lt;code&gt;selectedTeam&lt;/code&gt;property of the selection is 0, which would indicate that no selection has been made. If that’s the case, it reverts the transaction with a custom error &lt;code&gt;RandomTeamSelector__SelectionNotMade&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return getTeamName(selection.selectedTeam);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the function returns the name of the selected team by calling another function &lt;code&gt;getTeamName&lt;/code&gt;and passing the &lt;code&gt;selectedTeam&lt;/code&gt;ID from the selection.&lt;/p&gt;

&lt;p&gt;Moving on to the next function, let’s explore &lt;code&gt;getTeamOptions&lt;/code&gt;, which retrieves all the team options available for a manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Strategist: getTeamOptions Function
&lt;/h2&gt;

&lt;p&gt;In the tactical game of our smart contract, the &lt;code&gt;getTeamOptions&lt;/code&gt;function is akin to a coach reviewing the playbook. It’s where the manager surveys all possible moves before making the crucial decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Play by Play:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Surveying the Field&lt;/strong&gt;: This function allows the manager to look at all the potential team options at their disposal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ensuring Fair Play&lt;/strong&gt;: It checks to make sure the selection process is still ongoing, akin to verifying that the game hasn’t ended before making a move.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revealing the Options&lt;/strong&gt;: Once confirmed, it presents the array of team IDs, laying out all the possible strategies for the manager to consider.&lt;/p&gt;

&lt;p&gt;Line by Line Code Breakdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getTeamOptions(
    address manager
) public view returns (uint256[] memory) {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line declares the function &lt;code&gt;getTeamOptions&lt;/code&gt;, which is publicly accessible and doesn’t alter the state on the blockchain. It takes the manager’s address as a parameter and returns an array of unsigned integers, which represent the team IDs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ManagerSelection storage selection = s_managerSelections[manager];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the function retrieves the &lt;code&gt;ManagerSelection&lt;/code&gt;struct associated with the manager’s address from the &lt;code&gt;s_managerSelections&lt;/code&gt;mapping.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (selection.selectedTeam != SELECTION_ONGOING) {
        revert RandomTeamSelector__NoSelectionOptionsAvailable();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line checks if the selection process is not ongoing (meaning either not started or already completed). If so, it reverts the transaction with the error &lt;code&gt;RandomTeamSelector__NoSelectionOptionsAvailable&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; return selection.teamOptions;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the function returns the &lt;code&gt;teamOptions&lt;/code&gt;array from the selection, which contains the IDs of the available teams.&lt;/p&gt;

&lt;p&gt;Let’s move on to the &lt;code&gt;chooseTeam&lt;/code&gt;function, which allows a manager to finalize their team selection.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Decision Maker: chooseTeam Function
&lt;/h2&gt;

&lt;p&gt;In the strategic game of our smart contract, the chooseTeam function is like the final whistle that seals the fate of the match. It’s where the manager makes the definitive call, locking in their team choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Play by Play:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Final Call: This function is the decisive moment where the manager selects their team from the available options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ensuring the Rules Are Followed&lt;/strong&gt;: It verifies that the selection process is ongoing and that the chosen team is a valid option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Locking in the Choice&lt;/strong&gt;: Once the checks are passed, it finalizes the manager’s team selection, much like a coach submitting the final lineup.&lt;/p&gt;

&lt;p&gt;Line by Line Code Breakdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function chooseTeam(uint256 teamId) public {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line declares the function &lt;code&gt;chooseTeam&lt;/code&gt;, which is a public function that allows managers to choose a team. It takes one parameter, &lt;code&gt;teamId&lt;/code&gt;, which is the ID of the team being chosen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ManagerSelection storage selection = s_managerSelections[msg.sender];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the function retrieves the &lt;code&gt;ManagerSelection&lt;/code&gt;struct for the manager calling the function (indicated by &lt;code&gt;msg.sender&lt;/code&gt;) from the &lt;code&gt;s_managerSelections&lt;/code&gt;mapping.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; require(
        selection.selectedTeam == SELECTION_ONGOING,
        "Selection process not ongoing or already completed."
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line checks that the selection process is currently ongoing for the manager. If not, it will revert the transaction with an error message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bool validChoice = false;
    for (uint256 i = 0; i &amp;lt; selection.teamOptions.length; i++) {
        if (selection.teamOptions[i] == teamId) {
            validChoice = true;
            break;
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function then iterates through the &lt;code&gt;teamOptions&lt;/code&gt;array to check if the &lt;code&gt;teamId&lt;/code&gt;provided is a valid option. If it finds a match, it sets &lt;code&gt;validChoice&lt;/code&gt;to true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (!validChoice) {
        revert RandomTeamSelector__InvalidTeamChoice();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no valid option is found (&lt;code&gt;validChoice&lt;/code&gt;remains false), the function reverts the transaction with the error &lt;code&gt;RandomTeamSelector__InvalidTeamChoice&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;selection.selectedTeam = teamId;
    emit TeamChosen(msg.sender, teamId);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once a valid choice is confirmed, the function sets the &lt;code&gt;selectedTeam&lt;/code&gt;to the chosen &lt;code&gt;teamId&lt;/code&gt;and emits the &lt;code&gt;TeamChosen&lt;/code&gt;event, indicating that the manager has made their selection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smart Contract Function Flow Summary
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;RandomTeamSelector.sol&lt;/code&gt; smart contract orchestrates a series of functions to manage the process of random team selection. Here’s a summary of the flow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialization&lt;/strong&gt;: The contract begins with the &lt;code&gt;requestRandomTeamNames&lt;/code&gt;function, where the owner initiates the random selection process for a manager. This function checks if the manager has already made a selection and, if not, requests randomness from the VRF Coordinator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Randomness Fulfillment&lt;/strong&gt;: Upon receiving randomness from the VRF Coordinator, the &lt;code&gt;fulfillRandomWords&lt;/code&gt;callback function is triggered. It processes the random words to generate team options and updates the manager’s selection status to ongoing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Team Selection&lt;/strong&gt;: Managers can then call the &lt;code&gt;teamName&lt;/code&gt;function to retrieve the name of the team that has been selected for them, provided that the selection has been made.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reviewing Options&lt;/strong&gt;: Before making a selection, managers can review their available team options using the &lt;code&gt;getTeamOptions&lt;/code&gt;function, which returns an array of team IDs that are still in the running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finalizing Selection&lt;/strong&gt;: Finally, the &lt;code&gt;chooseTeam&lt;/code&gt;function allows managers to select their team from the provided options. It ensures the choice is valid and updates the manager’s selection, concluding the process.&lt;/p&gt;

&lt;p&gt;Each function plays a critical role in ensuring the integrity and fairness of the random team selection process within the smart contract environment. The functions work together to manage the selection from initiation to finalization, providing transparency and control to the contract owner and participating managers.&lt;/p&gt;

&lt;p&gt;And this is where I stand right now on the project. I know that I'll have to do some refactoring with some of these functions, but I'll likely leave that until after I write some tests and possibly after some interaction with a front-end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/SupaMega24/fantasy-team-vrf"&gt;The code lives here.&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building Randomness with Chainlink VRF</title>
      <dc:creator>Charles Jones</dc:creator>
      <pubDate>Tue, 11 Jun 2024 14:23:59 +0000</pubDate>
      <link>https://forem.com/charlesj_dev/building-randomness-with-chainlink-vrf-50ki</link>
      <guid>https://forem.com/charlesj_dev/building-randomness-with-chainlink-vrf-50ki</guid>
      <description>&lt;h2&gt;
  
  
  Random Fantasy Team Name Selector Part 1
&lt;/h2&gt;

&lt;p&gt;Imagine a lottery where the balls are tumbling in a glass sphere, watched by the world. Each number is a smart contract, each draw a transaction, and the entire network stands witness to the spectacle. This isn’t just a game of chance; it’s a demonstration of trust in technology, a showcase of fairness in play&lt;/p&gt;

&lt;p&gt;The Random Fantasy Team Name Selector does not merely pick a name; it orchestrates a symphony of unpredictability, with each note struck by the hammer of cryptographic algorithms. It’s a modern-day oracle, delivering prophecies of randomness that are transparent, tamper-proof, and fair.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this series of posts, we will dive into creating a decentralized application using Solidity, the programming language for writing smart contracts on the Ethereum blockchain. Our project currently consists of two main contracts: RandomTeamSelector and TeamNames. Both of these contracts leverage Chainlink's Verifiable Random Function (VRF) to ensure secure and verifiable randomness, essential for fair and unpredictable outcomes in our application.&lt;/p&gt;

&lt;p&gt;The RandomTeamSelector contract is designed to randomly assign team names to participants using names commonly associate with mythical and fantasy creatures. Using Chainlink VRF, this contract can request random values that are used to select from a predefined list of team names. The TeamNames contract holds the list of possible team names and provides a function to retrieve a name based on an index.&lt;/p&gt;

&lt;p&gt;Chainlink VRF is a reliable source of randomness for smart contracts. It provides cryptographic proof that the random values generated are tamper-proof and verifiably fair. By integrating Chainlink VRF into our Solidity contracts, we ensure that our random team selections are unbiased and transparent.&lt;/p&gt;

&lt;p&gt;So, join us as we embark on this journey through the mechanics of the Random Fantasy Team Name Selector, exploring how it harnesses the power of Chainlink VRF to bring verifiable randomness to the blockchain. It’s a story of innovation, a dance of algorithms, and a testament to the ingenuity of decentralized solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Forge of Creation: Setting the Stage for Smart Contract Development
&lt;/h2&gt;

&lt;p&gt;Before we delve deeper into the intricacies of our Random Team Selector smart contract, let’s take a moment to acknowledge the anvil upon which it was forged. In the modern alchemy of smart contract development, the tools we choose are as crucial as the spells we cast. For this project, we’ve chosen a tool that’s as robust as it is refined: Foundry’s forge.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;forge init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a simple forge init, we breathed life into our project, creating a structured environment where our smart contract could take shape. Foundry’s suite of tools offers a streamlined workflow for smart contract development, testing, and deployment, ensuring that our code is not only functional but also battle-tested.&lt;/p&gt;

&lt;p&gt;And when it came time to provide our contract with the power of randomness, we turned to the repositories of Chainlink contracts. With forge install, we summoned the Chainlink contracts into our project, each one a building block in the architecture of our application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;forge install smartcontractkit/chainlink --no-commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command is the digital equivalent of drawing water from the well of knowledge, bringing into our midst the Chainlink VRF contracts that would become the cornerstone of our Random Team Selector.&lt;/p&gt;

&lt;p&gt;NOTE: Don't forget your remappings!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[solidity]
remappings = [
    "@chainlink/contracts/=lib/chainlink/contracts"
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This update to your foundry.toml file sets the remappings for the Chainlink contracts within your Foundry project. It tells Foundry that whenever it encounters an import statement with @chainlink/contracts/, it should look in the lib/chainlink/contracts directory of your project. This is essential for ensuring that your Solidity files can correctly locate and import the Chainlink contract dependencies.&lt;/p&gt;

&lt;p&gt;With this configuration in place, you’re ensuring that your development environment is aware of where to find the Chainlink contracts, allowing your smart contract to seamlessly integrate with Chainlink’s VRF functionality.&lt;/p&gt;

&lt;p&gt;So, as we stand at the threshold of creation, let’s take a moment to appreciate the tools that make it all possible. Foundry’s forge is more than just a development environment; it’s a crucible where ideas are transformed into reality, where code becomes more than just instructions—it becomes a gateway to new worlds of possibility.&lt;/p&gt;

&lt;p&gt;Now, with our stage set and our tools at the ready, let’s continue our journey into the heart of the Random Team Selector smart contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Alchemy of Imports: Weaving the Magic of Randomness
&lt;/h2&gt;

&lt;p&gt;In the realm of Solidity, the import statement is akin to the summoning of allies, each bringing their unique powers to enhance our smart contract’s capabilities. In the case of our project, three such imports lay the foundation for its functionality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
import {TeamNames} from "./TeamNames.sol";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firstly, we invoke VRFConsumerBaseV2Plus, a contract from the hallowed libraries of Chainlink. This contract is the bedrock upon which we build our trust in randomness. It’s the guardian that interacts with the Chainlink VRF, ensuring that the randomness we receive is not just a roll of the dice but a cryptographically secure and verifiable act of chance.&lt;/p&gt;

&lt;p&gt;Next, we call upon VRFV2PlusClient, a library that serves as our conduit to the Chainlink VRF. It’s the spellbook containing the incantations needed to request and receive verifiable random numbers. This library simplifies the interaction with Chainlink VRF, abstracting the complexity of blockchain oracles into a few lines of Solidity code.&lt;/p&gt;

&lt;p&gt;Lastly, TeamNames emerges from our own domain, a contract that holds the essence of our application—the team names. It’s the treasure chest where the potential outcomes of our random selection are stored, waiting to be matched with the random numbers provided by the Chainlink oracle.&lt;/p&gt;

&lt;p&gt;Together, these imports form a trio of trust, randomness, and data, as a powerful digital alliance. They are the first step in our contract’s journey, the initial incantation in the spell that will bring forth the Random Fantasy Team Name Selector into existence.&lt;/p&gt;

&lt;p&gt;So, let us continue to weave this spell, line by line, until our smart contract stands complete, ready to bring the fair and exciting game of chance to all who dare to partake in its randomness.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Heart of the Contract: The Random Team Selector
&lt;/h2&gt;

&lt;p&gt;In the symphony of Solidity, the contract declaration is the opening note, the defining statement that brings our smart contract to life. For the Random Fantasy Team Name Selector, this declaration is the beginning of its existence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract RandomTeamSelector is VRFConsumerBaseV2Plus, TeamNames {
    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we declare that our RandomTeamSelector is not just any contract; it’s one that inherits from VRFConsumerBaseV2Plus and TeamNames. This inheritance is akin to a knight donning two powerful artifacts: one that grants the power of randomness and another that holds the wisdom of team names.&lt;/p&gt;

&lt;p&gt;But every knight needs an origin, a beginning to their quest. This is where the constructor comes into play:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(uint256 subscriptionId) VRFConsumerBaseV2Plus(vrfCoordinator) {
    s_subscriptionId = subscriptionId;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constructor is the sacred ritual that breathes life into our contract. It takes a subscriptionId—a talisman that connects us to the Chainlink VRF service—and binds it to our contract’s soul. This subscriptionId is the key to the oracle’s gate, allowing us to request randomness from the Chainlink network. You can get your own ID here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vrf.chain.link/"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbv5hq6j6zcexzg5h0ts4.png" alt="Image description" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By passing the vrfCoordinator to the VRFConsumerBaseV2Plus constructor, we establish a link to the Chainlink node that will serve as our intermediary to the oracle. It’s like setting the coordinates for a starship, ensuring that we can navigate the cosmos of randomness with precision.&lt;/p&gt;

&lt;p&gt;With these lines of code, the Random Fantasy Team Name Selector is no longer just an idea; it becomes a living entity within the blockchain, ready to embark on its mission to bring verifiable randomness to the world.&lt;/p&gt;

&lt;p&gt;In the coming sections, we’ll go over the building blocks that give power to our functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crafting the Core: Errors, State Variables, and Events
&lt;/h2&gt;

&lt;p&gt;As we delve into the heart of the our smart contract, we encounter the elements that give it structure and purpose. Like the rules of a board game, these components define how the game is played, what moves are allowed, and what happens when things go awry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom Errors: The Guardians of Order&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the Solidity realm, errors are the sentinels that guard the gates of functions, ensuring that only those who meet the criteria may pass:&lt;/p&gt;

&lt;p&gt;Errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error RandomTeamSelector__AlreadySelected();
error RandomTeamSelector__NoSelectionOptionsAvailable();
error RandomTeamSelector__SelectionNotMade();
error RandomTeamSelector__InvalidTeamChoice();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;RandomTeamSelector__AlreadySelected&lt;/code&gt;: This error is a stern warning that a selection has already been made, barring any attempts to alter fate.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RandomTeamSelector__NoSelectionOptionsAvailable&lt;/code&gt;: A reminder that one cannot choose from an empty list, this error appears when there are no options to select.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RandomTeamSelector__SelectionNotMade&lt;/code&gt;: This error emerges when someone seeks a result before the die has been cast.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RandomTeamSelector__InvalidTeamChoice&lt;/code&gt;: The final guardian, this error rejects any choice that strays from the path of available options.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;State Variables: The Pillars of Memory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;State variables are the pillars upon which the contract’s memory is built, each holding a piece of information that defines the contract’s state:&lt;/p&gt;

&lt;p&gt;State Variables:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE: Yes, I know they are hard coded. I will remedy this in part 3 :)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint256 private constant SELECTION_ONGOING = 24;
uint256 public s_subscriptionId;
address public vrfCoordinator = 0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B;
bytes32 public s_keyHash = 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae;
uint32 public callbackGasLimit = 300000;
uint16 public requestConfirmations = 3;
uint32 public numWords = 3;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SELECTION_ONGOING&lt;/code&gt;: An arbitrary constant that signifies the ongoing process of selection, like a flag raised high during a tournament.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;s_subscriptionId&lt;/code&gt;: The subscription ID for the Chainlink VRF service, akin to a membership card granting access to the oracle’s wisdom.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vrfCoordinator&lt;/code&gt;: The address of the Chainlink VRF Coordinator, serving as the contract’s liaison to the oracle network.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;s_keyHash&lt;/code&gt;: A unique identifier for the gas lane, guiding the contract’s requests through the network’s thoroughfares.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;callbackGasLimit&lt;/code&gt;: The breath of the oracle, the amount of computational effort allocated to process the callback of the random number request.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;requestConfirmations&lt;/code&gt;: The number of confirmations the network must reach before the oracle considers the request fulfilled.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;numWords&lt;/code&gt;: The chorus of the contract, the number of random values requested from the oracle. Our contract calls for a trio, 3, allowing the manager to choose from three fates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Curiosity Question: How do you know what state variables to use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, in this case I just looked at the documentation on Chainlink. However, we can dig a bit further. By analyzing the contract’s requirements in terms of data storage, access, cost, logic, and security, a developer can identify the appropriate state variables to use.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Contract Purpose&lt;/strong&gt;: Understand the core objective of the contract. Is it for token management, decentralized finance (DeFi), gaming, or something else? The purpose dictates the data needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Requirements&lt;/strong&gt;: Identify what data is essential for the contract to operate. For example, a token contract needs variables for total supply, balances, allowances, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Functionality&lt;/strong&gt;: Consider the functions the contract will perform. Each function may require specific data to execute its logic, which influences the state variables needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactions&lt;/strong&gt;: Think about how users and other contracts will interact with your contract. Variables might be needed to track ownership, permissions, or interaction history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security and Access Control&lt;/strong&gt;: Determine what access controls are necessary. State variables can help manage roles, permissions, and restrictions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upgradeability&lt;/strong&gt;: If the contract might need upgrades, consider state variables that facilitate this, such as addresses pointing to implementation contracts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency and Gas Costs&lt;/strong&gt;: Be mindful of storage costs on blockchain platforms like Ethereum. Efficiently structured state variables can reduce gas fees.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance and Regulations&lt;/strong&gt;: Depending on the jurisdiction and nature of the contract, certain compliance-related variables might be necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Practices and Standards&lt;/strong&gt;: Follow established patterns and standards in the blockchain domain, such as ERC standards for tokens, which prescribe certain state variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing and Simulation&lt;/strong&gt;: Before finalizing, simulate various scenarios to ensure all necessary state variables are included and functioning as expected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Structs and Mappings: The Ledger of Choices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ManagerSelection&lt;/code&gt; struct and associated mappings are the ledger where choices are recorded, a logbook that keeps track of each manager’s journey through the selection process:&lt;/p&gt;

&lt;p&gt;Struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ManagerSelection {
    uint256[] teamOptions;
    uint256 selectedTeam;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The struct serves as a custom data type to encapsulate the selection process for each manager. It has two properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;teamOptions&lt;/code&gt;: This is an array of uint256 that stores the team IDs available for the manager to choose from. These IDs correspond to the random numbers generated by the Chainlink VRF and represent the different teams that the manager can select as their choice.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;selectedTeam&lt;/code&gt;: This is a uint256 value that represents the manager’s final choice. Once the manager selects a team from the teamOptions, this property is updated to reflect the chosen team ID. Initially, it is set to 0 to indicate that no selection has been made. When the selection process is ongoing, it is set to the constant SELECTION_ONGOING, and upon completion, it holds the ID of the selected team.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mappings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mapping(uint256 =&amp;gt; address) private s_requestToManager;
mapping(address =&amp;gt; ManagerSelection) private s_managerSelections;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Solidity, mappings are a key-value data structure that allows you to associate unique keys with corresponding values. Think of them as a collection of pairs, where each key is linked to one value.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;s_requestToManager&lt;/code&gt;: A mapping that associates VRF request IDs with managers’ addresses, like a guest list at an exclusive event.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;s_managerSelections&lt;/code&gt;: A mapping that stores each manager’s selection details, chronicling their decisions for posterity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Curiosity Question: Could you explain the structure of mappings?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The structure of a mapping is defined as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mapping(keyType =&amp;gt; valueType) visibilityModifier variableName;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;keyType&lt;/strong&gt;: This is the data type of the key. It can be any built-in type such as uint, address, or bytes32. Solidity requires keys to be of a type that is comparable, which means custom structs or arrays cannot be used as keys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;valueType&lt;/strong&gt;: This is the data type of the value that the key maps to. It can be any type, including another mapping or an array.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;visibilityModifier&lt;/strong&gt;: This defines who can access the mapping. It can be public, private, or internal. If it’s public, Solidity automatically creates a getter function for it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;variableName&lt;/strong&gt;: This is the name you give to the mapping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Curiosity Question: How do you know when to use mappings?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mappings are typically used when you need to associate unique keys with specific values and require efficient retrieval and updating of these values. Mappings are ideal in scenarios where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to track ownership or balances, such as in a token contract.&lt;/li&gt;
&lt;li&gt;You want to store user data and retrieve it using identifiers like addresses or IDs.&lt;/li&gt;
&lt;li&gt;You’re managing permissions or roles in a contract, associating addresses with their respective permissions.&lt;/li&gt;
&lt;li&gt;You need a way to store and look up data without iterating over an entire collection, which can be gas-intensive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Events: The Herald’s Call&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Events in Solidity are the herald’s call, announcing significant occurrences within the contract for all to hear:&lt;/p&gt;

&lt;p&gt;Events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;event SelectionMade(uint256 indexed requestId, address indexed manager);
event SelectionRevealed(uint256 indexed requestId, uint256[] teamValues);
event TeamChosen(address indexed manager, uint256 teamId);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SelectionMade&lt;/code&gt;: Proclaimed when the selection process begins, like the starting bell of a race.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SelectionRevealed&lt;/code&gt;: Announced when the random selection is unveiled, akin to the unveiling of a masterpiece.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TeamChosen&lt;/code&gt;: Declared when a manager makes their choice, marking the moment of commitment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Curiosity Question: What is the indexed keyword in the arguments?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Solidity, the indexed keyword in event arguments is used to enable these arguments to be searchable and filterable when looking through blockchain logs. When an argument is indexed, it creates a topic that logs can be indexed by, which allows for efficient querying. You can have up to three indexed arguments in an event.&lt;/p&gt;

&lt;p&gt;For example, in the SelectionMade event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;event SelectionMade(uint256 indexed requestId, address indexed manager);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;requestId&lt;/code&gt;is indexed so that you can filter events by specific request IDs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;manager&lt;/code&gt;is indexed to allow filtering by the manager’s address.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is particularly useful for front-end applications that need to display specific information to users, such as all events related to a particular manager or a specific request. By indexing these arguments, the application can quickly retrieve relevant events without having to process every single event log on the blockchain.&lt;/p&gt;

&lt;p&gt;Collectively, the elements in this section form the backbone of the Random Fantasy Team Name Selector. They are the rules of engagement, the memory of the contract, and the voice that announces its actions. As we continue to explore the contract, we’ll see these elements in action, orchestrating the dance of randomness and choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Phew! We've covered a lot so far on our journey. We looked at how the project is set up in Foundry using forge init and how chainlink contracts were installed using forge install (although their documentation has an alternative to this). We covered the imports and how the contract is set up with it's core elements such as state variables, mappings, and events. Their were also a few curious questions along the way for those of us, like me, who need a bit more understanding about how things work.&lt;/p&gt;

&lt;p&gt;Thank you for reading! Here is what to expect with the rest of the series.&lt;/p&gt;

&lt;p&gt;Part 2: In-depth explanation of our functions&lt;/p&gt;

&lt;p&gt;Part 3: Proxy contract and makefile&lt;/p&gt;

&lt;p&gt;Part 4: Foundry unit tests&lt;/p&gt;

&lt;p&gt;Part 5: Fantasy Team NFTs&lt;/p&gt;

&lt;p&gt;Part 6: Deploy scripts&lt;/p&gt;

&lt;p&gt;Part 7: Front-end&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/SupaMega24/fantasy-team-vrf"&gt;The code lives here, on Github.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>tutorial</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
