基于以太坊区块链+Spring Boot+Solidity智能合约的投票系统设计与实现

基于以太坊区块链+Spring Boot+Solidity智能合约的投票系统设计与实现

前言

欢迎关注 B 站:麦麦大数据

主页:https://space.bilibili.com/1583208775

这篇文章一方面介绍这个区块链投票系统的技术实现,另一方面也给正在做毕设、课设的同学提个醒:买项目之前一定要看清楚,不要只看截图和录屏。

目录

  • 一、这个学生是怎么踩坑的
  • 二、项目原本存在的问题
  • 三、项目技术栈介绍
  • 四、系统功能模块说明
  • 五、系统架构设计
  • 六、麦麦修复和部署的过程
  • 七、运行效果展示
  • 八、毕设防骗技巧
  • 九、项目亮点
  • 十、源码获取
  • 总结

一、这个学生是怎么踩坑的

这位同学当时需要做一个区块链相关的毕业设计,主题是"基于智能合约的链上投票系统"。因为自己时间比较紧,就在网上找人花钱买了一个所谓的完整项目。

刚开始对方给他看的内容还挺像那么回事:

  • 有登录注册页面
  • 有投票活动列表
  • 有管理员创建投票页面
  • 有 Ganache 区块链截图
  • 还有一段所谓的演示视频

但是项目真正拿到手以后,问题就暴露出来了。

本地运行时页面能打开一部分,但核心功能经常报错;管理员创建投票后,只能保存到数据库,链上创建投票失败;配置文件里的合约地址也是旧的,当前 Ganache 上根本没有部署对应合约。也就是说,这个项目看起来像完整系统,实际上只是一个没有真正打通的半成品。

对于毕设项目来说,这种情况非常危险。因为答辩老师不一定只看页面,很多老师会问技术细节,比如:

  • 智能合约部署在哪里?
  • 交易哈希能不能查?
  • Ganache 里有没有真实交易?
  • 数据库和链上数据是什么关系?
  • 创建投票失败时怎么排查?

如果项目只是"能打开页面",但核心流程跑不通,答辩时就很容易露馅。

二、项目原本存在的问题

根据后续排查,这个项目主要有几个典型问题。

1. 合约地址失效

配置文件里写了一个旧的合约地址:

properties 复制代码
blockchain.contract-address=0x...

但是当前 Ganache 环境中,这个地址上没有任何合约代码。也就是说,后端通过 Web3j 调用合约时,其实是在调用一个空地址。

这种情况下,业务数据可以保存到数据库,所以页面会显示"投票活动创建成功",但上链部分会失败,最终出现类似:

text 复制代码
投票活动创建成功(上链失败)

2. 私钥和 Ganache 账户不匹配

Ganache 重新启动或重置后,账户、私钥、合约地址都可能变化。如果配置文件里的管理员私钥还是旧的,就会出现:

  • 账户余额不足
  • 交易发送失败
  • 调用合约权限不匹配
  • 合约管理员不是当前后端使用的钱包

这个项目里就存在类似问题,必须重新确认当前 Ganache 账户和 Spring Boot 配置是否一致。

3. 项目部署说明不完整

很多半成品项目最大的问题不是代码完全没有,而是部署步骤缺失。比如没有说清楚:

  • 先启动 Ganache
  • 再部署 VotingContract.sol
  • 再把新合约地址写回 application.properties
  • 再重启 Spring Boot
  • 最后再测试创建投票和投票上链

少任何一步,系统都可能出现"页面能打开,但核心功能不能用"的情况。

4. 前端演示和真实可运行不是一回事

有些项目卖家只给截图和录屏,但截图并不能证明项目真正能运行。尤其是区块链项目,必须看到真实合约部署、真实交易哈希、真实 Ganache 交易记录,才算核心流程打通。

三、项目技术栈介绍

这个项目本身的方向是没问题的,属于比较典型的 Java Web + 区块链应用。

模块 技术
后端框架 Spring Boot 2.7.18
页面模板 Thymeleaf
数据访问 Spring Data JPA
数据库 MySQL / H2
区块链交互 Web3j
智能合约 Solidity
本地链环境 Ganache
前端 HTML、CSS、JavaScript
构建工具 Maven

项目主要目录如下:

text 复制代码
blockchain-voting-system/
├── src/main/java/com/voting/
│   ├── controller/
│   ├── service/
│   ├── dao/
│   ├── entity/
│   └── config/
├── src/main/resources/
│   ├── templates/
│   ├── static/
│   └── application.properties
├── src/main/solidity/
│   └── VotingContract.sol
├── database/
│   └── init.sql
├── deploy.js
└── pom.xml

