如何将基于Truffle开发的彩票合约与ReactJS前端项目进行连接?
Great to hear you’ve got your lottery contract deployed and tested with Truffle—connecting it to a React frontend is totally straightforward with a few key steps. Let’s break this down into actionable, easy-to-follow parts:
First, create your React project and install the tools needed to interact with Ethereum:
- Create a new React app:
npx create-react-app lottery-frontend cd lottery-frontend - Install core dependencies for web3 integration:
npm install web3 @truffle/contract
From your Truffle project’s build/contracts folder, find your lottery contract’s JSON file (e.g., Lottery.json). This file contains two critical pieces of data:
- ABI (Application Binary Interface): Defines how your frontend can call the contract’s methods
- Contract Address: The deployed address of your contract on the blockchain
Copy these into a config file in your React project for easy access:
// src/config/contractConfig.js export const LOTTERY_ABI = [/* Paste your contract's full ABI here */]; export const LOTTERY_ADDRESS = "0xYourDeployedContractAddress";
You’ll need to handle wallet connection so users can interact with your contract. Create a custom hook to manage this:
// src/hooks/useWeb3.js import { useState, useEffect } from 'react'; import Web3 from 'web3'; export const useWeb3 = () => { const [web3, setWeb3] = useState(null); const [account, setAccount] = useState(''); useEffect(() => { const initWeb3 = async () => { // Check if MetaMask is installed if (window.ethereum) { try { // Request user permission to access their accounts await window.ethereum.request({ method: 'eth_requestAccounts' }); const web3Instance = new Web3(window.ethereum); setWeb3(web3Instance); // Fetch the user's active account const accounts = await web3Instance.eth.getAccounts(); setAccount(accounts[0]); } catch (error) { console.error('User rejected access or error occurred:', error); } } else { alert('Please install MetaMask to use this DApp!'); } }; initWeb3(); // Handle account/network changes const handleAccountChange = (accounts) => setAccount(accounts[0]); const handleChainChange = () => window.location.reload(); // Refresh on network switch if (window.ethereum) { window.ethereum.on('accountsChanged', handleAccountChange); window.ethereum.on('chainChanged', handleChainChange); } // Clean up event listeners on unmount return () => { if (window.ethereum) { window.ethereum.removeListener('accountsChanged', handleAccountChange); window.ethereum.removeListener('chainChanged', handleChainChange); } }; }, []); return { web3, account }; };
Create another hook to instantiate your contract once the web3 connection is established:
// src/hooks/useLotteryContract.js import { useState, useEffect } from 'react'; import { LOTTERY_ABI, LOTTERY_ADDRESS } from '../config/contractConfig'; export const useLotteryContract = (web3) => { const [contract, setContract] = useState(null); useEffect(() => { if (web3) { const lotteryContract = new web3.eth.Contract(LOTTERY_ABI, LOTTERY_ADDRESS); setContract(lotteryContract); } }, [web3]); return contract; };
Now you can create React components that let users call your contract’s methods (like buying tickets, checking winners, etc.). Here’s a simple example:
// src/components/Lottery.js import { useState } from 'react'; import { useWeb3 } from '../hooks/useWeb3'; import { useLotteryContract } from '../hooks/useLotteryContract'; const Lottery = () => { const { web3, account } = useWeb3(); const contract = useLotteryContract(web3); const [ticketValue, setTicketValue] = useState('0.1'); // Assume 0.1 ETH per ticket const buyTicket = async () => { if (!contract || !account) return; try { const weiValue = web3.utils.toWei(ticketValue, 'ether'); await contract.methods.buyTicket().send({ from: account, value: weiValue }); alert('Ticket purchased successfully!'); } catch (error) { console.error('Purchase failed:', error); alert('Purchase failed—check your wallet balance or network connection'); } }; const fetchLatestWinner = async () => { if (!contract) return; try { const winner = await contract.methods.getLatestWinner().call(); alert(`Latest winner: ${winner}`); } catch (error) { console.error('Failed to fetch winner:', error); } }; if (!web3) { return <div>Please install and connect MetaMask to continue</div>; } return ( <div style={{ padding: '2rem' }}> <h2>🎫 Lottery DApp</h2> <p>Connected Account: {account}</p> <div style={{ margin: '1rem 0' }}> <input type="text" value={ticketValue} onChange={(e) => setTicketValue(e.target.value)} placeholder="ETH amount per ticket" style={{ padding: '0.5rem', marginRight: '0.5rem' }} /> <button onClick={buyTicket} style={{ padding: '0.5rem 1rem' }}> Buy Ticket </button> </div> <button onClick={fetchLatestWinner} style={{ padding: '0.5rem 1rem' }}> Check Latest Winner </button> </div> ); }; export default Lottery;
Start your React app with npm start, make sure MetaMask is connected to the same network where you deployed your Truffle contract (e.g., Ganache local chain or a testnet like Goerli), and test the interactions to ensure everything works as expected.
内容的提问来源于stack exchange,提问作者Zoha Akram

