
源码系统概览
文章正文
election 是 DappUniversity 出品的经典以太坊 DApp 入门实战项目,用最精简的代码完整演示了如何把一个投票业务搬到区块链上。
它把 Solidity 智能合约、Truffle 编译部署、Ganache 本地测试链与一套网页前端串成一条可运行的主线,开发者跟着跑一遍就能理解去中心化应用的核心工作方式。
整个仓库结构非常干净,没有多余封装,适合作为学习 Web3 与智能合约开发的第一个练手样本。
源码简介
项目根目录是一个标准的 Truffle 工程,包含 contracts、migrations、src、test 与 build 几个核心目录。
合约层只有一个 Election.sol,定义了候选人结构体、投票人映射与计票逻辑;migrations 目录负责把合约部署到本地链;src 目录是纯前端页面与交互脚本。
前端由 index.html 与 js/app.js 组成,依赖 Web3.js 与 truffle-contract 两个库,配合 Bootstrap 做基础样式,整体不依赖任何重型框架。
构建产物 build/contracts/Election.json 是编译后的合约 ABI 与字节码,前端通过它实例化合约对象并调用方法。
适用场景
最适合区块链初学者、前端工程师或在校学生作为第一个以太坊 DApp 的对照样例,按步骤就能在本地跑通完整投票流程。
也适合用于技术分享、教学演示或企业内部培训,用最小的代码量讲清楚智能合约与网页交互的关系。
对于想快速验证某个链上业务逻辑的产品经理,也可以把它当作可运行的原型骨架来改造。
功能亮点
合约侧用 require 做双重校验,既防止同一地址重复投票,也保证只能投给合法候选人编号,逻辑清晰且安全。
投票动作会触发 votedEvent 事件,前端通过监听该事件在票数变化后自动刷新页面,无需手动刷新即可看到最新结果。
前端会把候选人列表动态渲染成表格与下拉选项,并实时显示当前连接的钱包地址,交互直观。
已经投过票的钱包地址会被隐藏投票表单,避免重复提交,细节体验考虑得比较到位。
合约构造函数在部署时自动写入两名初始候选人,开箱即可演示完整投票场景。
技术架构与部署指南
| 维度 | 本套源码 | 同类通用方案 |
|---|---|---|
| 技术栈 | 前端:HTML + Bootstrap + 原生 JavaScript(Web3.js 0.x、truffle-cont | 依具体方案选型,需自行搭建与维护 |
| 部署方式 | 第一步先安装 Node.js、Truffle 命令行与 Ganache 图形客户端,并在浏览器中准备好 MetaMask | 多托管于第三方平台或订阅云服务 |
| 功能侧重 | 合约侧用 require 做双重校验,既防止同一地址重复投票,也保证只能投给合法候选人编号,逻辑清晰且安全。 | 功能通用,定制深度有限 |
| 数据归属 | 数据自持,部署在自有服务器,不出站 | 数据通常留存于服务商侧 |
| 成本模式 | 获取后自主部署,无持续授权费用 | 通常按订阅或调用量计费 |
技术栈与运行环境
前端:HTML + Bootstrap + 原生 JavaScript(Web3.js 0.x、truffle-contract)
后端:Solidity 0.4.20 智能合约(Election.sol),由 Truffle 编译部署
数据库:以太坊本地测试链(Ganache),链上状态即存储
运行环境:Node.js + NPM、Truffle、Ganache 本地节点(默认 127.0.0.1:7545)、MetaMask 浏览器插件
其他依赖:lite-server(npm run dev 静态服务,端口 3000)、jQuery
安装与部署提示
第一步先安装 Node.js、Truffle 命令行与 Ganache 图形客户端,并在浏览器中准备好 MetaMask 插件。
第二步进入项目目录执行 npm install 安装 lite-server 等前端依赖,随后启动 Ganache 获得一条本地测试链。
第三步用 truffle migrate –reset 把 Election 合约编译并部署到本地链,每次重启 Ganache 都需要重新迁移。
第四步把 MetaMask 连接到 Ganache 提供的本地网络并导入其中一个测试账户,最后执行 npm run dev 打开本地页面即可投票。
截图与演示说明
页面入口 src/index.html 顶部展示 Election Results 标题,加载时先显示 Loading 提示,合约数据就绪后再切换到内容区。
内容区是一张候选人结果表,列出发件人编号、姓名与当前票数,数据来自合约的 candidates 映射逐项读取。
页面下方提供候选人下拉框与投票按钮,选择后调用合约 vote 方法,交易确认后表格票数随之更新。
账号区域会显示当前 MetaMask 连接的钱包地址,已投票的地址会被隐藏投票表单,这些交互都在 js/app.js 的 render 与 castVote 中实现。
常见问题
问:部署合约时报错或页面一直停在 Loading 怎么办?
答:最常见原因是 Ganache 没启动、Truffle 网络端口不匹配,或忘记重新执行 truffle migrate –reset;请确认 MetaMask 已切到本地网络并导入对应账户。
问:必须把数据放到主网吗,能否接到测试网?
答:本仓库默认只连本地 Ganache,若要上测试网需自行修改 truffle.js 的 networks 配置并填入对应 RPC 与助记词,切勿把私钥写进公开仓库。
问:为什么打开页面后投票不刷新结果?
答:这是 MetaMask 旧版本的事件监听已知问题,可尝试重启浏览器;合约侧 votedEvent 已正确触发,刷新后数据会重新渲染。
安全风险提示
特别提示:本源码未检测安全风险文件,下载后请务必进行安全审计,删除恶意代码后再部署使用!
下载说明
源码仅供学习研究、测试部署和二次开发参考,商用前请自行确认授权、版权和安全风险。
本项目为公开的以太坊 DApp 教学示例,合约与前端均可在本地安全运行,但请注意不要把任何私钥或助记词提交到公开代码仓库。
GitHub项目开源地址:https://github.com/dappuniversity/election