从技术选型来看,它比较适合用于区块链方向的毕业设计,因为既有传统 Web 系统,又有智能合约和链上交易记录,答辩时可讲的内容比较多。

四、系统功能模块说明

修复后的系统主要包含以下功能。

1. 用户端功能

  • 用户注册
  • 用户登录
  • 个人中心
  • 钱包地址绑定
  • 浏览投票活动
  • 参与投票
  • 查看投票结果
  • 查看投票记录

截图文件:截图/1-登录.png

截图文件:截图/1-注册.png

截图文件:截图/2-个人中心.png

2. 管理员功能

  • 管理员登录
  • 创建投票活动
  • 设置投票开始和结束时间
  • 添加候选人
  • 查看投票统计
  • 触发区块链相关操作

截图文件:截图/3-admin登录.png

截图文件:截图/3-创建投票.png

截图文件:截图/3-创建投票-候选人.png

3. 区块链功能

  • Web3j 连接 Ganache
  • Solidity 合约部署
  • 创建投票活动上链
  • 候选人信息上链
  • 用户投票上链
  • 返回交易哈希
  • 在 Ganache 中查看区块和交易

截图文件:截图/2-区块链状态.png

截图文件:截图/ganache-以太坊区块链.png

五、系统架构设计

系统采用 Spring Boot 分层架构,整体分为前端页面层、Controller 控制层、Service 业务层、Repository 数据访问层,以及区块链交互层。

截图文件:截图/系统架构图.png

整体流程可以理解为:

text 复制代码
用户操作页面
  ↓
Controller 接收请求
  ↓
Service 处理业务逻辑
  ↓
Repository 保存数据库

同时:
BlockchainService
  ↓
Web3j
  ↓
VotingContract 智能合约
  ↓
Ganache 本地区块链

数据库负责保存用户、投票活动、候选人、投票记录等业务数据;区块链负责保存关键投票行为,保证数据透明、可追溯、不可篡改。

六、麦麦修复和部署的过程

这个项目找到我时,最大的问题不是页面完全打不开,而是"看起来能用,核心链上流程不能用"。这种项目最坑,因为表面上像完成了,实际答辩一演示就容易出问题。

我主要做了几步处理。

1. 重新梳理项目结构

先确认项目的 Controller、Service、Repository、Entity 是否完整,再确认前端模板、数据库脚本、配置文件和智能合约文件是否对应。

重点检查的文件包括:

text 复制代码
VotingController.java
BlockchainService.java
VotingContract.sol
application.properties
deploy.js
database/init.sql

2. 排查上链失败原因

创建投票时,本地数据库保存成功,但页面提示上链失败。于是重点排查:

  • Ganache 是否启动
  • RPC 地址是否正确
  • 合约地址是否有代码
  • 管理员私钥是否对应 Ganache 当前账户
  • 合约部署者是否和后端调用者一致

最终确认:原来的合约地址已经失效,需要重新部署智能合约。

3. 重新部署智能合约

重新将 VotingContract.sol 部署到当前 Ganache,并将新的合约地址写回配置文件:

properties 复制代码
blockchain.contract-address=0x新的合约地址

同时确保:

properties 复制代码
blockchain.admin-private-key=Ganache当前账户私钥

这一步非常关键。因为合约中的 createVoting()addCandidate() 等方法有管理员权限限制,如果私钥和合约部署者不匹配,就会调用失败。

4. 修复功能并远程部署通过

完成合约部署和配置修复后,再重新启动 Spring Boot 项目,测试核心流程:

text 复制代码
管理员登录
  ↓
创建投票活动
  ↓
添加候选人
  ↓
调用智能合约上链
  ↓
普通用户投票
  ↓
生成交易哈希
  ↓
Ganache 查看交易记录

截图文件:截图/2-投票活动.png

截图文件:截图/2-投票成功.png

截图文件:截图/以太坊-transactions.png

最终这个项目从"半成品跑不通",修复到"功能可演示、链上可追踪、远程部署通过",也帮助这位同学完成了毕设答辩。

七、运行效果展示

1. 投票列表

用户登录后可以查看所有投票活动,并进入详情页进行投票。

截图文件:截图/2-投票.png

2. 投票详情

投票详情页展示候选人、投票状态、当前票数等信息。

截图文件:截图/2-投票结构.png

3. 区块与交易

当投票成功上链后,可以在 Ganache 中查看对应区块和交易记录。

截图文件:截图/以太坊-blocks.png

