Table of contents
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:
Node.js and npm (Node Package Manager) are installed on your computer.
Basic knowledge of JavaScript and React (optional but helpful).
A QuickNode account (sign up here if you don't have one).
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!