Blockchain 实战指南
FreeGuideOnline
最新
2026-07-15
区块链投票系统
```5.4 app.js
// 合约 ABI(从 build/contracts/Voting.json 复制到此处)
const contractABI = []; // 粘贴完整的 ABI
const contractAddress = '部署后的合约地址'; // 从 Ganache 控制台或 truffle console 获取
let web3;
let votingContract;
window.addEventListener('load', async () => {
// 现代浏览器需通过 MetaMask 注入
if (window.ethereum) {
web3 = new Web3(window.ethereum);
await window.ethereum.request({ method: 'eth_requestAccounts' });
} else {
// 降级使用本地 Ganache 提供者
web3 = new Web3('http://127.0.0.1:7545');
}
// 获取合约实例
votingContract = new web3.eth.Contract(contractABI, contractAddress);
// 渲染候选人和票数
await renderCandidates();
// 监听投票事件
votingContract.events.votedEvent({ fromBlock: 'latest' }, (error, event) => {
if (!error) {
renderCandidates();
}
});
});
async function renderCandidates() {
const count = await votingContract.methods.candidatesCount().call();
const container = document.getElementById('candidates');
container.innerHTML = '';
for (let i = 1; i <= count; i++) {
const candidate = await votingContract.methods.candidates(i).call();
container.innerHTML += `
<div>
<strong>${candidate.name}</strong> - 票数: ${candidate.voteCount}
<button onclick="vote(${candidate.id})">投票</button>
</div>
`;
}
}
async function vote(candidateId) {
const accounts = await web3.eth.getAccounts();
try {
await votingContract.methods.vote(candidateId).send({ from: accounts[0] });
alert('投票成功!');
} catch (err) {
alert('投票失败: ' + err.message);
}
}
5.5 获取合约 ABI 与地址
- ABI:打开
build/contracts/Voting.json,找到"abi"字段,复制到contractABI数组中。 - 地址:部署成功后,终端输出类似:
或者在 Ganache 的 “Contracts” 页签中查看。Voting: 0x1234567890abcdef...
5.6 连接 MetaMask 测试
- 打开 MetaMask,添加自定义网络:
- 网络名称:Localhost 7545
- RPC URL:
http://127.0.0.1:7545 - 链 ID:1337
- 从 Ganache 导入一个测试账户的私钥到 MetaMask。
- 用浏览器打开
app/index.html(可使用npx http-server ./app启动简易服务器)。 - 页面会显示候选人及投票按钮,点击投票,MetaMask 弹出确认交易,确认后票数自动更新。
6. 部署到 Goerli 测试网(可选)
本地测试通过后,可将合约部署到公共测试网。
- 前往 Infura 注册,创建项目获取 Goerli 网络的 RPC URL。
- 从水龙头获取 Goerli 测试 ETH。
- 导出 MetaMask 账户的私钥,用于 Truffle 部署。
- 安装
@truffle/hdwallet-provider:
npm install @truffle/hdwallet-provider
- 修改
truffle-config.js,新增网络配置:
const HDWalletProvider = require('@truffle/hdwallet-provider');
module.exports = {
networks: {
goerli: {
provider: () => new HDWalletProvider({
privateKeys: ['你的私钥'],
providerOrUrl: '你的Infura_Gorli_RPC_URL'
}),
network_id: 5,
gas: 5500000,
confirmations: 2,
timeoutBlocks: 200
}
}
};
- 部署:
truffle migrate --network goerli