八、毕设防骗技巧

这个案例也给准备做毕设的同学提个醒:不要只看项目截图,不要只相信录屏,更不要觉得"页面能打开"就代表项目完整。

1. 一定要要求现场运行

买项目前最好让对方远程现场运行,不只是看截图。至少要看到:

  • 项目能启动
  • 页面能访问
  • 数据库能连接
  • 核心功能能操作
  • 退出后重新启动仍然能跑

2. 要求演示核心业务闭环

比如这个区块链投票系统,不能只看登录页面。必须完整演示:

text 复制代码
管理员创建投票
添加候选人
用户参与投票
查看投票结果
Ganache 查看交易
数据库查看记录

能跑通闭环,才说明项目基本可用。

3. 区块链项目必须看链上记录

如果是区块链毕设,必须确认:

  • 合约是否真实部署
  • 合约地址是否有效
  • Ganache 是否有交易
  • 交易哈希是否真实存在
  • 后端是否真的调用了智能合约

只给一张 Ganache 截图,不代表项目真的打通。

4. 配置文件要重点检查

很多项目不是代码完全坏了,而是配置不对。比如:

properties 复制代码
blockchain.node-url=http://127.0.0.1:7545
blockchain.contract-address=0x...
blockchain.admin-private-key=0x...

这几个配置只要有一个和当前环境不匹配,链上功能就会失败。

5. 不要临近答辩才第一次部署

很多同学吃亏就是因为答辩前几天才第一次真正部署。结果发现环境不通、数据库缺表、依赖下不来、合约没部署,最后非常被动。

建议至少提前一周完整跑一遍:

  • 本地启动
  • 数据库初始化
  • 功能测试
  • 合约部署
  • 远程部署
  • 答辩演示流程

九、项目亮点

1. 业务完整度较高

项目包含用户端、管理员端、投票活动、候选人、投票记录、结果统计等模块,不是单页面演示项目。

2. 区块链概念落地

项目不是只在文章里写区块链,而是实际通过 Web3j 调用 Solidity 智能合约,将投票行为写入 Ganache 本地测试链。

3. 数据库与链上数据结合

数据库保存业务信息,链上保存关键投票行为,两者结合后,系统既方便展示,又具备可追溯性。

4. 答辩可讲内容丰富

答辩时可以从以下角度展开:

  • Spring Boot 分层架构
  • Thymeleaf 页面展示
  • MySQL/H2 数据库设计
  • Web3j 调用智能合约
  • Solidity 合约结构
  • Ganache 本地链部署
  • 投票上链与交易哈希
  • 防重复投票机制

十、源码获取

源码获取:联系麦麦大数据获取。

更多项目讲解、部署教程、源码资料,欢迎关注 B 站:麦麦大数据

主页:

总结

这个案例其实很典型:学生花钱买了一个看起来像完整项目的毕设,结果拿到手以后发现只是半成品,核心功能没有真正打通。尤其是区块链项目,页面只是表象,真正关键的是合约能不能部署、交易能不能上链、配置能不能和当前环境匹配。

后来通过重新排查配置、修复程序功能、部署智能合约、远程跑通环境,最终把这个链上投票系统修复成一个可以用于答辩演示的完整项目。

所以同学们做毕设一定要记住:买项目不是看截图,而是看能不能运行;区块链项目不是看概念,而是看有没有真实交易。遇到项目跑不通、部署失败、答辩前救急的问题,也可以关注麦麦大数据,后续会继续分享更多真实项目修复和部署案例。

相关推荐
薪火铺子8 小时前
CAS单点登录原理与实践
java·后端
DevilSeagull8 小时前
Rust 枚举(enum)深度解析:从定义到 Option 的安全之道
开发语言·后端·安全·rust·github
一 乐8 小时前
茶叶商城|基于springboot + vue茶叶商城系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·茶叶商城系统
鱼弦8 小时前
Git 版本控制:Spring Boot 项目的分支管理与协作
spring boot
devpotato17 小时前
Spring Boot mTLS 报 `keystore password was incorrect`:不一定是密码错了
spring boot·tls·pkcs12·mtls
Bczheng118 小时前
二十三.交易数据之签名(2)--选币逻辑
区块链
古城小栈19 小时前
从 cargo-whero 库中,找到提升 rust 的契机
开发语言·后端·rust
keep one's resolveY19 小时前
SpringBoot实现重试机制的四种方案
java·spring boot·后端
阿丰资源21 小时前
基于Spring Boot的电影城管理系统(直接运行)
java·spring boot·后端