Building a Blockchain Lottery DApp with QuickNode

Building a Blockchain Lottery DApp with QuickNode

Introduction

In this tutorial, we'll create a decentralized lottery application using QuickNode, a powerful blockchain infrastructure provider. Building a lottery application on the blockchain ensures fairness and transparency, as every participant can independently verify the results. We'll use Ethereum smart contracts and React for the frontend.

Prerequisites:

Before we begin, ensure you have the following:

  1. Node.js and npm (Node Package Manager) are installed on your computer.

  2. Basic knowledge of JavaScript and React (optional but helpful).

  3. A QuickNode account (sign up here if you don't have one).

  4. Familiarity with Ethereum and Web3.js (Learn more here).

Step 1: Set Up Your Development Environment

Create a new directory for your project and navigate to it in your terminal:

mkdir blockchain-lottery-dapp
cd blockchain-lottery-dapp

Initialize a new Node.js project:

npm init -y

Install the necessary dependencies:

npm install web3 solc

Step 2: Connect to QuickNode

To interact with the Ethereum blockchain, we'll use QuickNode's API. Sign in to your QuickNode account and obtain your API endpoint.

Create a file named web3.js in your project directory and add the following code:

const Web3 = require("web3");

const web3 = new Web3("<YOUR_QUICKNODE_API_ENDPOINT>");

module.exports = web3;

Replace <YOUR_QUICKNODE_API_ENDPOINT> with your QuickNode API endpoint.

Step 3: Create the Smart Contract

In this step, we'll create a simple Ethereum smart contract for our lottery application. Create a file named Lottery.sol in your project directory with the following content:

// Lottery.sol
pragma solidity ^0.8.0;

contract Lottery {
    address public manager;
    address[] public players;

    constructor() {
        manager = msg.sender;
    }

    function enter() public payable {
        require(msg.value > .01 ether, "Minimum contribution required.");

        players.push(msg.sender);
    }

    function random() private view returns (uint) {
        return uint(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players)));
    }

    function pickWinner() public restricted {
        uint index = random() % players.length;
        address winner = players[index];
        winner.transfer(address(this).balance);

        players = new address[](0);
    }

    modifier restricted() {
        require(msg.sender == manager, "Only the manager can call this function.");
        _;
    }

    function getPlayers() public view returns (address[] memory) {
        return players;
    }
}

This contract allows users to enter the lottery by sending Ether and allows the manager to pick a random winner.

Step 4: Compile and Deploy the Smart Contract

Next, we need to compile and deploy the smart contract. Create a file named deploy.js and add the following code:

// deploy.js
const Web3 = require("./web3");
const solc = require("solc");
const fs = require("fs");

const source = fs.readFileSync("Lottery.sol", "utf-8");
const compiledContract = solc.compile(source, 1);

const bytecode = compiledContract.contracts[":Lottery"].bytecode;
const abi = JSON.parse(compiledContract.contracts[":Lottery"].interface);

const deployContract = async () => {
    const accounts = await web3.eth.getAccounts();
    const gas = await web3.eth.estimateGas({ data: bytecode });

    const result = await new web3.eth.Contract(abi)
        .deploy({ data: bytecode })
        .send({ from: accounts[0], gas });

    console.log("Contract deployed to:", result.options.address);
};

deployContract();

This script compiles and deploys the Lottery smart contract to the Ethereum blockchain.

Step 5: Create the Frontend

We'll build a simple frontend using React to allow users to enter the lottery and check the list of participants.

Create a directory named src in your project and add the following files:

  • App.js

  • Lottery.js

Step 6: Implement the Lottery Interface

In the Lottery.js file, implement the lottery interface where users can enter the lottery and check the list of participants.

// Lottery.js
import React, { useState, useEffect } from "react";
import web3 from "./web3";

function Lottery() {
    const [amount, setAmount] = useState(0.01);
    const [message, setMessage] = useState("");
    const [players, setPlayers] = useState([]);
    const [manager, setManager] = useState("");
    const [balance, setBalance] = useState(0);

    useEffect(() => {
        const fetchContractInfo = async () => {
            const lotteryContract = new web3.eth.Contract(
                JSON.parse("<ABI_OF_DEPLOYED_CONTRACT>"),
                "<CONTRACT_ADDRESS>"
            );

            const players = await lotteryContract.methods.getPlayers().call();
            const manager = await lotteryContract.methods.manager().call();
            const balance = await web3.eth.getBalance("<CONTRACT_ADDRESS>");

            setPlayers(players);
            setManager(manager);
            setBalance(web3.utils.fromWei(balance, "ether"));
        };

        fetchContractInfo();
    }, []);

    const enterLottery = async () => {
        const accounts = await web3.eth.getAccounts();

        setMessage("Entering the lottery...");
        await new web3.eth.Contract(JSON.parse("<ABI_OF_DEPLOYED_CONTRACT>"), "<CONTRACT_ADDRESS>")
            .methods.enter()
            .send({
                from: accounts[0],
                value: web3.utils.toWei(amount.toString(), "ether"),
            });

        setMessage("Entered the lottery!");
    };

    const pickWinner = async () => {
        const accounts = await web3.eth.getAccounts();

        setMessage("Picking a winner...");
        await new web3.eth.Contract(JSON.parse("<ABI_OF_DEPLOYED_CONTRACT>"), "<CONTRACT_ADDRESS>")
            .methods.pickWinner()
            .send({
                from: accounts[0],
            });

        setMessage("A winner has been picked!");
    };

    return (
        <div>
            <h2>Blockchain Lottery</h2>
            <p>Manager: {manager}</p>
            <p>Current Balance: {balance} Ether</p>
            <p>Total Players: {players.length}</p>

            <div>
                <h3>Enter the Lottery</h3>
                <label>Amount (Ether):</label>
                <input
                    type="number"
                    step="0.01"
                    value={amount}
                    onChange={(e) => setAmount(e.target.value)}
                />
                <button onClick={enterLottery}>Enter</button>
            </div>

            <div>
                <h3>Pick a Winner</h3>
                <button onClick={pickWinner}>Pick Winner</button>
            </div>

            <h3>Participants</h3>
            <ul>
                {players.map((player, index) => (
                    <li key={index}>{player}</li>
                ))}
            </ul>

            <p>{message}</p>
        </div>
    );
}

export default Lottery;

Step 7: Display the Lottery Interface

In the App.js file, display the lottery interface component.

// App.js
import React from "react";
import "./App.css";
import Lottery from "./Lottery";

function App() {
    return (
        <div className="App">
            <h1>Blockchain Lottery Application</h1>
            <Lottery />
        </div>
    );
}

export default App;

Step 8: Run Your Blockchain Lottery DApp

To run your blockchain lottery DApp, execute the following commands:

npm start

Your DApp will be available at http://localhost:3000. Users can enter the lottery, check the list of participants, and pick a winner.

Conclusion

In this tutorial, you've learned how to create a blockchain-based lottery DApp using QuickNode, Ethereum, React, and Solidity. This application demonstrates the transparency and security benefits of blockchain technology in the context of a fair lottery. You can further enhance the DApp by adding features such as automated draws and user authentication. Happy coding!

I'd love to connect with you on Twitter | LinkedIn | Portfolio.

About QuickNode

QuickNode is building infrastructure to support the future of Web3. Since 2017, we've worked with hundreds of developers and companies, helping scale dApps and providing high-performance access to 24+ blockchains. Subscribe to our newsletter for more content like this, and stay in the loop with what's happening in Web3!‌