Building a React App for Solidity Contracts with Vite, Tailwind, and Web3
This guide will show you how to create a React app to interact with Ethereum smart contracts using Web3.js. We will set up a Vite project with Tailwind CSS styling and build interfaces for two example contracts: a Vending Machine and a Lottery.
Steps to Set Up the React App
Step 1: Initialize a Vite Project
Run the following commands to create a Vite React app, install dependencies, and start the development server:
Install Web3.js to connect your React app to the Ethereum blockchain:
npm install web3
Vending Machine Contract
The Vending Machine smart contract allows users to purchase items with Ether and allows the owner to restock inventory.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract VendingMachine {
address public owner;
mapping (address => uint) public cokeBalances;
constructor() {
owner = msg.sender;
cokeBalances[address(this)] = 100;
}
function getVendingMachineBalance() public view returns (uint) {
return cokeBalances[address(this)];
}
function restock(uint amount) public {
require(msg.sender == owner, "Only the owner can restock.");
cokeBalances[address(this)] += amount;
}
function purchase(uint amount) public payable {
require(msg.value >= amount * 2 ether, "You must pay at least 2 ETH per item");
require(cokeBalances[address(this)] >= amount, "Not enough items in stock to complete this purchase");
cokeBalances[address(this)] -= amount;
cokeBalances[msg.sender] += amount;
}
}
Lottery Contract
The Lottery smart contract allows players to join by paying an entry fee, with the contract owner able to pick a winner at random.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Lottery {
address public owner;
address payable[] public players;
uint public lotteryId;
mapping (uint => address payable) public lotteryHistory;
constructor() {
owner = msg.sender;
lotteryId = 1;
}
function getWinnerByLottery(uint lottery) public view returns (address payable) {
return lotteryHistory[lottery];
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
function getPlayers() public view returns (address payable[] memory) {
return players;
}
function enter() public payable {
require(msg.value > .001 ether);
players.push(payable(msg.sender));
}
function getRandomNumber() public view returns (uint) {
return uint(keccak256(abi.encodePacked(owner, block.timestamp)));
}
function pickWinner() public onlyowner {
uint index = getRandomNumber() % players.length;
players[index].transfer(address(this).balance);
lotteryHistory[lotteryId] = players[index];
lotteryId++;
players = new address payable ;
}
modifier onlyowner() {
require(msg.sender == owner);
_;
}
}
Integrating the Contracts with the React App
Set up Web3 Provider and ABI files for each contract in src/contracts/.