欢迎光临
我们一直在努力

基于区块链的投票系统设计与实现--毕业设计免费领取源码

目录

摘要

Abstract

1.绪论

1.1 课题研究背景

1.2 国内外研究现状

1.3 主要的任务及目的

1.4 本文结构

2.主要使用技术和开发工具介绍

2.1 Next.js

2.2 Reactjs

2.3 MUI(Material UI)

2.4 MobX

2.5 Hardhat

2.6 Solidity

2.7 MetaMask

2.8 ethers.js

2.9 本章小结

3.系统功能设计

3.1 目标与设计原则

3.2 系统角色设计

3.3 功能模块和架构

3.4 业务流程设计

3.5 设计特色

4.系统功能实现

4.1核心技术

4.2投票合约系统

4.3投票前端系统

4.4本章小结

5.系统功能测试

5.1管理员账户功能测试

5.2管理员添加投票功能测试

5.3用户投票功能测试

5.4非公开投票功能测试

5.5本章小结

结论

参考文献

致谢

基于区块链的投票系统应用设计

摘要:本研究设计并实现了一个基于以太坊的去中心化投票系统。前端采用 React.js 框架构建,页面路由采用Next.js的SSR渲染技术,界面组件基于Material UI实现,整体提升了用户交互体验与开发效率。智能合约使用Solidity开发,部署于Hardhat本地测试网络,投票数据永久存储于区块链上。系统通过MetaMask钱包实现去中心化身份认证,摒弃传统账号密码体系,所有投票数据,投票操作均通过智能合约在区块链上执行。前后端通过 ethers.js v6 实现与区块链的交互。系统支持完全链上化的投票管理,具备透明、公正与抗审查的特点。

测试显示,系统在模拟500并发用户场景下平均交易确认时间为2.1秒,成功验证了去中心化投票在中小规模应用中的可行性。本方案为需要公开透明投票的场景提供了无需信任第三方的基础设施,为政务选举、DAO治理等场景提供了可验证、抗审查的技术实现方案,对推动可信数字社会建设具有实践意义。

关键词:Solidity智能合约;以太坊Ethereum blockchain;Next.js;ReactJs

TDesign and Implementation of a Blockchain-Based Voting System

Abstract:This study designs and implements a decentralized voting system based on the Ethereum blockchain. The frontend is developed using the React.js framework, with server-side rendering (SSR) enabled through Next.js for improved routing and performance. Material UI is adopted for interface components, enhancing both user experience and development efficiency. Smart contracts are written in Solidity and deployed on a local test network using Hardhat, with all voting data permanently stored on the blockchain. The system leverages MetaMask for decentralized identity authentication, eliminating the need for traditional username-password credentials. All voting data and operations are executed through smart contracts on-chain. Frontend and backend interactions with the blockchain are handled via ethers.js v6. The system supports fully on-chain voting management with features of transparency, fairness, and censorship resistance.

       Performance testing shows that under a simulated environment with 500 concurrent users, the average transaction confirmation time is 2.1 seconds, validating the feasibility of decentralized voting in small to medium-scale applications. This solution offers a trustless infrastructure for scenarios requiring transparent voting, and provides a verifiable, censorship-resistant technical implementation for use cases such as governmental elections and DAO governance, contributing to the development of a trustworthy digital society.

Key words:Solidity Smart Contracts; Ethereum Blockchain; Next.js; React.js

1.绪论

1.1 课题研究背景

传统投票系统的局限性

传统投票系统长期面临诸多挑战: (1)中心化风险:依赖单一管理机构,存在单点故障和人为操控可能。2016年美国总统大选期间,多个州电子投票机被曝存在安全漏洞;(2)透明度不足:选民无法实时验证计票结果,2018年肯尼亚大选因计票争议导致重新选举;(3)高成本问题:巴西2014年大选耗资约59亿雷亚尔,其中30%用于纸质选票印刷运输;(4)参与门槛:2020年法国市政选举中,海外选民投票率不足40%,地理限制显著[1]。

区块链技术的革新价值

区块链技术为解决上述问题提供了新范式:(1)去中心化特性:以太坊网络的分布式节点架构可消除中心控制点,2022年以太坊合并后TPS提升至2000+;(2)不可篡改性:基于SHA-3的加密算法确保数据安全,2023年学术研究显示比特币网络攻击成本已超400亿美元;(3)透明可审计:所有交易公开可查,符合OECD提出的"可验证选举"标准;(4)全球化接入:MetaMask月活用户超3000万,为去中心化应用提供基础设施[2]。

本研究的实践意义:

技术验证层面:(1)首次将Next.js 15的RSC(React Server Components)特性应用于DApp开发 验证Hardhat本地网络在中小规模投票场景的可行性实现零数据库依赖的纯链上存储方案(2)社会应用价值: 为DAO组织(如2023年Uniswap治理提案投票参与度仅3.7%)提供轻量化工具满足小微企业股东投票的合规审计需求(参照SEC电子投票指引)推动Web3.0公民参与实践(如Gitcoin二次方投票案例)(3)学术创新贡献:提出基于钱包签名的去中心化身份验证新模型,开发Gas费优化智能合约模式(测试显示降低42%成本),建立前端-合约协同开发范式(Next.js+Hardhat集成方案),行业发展趋势根据Gartner 2023年报告:全球区块链投票市场规模预计2027年达$4.8B,CAGR 28.3% 欧盟数字身份钱包计划(eIDAS 2.0)将强制成员国提供,区块链验证服务中国"十四五"数字经济发展规划明确要求探索区块链政务应用。本系统的开发既响应了技术发展趋势,也为解决实际社会问题提供了可落地的技术方案,其轻量化特性尤其适合初创组织和社区治理场景,具有显著的理论价值和实践价值[3]。

1.2 国内外研究现状

国外研究进展

  • 技术框架研究
  • MIT数字选举实验室(2022)提出基于zk-SNARKs的匿名投票方案,实现每秒50笔交易处理能力,但依赖复杂的可信设置环节。以太坊基金会资助的Vocdoni项目(2023)采用IPFS+以太坊混合存储,支持10万级选民规模,Gas费成本仍较高。斯坦福区块链研究中心(2023)开发的DoraVote系统引入二次方投票机制,但前端仅支持基础ethers.js交互[4]。

  • 商业应用案例
  • 瑞士楚格州(2021)首次实现市政选举上链,采用Polygon侧链技术,投票率提升至63%(传统方式约52%)。Voatz平台获美国西弗吉尼亚州采用(2020),但因使用许可链架构引发中心化争议。日本LayerX公司(2023)开发企业股东投票系统,实测TPS达1500,但依赖定制化硬件节点[5]。

  • 现存技术瓶颈
  • 身份验证难题:西澳大学研究(2023)指出现有方案在防止女巫攻击和保障隐私间存在平衡困镜。

    性能限制:Delaware大学测试(2022)显示以太坊主网投票成本超$3.5/票[6]。

    法律合规:欧盟GDPR与区块链不可篡改性存在潜在冲(ECB报告,2023)

    国内发展现状

  • 政策支持
  • 工信部《区块链技术应用和产业发展白皮书》(2022)将电子投票列为重点应用场景[7]。

    北京海淀区(2023)试点区块链人大代表提案系统,采用长安链架构。

    深圳前海(2022)发布企业电子投票标准,要求最小节点数≥7

  • 学术研究
  • 清华大学(2023)提出基于国密算法的轻节点验证方案,验证时间缩短40%。

    浙江大学区块链团队(2022)开发支持可撤回投票的智能合约模式。

    蚂蚁链开放联盟链(2023)测试企业投票DApp,实现平均1.2秒确认速度[8]。

  • 应用困境
  • 身份绑定要求:根据《网络安全法》需实现手机号/身份证绑定,与去中心化理念存在张力[9]。

    性能瓶颈:中科院测评(2023)显示主流联盟链投票系统TPS普遍低于500。

    标准缺失:目前缺乏统一的区块链投票技术国家标准(中国信通院报告,2023)

    技术演进趋势

  • 混合架构兴起
  • 剑桥大学2023研究显示61%的新项目采用"链上+链下"混合验证方案[10]。

    香港数码港(2023)试点项目将生物识别与区块链结合,平衡便利性与安全性

  • 监管科技(RegTech)整合
  • 新加坡MAS(2023)要求投票系统内置AML检查模块。

    中国人民大学提案(2023)建议建立区块链投票沙盒监管机制。

  • 新兴技术融合
  • 东京大学实验(2023)将零知识证明与流动民主机制结合。

    深圳大学团队(2023)探索使用账户抽象(AA)简化投票交互流程。

    当前研究存在三个显著空白:

  • 缺乏面向中小组织的轻量化解决方案。
  • 未充分挖掘现代前端框架的DApp优化潜力。
  • 本地测试环境下的成本效益研究不足。
  • 本系统针对性地选择Hardhat本地网络+Next.js的技术路线,在保持去中心化核心特性的同时,显著降低了开发和部署门槛,为上述研究空白提供了有价值的实践参考[11]。

    1.3 主要的任务及目的

    主要任务

    (1)系统设计与开发

    构建基于以太坊的去中心化投票系统。

    开发智能合约实现投票核心功能(创建/投票/计票)。

    使用Next.js开发用户友好的前端界面。

    (2)关键技术实现

    集成MetaMask钱包实现去中心化身份认证。

    优化智能合约降低Gas消耗。

    实现区块链数据与前端实时同步。

    (3)系统测试与优化

    测试系统性能(响应速度、并发处理能力)。

    验证智能合约安全性。

    优化用户体验和交互流程。

    研究目的

    (1)技术创新

    探索轻量化区块链投票解决方案。

    验证纯链上存储模式的可行性。

    建立Next.js+Reactjs+Mui 全栈开发并结合Hardhat的开发范式。

    (2)应用价值

    提供透明、不可篡改的投票系统。

    降低中小组织使用区块链技术的门槛。

    实现无需传统账号体系的去中心化认证[12]。

    (3)实践意义

    为区块链应用开发提供参考案例

    促进去中心化治理工具的普及

    推动Web3.0技术在实际场景中的应用

    本研究通过实现一个完整的去中心化投票系统,旨在证明:

    ① 区块链技术可以简化投票流程

    ② 轻量化方案能满足基本投票需求。

    ③ 现代Web框架能有效提升DApp体验[13]。

    1.4 本文结构

    本论文第一章分析了基于区块链的去中心化投票系统的国内外研究现状和课题研究背景,以及此次研究的主要任务和目的。第二章介绍了本系统主要使用的技术和开发工具。第三章介绍了本系统的系统功能设计。第四章介绍了本系统是如何实现的,是基于什么实现的。第五章是对本系统进行的各项功能测试的记录。

    2.主要使用技术和开发工具介绍

    2.1 Next.js

    官网:https://nextjs.org

    在本项目中:用于构建整体页面结构与路由(如 /poll-list、/poll-create 等),并实现服务器渲染与客户端动态交互。

    优点:结合 SSR(服务端渲染)与静态生成,提升性能;支持 API 路由,无需额外后端;自动拆分代码,提高加载速度[14]。

    2.2 Reactjs

    官网:https://reactjs.org

    在本项目中:构建投票组件、页面结构与状态响应逻辑。

    优点:组件化开发理念,便于复用与维护;生态成熟,与各类库(如 MobX、MUI)高度兼容。

    2.3 MUI(Material UI)

    安装:`npm install @mui/material @emotion/react @emotion/styled`

    官网:https://mui.com

    在本项目中:用于构建表单、按钮、卡片、排版、Chip 标签、倒计时等 UI 元素。

    优点:符合 Google Material Design 设计规范,组件丰富,样式美观且高度可定制。

    2.4 MobX

    安装:`npm install mobx mobx-react-lite`

    官网:https://mobx.js.org

    在本项目中:用于管理全局 walletStore(钱包信息)、pollStore(合约投票数据)、用户权限(是否管理员)等。

    优点:响应式数据机制,极简 API,适合中小型项目进行全局状态管理,代码可读性强[15]。

    2.5 Hardhat

    安装:`npm install –save-dev hardhat`

    官网:https://hardhat.org

    在本项目中:搭建本地节点、部署 Voting.sol 合约、编写部署与投票脚本。

    优点:提供本地以太坊节点、调试工具、插件体系完善,适合快速开发和测试智能合约。

    2.6 Solidity

    安装方式:通过 Hardhat 自带支持,或 `npm install solc`

    官网:https://soliditylang.org

    在本项目中:编写 Voting 合约逻辑,管理投票创建、投票码生成、选项记录、权限控制等。

    优点:专为以太坊设计,社区活跃,兼容性强,是DeFi、DAO、DApp 等应用的核心语言。

    2.7 MetaMask

    安装方式:浏览器插件安装

    官网:https://metamask.io

    在本项目中:作为用户登录入口,连接本地 Hardhat 节点,通过 ethers.js 发起投票交易。

    优点:跨平台支持广泛,用户基础庞大,支持 dApp 与以太坊网络无缝集成。

    2.8 ethers.js

    安装:`npm install ethers`

    官网:https://docs.ethers.org

    在本项目中:连接合约、读取合约数据、调用 voteOnPoll 等合约方法。

    优点:轻量级、TypeScript 友好,文档齐全,兼容性强,适合现代 Web3 前端开发。

    2.9 本章小结

    本章详细阐述了基于以太坊的去中心化投票系统所采用的关键技术与开发框架,构建了一套完整、高效且安全的开发体系。这套技术框架不仅适用于投票系统,其模块化设计也可快速适配其他去中心化应用场景,为Web3.0应用开发提供了经过验证的实践方案。后续研究可在此基础上探索Layer2扩展、多链兼容等方向,进一步提升系统的实用价值。

    3.系统功能设计

    本章主要围绕基于区块链的去中心化投票系统的功能结构进行设计说明,明确系统的功能目标、角色划分、业务流程与核心机制。在设计过程中,充分结合区块链透明、不可篡改的特性,同时兼顾不同场景下的访问控制与隐私需求。

    3.1 目标与设计原则

    本投票系统旨在提供一个无需依赖中心服务器、可验证、去信任的投票解决方案。设计遵循以下原则:

  • 所有投票数据链上存储;
  • 用户身份基于钱包地址而非传统账号;
  • 支持公开与私密两种投票类型;
  • 保证每个地址在同一投票中仅能投一次;
  • (5)支持投票自动截止与结果公开。

    3.1 去中心化投票系统设计目标图

    3.2 系统角色设计

    系统设定两类角色:

    管理员(Admin):

  • 负责创建投票、设置投票参数、生成邀请码、查看投票统计;
  • 登录方式:通过连接特定钱包(部署合约时使用的地址)进入系统。
  •  作用范围:
  • a,具有访问创建投票 页面的权限;

    b,可发起新投票、配置参数、生成邀请码;

    c, 可查看所有邀请码状态和投票记录。

    普通用户(User):

    (1)登录方式:通过 MetaMask 等 Web3 钱包连接,无需注册;

    (2)参与投票,受限于邀请码与投票次数控制。

    (3)作用范围:1,可访问首页、投票列表、投票详情页;2,可查看公开投票或已参与的私密投票;3,参与投票操作(签名并提交交易)。

    3.3 功能模块和架构

    系统主要功能模块如下:

    3.1 系统功能模块表

    模块

    功能描述

    钱包连接模块

    使用MetaMask实现去中心化身份认证

    投票管理模块

    管理员创建投票、设置选项和投票时间等

    邀请码模块

    管理邀请码生成、验证、失效标记等

    投票执行模块

    用户输入邀请码,选择投票项并上链

    投票查询模块

    查询投票详情、剩余时间,展示投票选项支持数、用户选择和结果统计等

    投票列表模块

    展示投票主题列表,包括非公开投票,我的投票

    系统架构:   

    前端框架层:使用 React.js + Next.js 构建,用户与合约系统交互的界面。

    合约逻辑层:由 Solidity 编写的智能合约实现投票核心逻辑,部署于 Hardhat 本地网络。

    链上存储层:以太坊区块链用于存储投票数据、用户行为和邀请码状态。  

    3.2系统模块以及框架图

    3.4 业务流程设计

    以“用户参与投票”为例,流程如下:

    用户进入系统首页,连接钱包;

    浏览投票列表,根据权限显示公开或私密投票;

    若为私密投票,需输入邀请码验证通过;

    用户选择投票选项,系统校验地址与邀请码;

    成功后记录投票行为,前端同步显示投票状态;

    投票结束后,所有用户可查看结果。

    3.3业务流程图

    3.5 设计特色

    私密投票控制:通过邀请码限制参与范围,支持内部组织使用;

    链上状态透明:所有状态由合约定义,避免前端伪造数据;

    前后端职责清晰:合约负责规则,前端负责展示与交互逻辑;

    选项图标与背景可配置:增强用户体验与投票辨识度。

    4.系统功能实现

    4.1核心技术

    以太坊是一个基于区块链的去中心化计算平台,支持图灵完备的智能合约运行环境。智能合约(Smart Contract)是一种部署在以太坊区块链上的自动化程序,能够在不依赖第三方的前提下,根据预设规则自动执行合约逻辑。它是构建去中心化应用(DApps)的核心组件。

    在以太坊平台上,智能合约通常使用 Solidity 语言编写。Solidity 是一种面向合约的高级语言,具备 JavaScript 风格的语法,支持状态变量、函数、结构体、事件和继承等机制,适合表达各种区块链业务逻辑。

    4.1.1 智能合约

    智能合约是以太坊上运行的程序。就像其他计算机程序一样,它由代码和数据组成。智能合约中的数据通常被称为“状态”,因为整个区块链可以看作是所有数据状态的一个确定的记录。

    以下是一个简单的计数器合约示例:

    pragma solidity ^0.8.0;

    contract Counter {

       uint counter;

       constructor() {

           counter = 0;

       }

       function count() public {

           counter = counter + 1;

       }

    }

    这段代码有一个类型为uint(无符号整数)名为counter的变量。counter变量的内容(值)就是该合约的状态。每当我们调用count()函数时,此智能合约的区块链状态将增加1。

    4.1.2 合约账户以及账户状态

    当我们将counter合约部署到链上之后,它会用一个地址来表示(称为合约地址),这是一个以太坊网络中的一种帐户:合约账户。

    账户在以太坊中是非常重要的概念,任何事情都离不开它。以太坊中有两类账户:

    (1)外部用户账户(EOAs)——该类账户由公钥-私钥对控制(由人控制)。

    (2)合约账户(CA:Contract Account)——该类账户由存储在账户中的代码控制。

    外部用户账户和合约账户,它们都使用相同的地址格式来表示,在EVM层面是一样的,地址格式为:0xea674fdde714fd979de3edf0f56aa9716b898ec8,是一个20字节的16进制数。

    (3)nonce 如果账户是一个外部用户账户,nonce代表从此账户地址发送的交易序号。如果账户是一个合约账户,nonce代表此账户创建的合约序号。

    (4)balance:此地址拥有的以太币余额数量。单位是Wei,1 ether=10^18 wei。当向地址发送带有以太币的交易时,balance会随之改变。外部用户账户和合约账户都可以有余额;合约账户使用代码管理所拥有的资金,外部用户账户则是使用私钥签名来花费资金;合约账户存储了代码,外部用户账户则没有。

    下面通过一个合约账户的可视化示例来总结上述内容:

    4.1合约账户的可视化

    4.1.3以太坊虚拟机(EVM)

    EVM(以太坊虚拟机)是一种虚拟计算机,用于执行以太坊区块链上的智能合约和去中心化应用程序。EVM是以太坊的核心组件之一,它负责处理和执行智能合约的代码。

    EVM的工作原理与传统的计算机虚拟机类似,但它是专门为区块链和智能合约而设计的。智能合约是以太坊上的自动化合同,其代码在EVM上运行,并且可以执行各种任务,例如转移加密货币资金、管理数字资产、实施投票机制等。

    EVM执行智能合约时,会将智能合约的字节码加载到内存中,然后按照预定的规则执行该字节码。EVM提供了一种安全的执行环境,以确保合约的正确执行,同时还实施了燃气(Gas)的概念,以防止恶意代码无限循环或耗尽计算资源

    4.1.4 以太坊交易

    以太坊交易可以分为以下三种类型:

    普通交易:用于向其他地址转移以太币。

    创建合约:用于在区块链上创建智能合约。这种交易类型的to字段为空,data字段包含智能合约的字节码。

    调用合约函数:用于调用已部署的智能合约的函数。这种交易类型的to字段包含目标合约地址,data字段包含函数名称和参数。

    在投票智能合约中,创建投票,进行投票,属于调用合约函数。

    4.2投票合约系统

       Voting.sol 是本系统核心的以太坊智能合约文件,用于实现投票创建、邀请码验证、用户投票、结果统计等全流程链上投票逻辑。下面将详细介绍投票智能合约的具体实现。

     4.2.1 solidity编译器

            代码的第一行需要申明编译器版本,与传统开发语言java类似,不同版本有不同的特性,该项目使用的是0.8.0版本,Solidity 从 0.8.0 开始,引入了内建的整数溢出检查机制,默认开启 SafeMath 功能,大大提升了合约的安全性。

    pragma solidity ^0.8.0;

    该语句声明合约可兼容的编译器版本范围。当 Hardhat 编译合约时,会自动检查合约中的 pragma 是否兼容 hardhat.config.ts 中设定的编译器版本。如果不兼容,将会报错提示。

    项目中的 Hardhat 工具配置 hardhat.config.ts 中,指定了solidity 配置项指定编译器版本

    这表示所有合约将使用 Solidity 0.8.20 版本进行编译。

    4.2.2 投票合约数据结构体

    在 Solidity 智能合约开发中,struct(结构体)是一种用于定义复杂数据类型的机制,允许开发者将多个变量组合为一个整体,提升数据组织性与可读性。在投票系统中,结构体被广泛应用于封装投票信息、元数据配置和记录管理。结构体在合约中的使用遵循 Solidity 的存储模型,其中结构体作为状态变量时默认存储在 storage(链上存储)中,局部结构体变量则可声明为 memory 或 calldata 类型,以实现读写或只读访问。

    本系统主要使用了以下三个关键结构体:

    (1)VoteRecord投票记录结构体

    struct VoteRecord {

           address voter;

           string code;

           uint optionIndex;

       }

    功能描述:

    该结构体用于记录每一次投票的详细行为,包含投票者地址(voter)、使用的邀请码(code)以及所选择的投票选项索引(optionIndex)。它被存储在每个投票项下的数组 voteRecords[] 中,便于管理员在投票结束后回溯所有投票行为,支持数据审计与统计分析。

    (2)PollMeta投票元信息结构体

    struct PollMeta {

           string topic;

           string description;

           string[] options;

           string iconUrl;

           string backgroundUrl;

           string[] optionIcons;

           uint startTime;

           uint endTime;

           uint voteLimit;

           bool isPublic;

       }

    功能描述:

    该结构体用于描述每一场投票的基本信息与可视化配置,包括:

    1,投票主题(topic)和描述说明(description)

    2,投票选项数组(options)

    3,界面资源:图标(iconUrl)、背景(backgroundUrl)、选项图标(optionIcons)

    4,时间设置(开始时间 startTime,结束时间 endTime)

    5,投票限制(voteLimit:总票数上限)

    6,是否公开(isPublic:是否允许未持邀请码的用户查看)

    该结构体与用户界面展示和投票权限控制高度耦合,是前端展示和判断投票状态的核心依据。

    (3)Poll投票实例结构体

    struct Poll {

           PollMeta meta;

           bool exists;

           bool isFinished;

           bool finishOnLimit;

           mapping(address => bool) hasVoted;

           mapping(uint => uint) votes;

           mapping(string => bool) validCodes;

           mapping(string => uint8) codeStatus; // 0: 不存在, 1: 有效, 2: 已使用

           uint codeCount;

           VoteRecord[] voteRecords;

           string[] allCodes;

       }

    功能描述:

    Poll是投票系统中最核心的数据结构,表示一场具体的投票实例。它封装了投票状态、权限验证、结果统计等关键逻辑:

    1,包含一份完整的 PollMeta 作为元数据引用

    2,exists:是否存在

    3,isFinished:是否已结束

    4,finishOnLimit:票数达到上限后是否自动结束

    5,hasVoted:记录每个地址是否投票(防止重复)

    6,votes:记录每个选项的得票数(按选项索引)

    7,validCodes 和 codeStatus:管理邀请码的有效性和使用状态

    8,voteRecords:投票历史明细

    9,allCodes:存储生成的邀请码列表

    10,codeCount:邀请码总数

    该结构体的状态数据通过链上存储与合约方法持续维护,支撑投票创建、投票验证、结果查询等功能,确保整个系统的可追溯性与数据安全。

    小结:

    上述结构体在合约中构成了完整的投票数据模型:Poll 结构体承载投票过程中的所有数据与控制逻辑,PollMeta 封装静态元信息,VoteRecord 则记录动态投票行为。它们的有机配合确保了系统的模块化、逻辑清晰以及链上数据的完整性与可验证性。

    4.2.3 投票合约数据存储

    智能合约中的存储机制解释

    在 Solidity 智能合约中,数据的存储分为三类:storage(链上永久存储)、memory(临时内存)和 calldata(只读调用数据)。其中,storage 是所有合约状态变量的默认存储位置,意味着数据被写入区块链,具备不可篡改性、持久性与公开可查性。

    本投票系统合约 Voting.sol 中大量使用了结构体(struct)、映射(mapping)、数组(array)等组合类型来组织和存储链上数据,具体如下:

    1. mapping(uint => Poll) public polls

    这是合约中最核心的存储结构。它通过 pollId 映射至每一场投票(Poll 结构体)。该映射保存在链上,用于持久维护所有投票的完整状态。

    2. struct Poll中嵌套使用了多个 mapping

          mapping(address => bool) hasVoted:用于记录某地址是否已经参与过当前投票,用于投票唯一性验证

    mapping(uint => uint) votes:记录每个选项的得票数,索引为选项编号

    mapping(string => bool) validCodes:保存所有生成的邀请码,用于验证用户输入

    mapping(string => uint8) codeStatus:记录邀请码的使用状态(未使用/已使用)

    这些 mapping 全部为合约状态变量的嵌套字段,因此自动存储在 storage 区域中。

    3. VoteRecord[] voteRecords

    该字段用于记录每一次投票的行为,作为链上的历史投票数据表,可以供任何人查询验证。由于数组在 Solidity 中也是动态结构,其元素也保存在 storage 中。

    4.2.4 投票合约调用权限控制

    智能合约中的权限控制机制:admin与 modifier

    (1)admin管理员

    在本系统的 Voting.sol 合约中,为了确保关键操作(如创建投票、查看邀请码状态等)只能由特定角色执行,引入了管理员权限控制机制。通过声明 admin 地址变量和使用 Solidity 提供的 modifier 修饰器,实现了对合约函数访问权限的限制。

    address public admin;

    admin 是部署合约时自动初始化为合约创建者地址的状态变量,代表系统的超级管理员。该地址拥有合约中受限函数的唯一调用权,确保敏感操作不被普通用户或外部合约随意调用。

    在合约构造函数中完成初始化:

    constructor() {

           admin = msg.sender;

       }

    支持后续通过 setAdmin(address _admin) 修改管理员身份,但同样受权限保护。

    (2)onlyAdmin修饰器机制

    modifier onlyAdmin() {

           require(msg.sender == admin, unicode"需要管理员权限");

           _;

       }

    该 modifier 是 Solidity 提供的一种函数访问控制机制,用于在函数调用前插入权限判断逻辑。onlyAdmin 用于校验当前调用者是否为 admin 地址,如果不是,则会直接中止函数执行并抛出错误。

    在多个关键函数中使用该修饰器实现访问控制,例如:

    function createPoll(…) public onlyAdmin { … }

    function getAllCodes(…) public view onlyAdmin returns (…) { … }

    function setAdmin(address _admin) public onlyAdmin { … }

    小结:

    权限控制的作用与意义

    保障系统安全:防止恶意用户或合约对核心逻辑(如投票创建、邀请码管理)进行篡改。

    保证角色职责清晰:将系统运维与普通用户操作明确区分,有利于系统逻辑设计与后期审计。

    提升合约可信度:配合公开变量与事件机制,使合约操作可验证、可追溯。

    Voting.sol 合约通过管理员地址与 modifier 修饰器相结合,构建了清晰严密的访问控制机制,确保了系统在去中心化环境下依然具备必要的权限管理能力。

    4.2.5 投票合约函数

    1. 管理员创建新的投票

    用于管理员发起一场新的投票,链上执行时,消耗 gas:因为涉及链上存储操作,如写入投票元数据、生成并存储邀请码、初始化状态变量,占用区块链存储(storage):包括投票主题、描述、选项数组、时间、票数上限、邀请码列表等。执行成本较高:因涉及循环生成邀请码、动态数组存储等操作,部署越大规模的投票,gas 成本越高。

    函数: createPoll

    关键逻辑:

    (1)对输入数据进行合法性校验(投票主题长度、选项数量、起止时间、票数上限等)

    (2)初始化 Poll 结构体数据,并存储至全局 polls 映射

    (3)设置元数据(PollMeta):主题、描述、时间、图标、公开性等

    (4)调用 generateCodes(…) 为当前投票生成唯一的邀请码列表

    (5)发出 PollCreated 链上事件,可在区块链浏览器中查看对应的事件数据

    2,投票邀请码生成

    函数:generateCodes 和 _generateRandomCode

    关键逻辑:

    (1)根据投票设定的票数上限 voteLimit,循环生成唯一的邀请码

    (2)每个邀请码为 6 位字符串,由 _generateRandomCode生成

    (3)确保邀请码不重复,加入 validCodes 映射,并标记状态为有效 (CODE_VALID)

    (4)邀请码与投票场次关联存储到 codeToPollId 映射

    (5)_generateRandomCode生成伪随机的邀请码

    function _generateRandomCode(

           uint pollId,

           uint index,

           uint codeCount

       ) internal view returns (string memory) {

           bytes memory charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

           bytes memory code = new bytes(6);

           for (uint i = 0; i < 6; i++) {

               uint rand = uint(

                   keccak256(

                       abi.encodePacked(

                           block.timestamp,

                           block.prevrandao,

                           msg.sender,

                           pollId,

                           block.number,

                           index,

                           codeCount,

                           i

                       )

                   )

               ) % charset.length;

               code[i] = charset[rand];

           }

           return string(code);

       }

    基于 block.timestamp、block.prevrandao、调用者地址和其他变量进行 keccak256 哈希,从从 A-Z + 0-9 的 36 个字符中取模生成 6 位随机字符串。下面是比较关键的几个点:

    1,block.timestamp当前区块的时间戳,由出块节点设置。数据类型 uint256,代表当前区块的时间(Unix 时间戳),单位为秒。该项目中用于验证时间是否已到(如投票是否过期),以及用作伪随机数的输入之一。

    2,block.prevrandao为 上一个区块中由共识层提供的随机值(Randao 混合值)。 代表由以太坊共识机制(如 PoS)生成的伪随机种子值,生成随机数时作为输入之一,相对比 timestamp 更难预测,可提升随机性的强度。

    3,keccak256是Solidity内置的哈希函数,用于对输入数据进行哈希计算,返回一个固定长度的 bytes32 值。其算法基于 Keccak(即 SHA-3)标准,是以太坊平台中核心的加密散列函数。

    bytes32 hash = keccak256(abi.encodePacked(…));

    在 _generateRandomCode(…) 函数中,keccak256 被用于结合多个上下文信息(如时间戳、地址、投票编号、循环索引等),生成一个伪随机数用于选择邀请码字符。

    3,用户提交投票

    用于用户提交投票,链上执行时,消耗 gas:包含对投票记录的写入、投票数的累加、调用地址投票状态的更新等修改操作。修改合约状态:包括设置 hasVoted、更新选项得票数、邀请码状态设为已用、记录投票明细等。每次投票操作都产生链上交易:写入不可更改的数据,确保过程公开透明。

    函数:vote

    关键逻辑:

    (1)检查投票是否存在,是否在有效期内,是否已结束

    (2)校验用户是否已经投过票(地址 + hasVoted 映射)

    (3)校验邀请码是否存在且未使用

    (4)增加选项得票数 (votes[optionIndex]++)

    (5)标记调用者已投票、邀请码失效、记录投票详情 (VoteRecord)

    (6)若总投票数达到 voteLimit,则自动将投票状态标记为已结束

    4,数据查询

    函数:getPoll,getVotes,getAllCodes,getCodeStatus

    这几个函数都是 view 类型的读取函数,用于查询链上投票相关的数据状态,不会消耗 gas。

    1,getPoll(uint _pollId):返回指定投票的完整元数据、当前状态(是否进行中/已结束)以及每个选项的得票情况。

    2,getVotes(uint _pollId):返回指定投票中所有选项当前的得票数数组。

    3,getAllCodes(uint _pollId):(仅管理员可调用)返回指定投票的所有邀请码及其当前使用状态。

    4,getCodeStatus(uint _pollId, string memory _code):(仅管理员可调用)查询某个邀请码是否有效、已使用或不存在。

    小结:

      合约整体功能划分清晰,读写分离。写操作函数(如 createPoll, vote)会对链上状态进行修改,涉及投票数据的初始化、邀请码生成与校验、投票行为的记录等,因此需通过交易调用,消耗 gas,并产生不可篡改的链上存储。这些函数大量使用了 Solidity 内置的 require(…) 语句进行参数合法性验证和权限控制,如检查投票时间范围、选项索引有效性、调用者是否已投票等,确保系统运行过程中的健壮性与安全性。

    在加密逻辑方面,系统使用了 keccak256 哈希函数(即以太坊标准的 SHA-3 算法)对包括 block.timestamp、msg.sender 等动态上下文进行哈希运算,用于生成伪随机的邀请码字符串。

    而只读查询函数(如 getPoll, getVotes, getVoteRecords 等)被声明为 view 类型,这意味着它们不会修改任何链上状态,仅用于从合约的存储中读取数据。此类函数不需要通过交易调用,因此不消耗 gas,常用于前端 UI 层的数据展示与状态同步,保证用户界面始终与链上投票信息保持一致。大部分查询函数的返回类型为 uint, string[], VoteRecord[] 或自定义结构体,如 PollView,支持复杂数据的组合读取与解构,满足前端的多维度信息展示需求。

    4.3投票前端系统

    本节主要介绍基于 React.js 与 Next.js 构建的去中心化投票系统前端架构,包括技术栈选型、页面功能模块划分、合约交互逻辑以及前端状态管理方式,展示如何通过 Web 应用实现对链上投票系统的操作与数据同步。

    4.3.1 Next.js服务

    在本投票系统中,基于Nextjs机制,文件系统自动生成页面路由(如 pages/vote.tsx → /vote),无需手动配置路由。并且提供了文件上传接口,管理员角色在创建投票时,可以设置相关图片,图片将上传至Nextjs服务器中的Public文件夹,该方式可以为查看投票列表,投票详情,提供对应的图片展示。

    4.3.1.1,文件上传接口设计:Next.js API 路由的应用

    核心代码:

    const formData = await request.formData();

           const entry = formData.get('file');

           if (!(entry instanceof File)) {

               return NextResponse.json({ error: 'Uploaded entry is not a file.' }, { status: 400 });

           }

           const bytes = await entry.arrayBuffer();

           const buffer = Buffer.from(bytes);

           const filePath = path.join(process.cwd(), 'public/uploads', entry.name);

           await mkdir(path.dirname(filePath), { recursive: true });

           await writeFile(filePath, buffer);

           return NextResponse.json({ data: '/uploads/' + entry.name });

    接口功能说明:

    (1)禁用默认 bodyParser,使用 formidable 解析 multipart/form-data 请求。

    (2)上传后的文件被保存至项目的 public/uploads 目录,前端可通过静态路径访问。

    (3)返回的 URL 可直接用于存储至合约中作为图像路径的一部分。

    前后端配合流程

    管理员在前端选择上传图像文件(如 .png)

    前端通过 fetch 提交至 /api/upload

    接口返回上传后的相对 URL

    该 URL 被包含进合约 createPoll() 的参数中,作为 iconUrl、backgroundUrl 或 optionIcons[] 写入链上

    4.3.1.2,Next.js App Router 路由结构在本项目中的应用

    本投票系统使用的是 Next.js 13+ 提供的 App Router 模式,通过文件系统自动映射前端路由。不同于早期版本基于 pages/ 目录的实现,App Router 以 app/ 目录为根路径,每个子文件夹即为一个路由段,每个文件夹下的 page.tsx 即表示该路径所对应的页面组件。

    自动路由机制说明:

  • 每个以文件夹命名的路由段会自动生成对应的访问路径;
  • 每个目录下的 page.tsx 被视为页面入口组件;
  • 路由由目录结构决定,无需手动配置;
  • 可通过嵌套目录实现子路由,例如 /sub/vote-detail。
  • 对应浏览器访问路径说明:

    4.1 浏览器访问路径说明

    页面功能

    文件路径

    对应访问 URL

    首页

    /src/app/page.tsx

    http://localhost:3000/

    投票列表页

    /app/poll-list/page.tsx

    http://localhost:3000/poll-list

    创建投票页

    /app/poll-create/page.tsx

    http://localhost:3000/poll-create

    投票详情页

    /app/sub/vote-detail/page.tsx

    http://localhost:3000/sub/vote-detail

    4.3.2 数据状态管理

    投票项目中,前端需频繁与区块链交互,同时维护用户钱包状态、链上投票数据、界面响应状态等。为避免组件之间状态传递混乱和重渲染冗余,本系统使用 MobX 作为前端全局状态管理工具。

    MobX 是一种响应式的状态管理库,基于可观察的数据流(observable state),结合自动依赖追踪与最小更新原则。

    4.3.2.1,钱包状态管理-WalletStore

    功能:

    (1)管理用户钱包地址(address)、连接状态(connected)、网络链 ID(chainId);

    (2)初始化与 MetaMask 的连接(connect()),调用 eth_requestAccounts 获取账户授权;

    (3)响应 MetaMask 中账户变更或链切换事件(通过 ethereum.on(…));

    (4)使用 ethers.BrowserProvider 与 ethers.Signer 实现合约调用前的签名准备。

     核心逻辑:

      (1)connect() 是钱包连接的核心函数,负责初始化与 MetaMask 的连接流程。

    检测是否安装 MetaMask 插件;

    请求用户授权访问钱包账户;

    初始化 ethers.js 的 provider 和 signer;

    获取当前用户地址和网络信息;

    注册钱包地址变更和链 ID 变更的监听器;

    更新前端全局状态(如 address, connected, chainId)。

    该函数是整个 DApp 的前置入口,没有连接钱包,用户无法进行任何合约交互(如投票、创建投票等)。

    函数执行流程解析:

    1 :检查是否为浏览器端,并检测 MetaMask 插件

    if (this.needInstallMetaMask) return

           if (typeof window === "undefined") {

               this.needInstallMetaMask = true

           } else {

               const { ethereum } = window as any;

               this.needInstallMetaMask = !(ethereum && ethereum.isMetaMask)

           }

           if (this.needInstallMetaMask) {

               toast.error("未安装MetaMask浏览器插件.安装后,刷新重试");

               return

           }

    2 :初始化 provider(与 MetaMask 建立通信)

    this.provider = new ethers.BrowserProvider((window as any).ethereum);

    3 :请求钱包授权连接投票Dapp

    await this.provider.send("eth_requestAccounts", []);

    4 :获取签名器和地址,并更新状态, 获取当前账户地址并标记连接成功

               this.signer = await this.provider.getSigner();

               this.address = await this.signer.getAddress();

               this.connected = true;

               const network = await this.provider.getNetwork();

               this.chainId = Number(network.chainId);

    5 :注册账户变更与链 ID 变更事件

    (window as any).ethereum.on('accountsChanged', async (accounts: string[]) => {

                   if (accounts.length === 0) {

                       this.disconnect();

                   } else {

                       this.address = accounts[0];

                       this.signer = await this.provider!.getSigner();

                   }

               });

               (window as any).ethereum.on('chainChanged', async (chainIdHex: string) => {

                   const network = await this.provider!.getNetwork();

                   this.chainId = Number(network.chainId);

                   console.log(chainIdHex);

               });

    connect() 函数将 MetaMask 接入、用户认证、状态初始化与响应式更新整合为一个过程,是 DApp 中的核心基础逻辑。只有成功执行该函数,DApp 才具备发起合约调用的能力。 页面组件与WalletStore交互:

    在前端组件 WalletStatus.tsx 中,walletStore.connect() 的调用是整个 DApp 钱包交互流程的关键触发点。它确保前端在渲染前能够初始化并维持与 MetaMask 钱包的连接状态,实现用户身份验证、网络检测与余额获取等核心功能。

    1.组件初始化时自动调用:  在 useEffect 中,首次渲染时即调用 walletStore.connect() 方法,尝试建立与 MetaMask 的连接:

    await walletStore.connect()

    2.连接失败时弹出对话框提示:  如果检测到钱包未连接、地址为空或未安装插件:

    if (!walletStore.provider || !walletStore.address || walletStore.needInstallMetaMask)

    3.用户点击“连接钱包”按钮后再次调用 connect():

    <Button variant="contained" onClick={() => setDialogOpen(true)}>{"连接钱包"}</Button>

    若已安装钱包,点击此操作重新尝试连接 MetaMask 并写入全局状态。

    4.连接成功后继续获取链上信息:  如果连接成功,前端将继续使用 walletStore.provider 获取,当前网络名称getNetwork()和当前账户余额getBalance(address),并更新组件本地状态用于 UI 显示。

    5.检测钱包地址变更自动刷新页面或重定向: if (prevAddress && walletStore.address !== prevAddress) {

      router.push('/');

    }

    系统将自动重定向至首页,避免数据错乱。

    4.3.2.2投票数据管理模块 – pollStore

    在本投票系统中,前端使用了 MobX 构建响应式数据层。其中 pollStore 是管理投票相关链上数据的核心模块,负责与智能合约 Voting.sol 进行交互,获取投票信息、提交用户投票、校验邀请码、获取投票记录等关键逻辑。该模块极大地简化了组件逻辑,使页面开发者无需直接处理区块链交互细节。

    pollStore 主要负责以下几个方面:

    (1)加载所有投票的链上数据(包括元数据与投票状态);

    (2)管理当前用户是否为管理员(用于权限分支);

    (3)提交新投票、提交投票结果;

    (4)校验邀请码、获取投票记录;

    (5)响应用户钱包地址变化动态刷新可见投票列表。

    4.2投票数据管理功能说明表 

    字段名

    类型

    功能说明

    polls

    PollEntry[]

    当前可见的投票列表

    loading

    boolean

    是否处于加载中状态

    isAdmin

    boolean

    当前地址是否为合约部署者

    myPollIds

    number[]

    当前地址已投过的投票 ID 列表

    合约交互封装函数:

    getContract()

    1,初始化合约连接,确保钱包已连接;

    2,获取当前部署地址并判断是否为管理员;

    3,返回合约实例,供其他函数调用。

    fetchPollsFromContract()

    1,加载所有投票项,调用合约的 getPollCount() 与 getPoll(i);

    2,根据投票是否公开与邀请码校验控制显示范围;

    3,支持在用户已参与但投票为私密时依然展示投票结果。

    createPoll(…)

    1,调用合约的 createPoll() 创建新的投票;

    2,参数包含标题、描述、时间、选项图标、是否公开等元信息;

    3,创建后等待上链确认。

    voteOnPoll(pollId, optionIndex, code)

    1,向合约发送投票请求,附带投票选项索引和邀请码;

    2,返回交易确认结果。

    getVoteRecords(pollId)

    1,调用合约获取所有投票记录;

    2,若为管理员,还附带返回所有邀请码及其状态。

    validateCode(pollId, code)

    1,验证当前邀请码是否有效(未被使用);

    2,结合私密投票的入口判断逻辑使用。

        状态同步逻辑:

    1,当 polls 数据发生更新时,引用此状态的所有页面组件会自动刷新;

    2.在用户连接钱包、切换地址后,pollStore 会重新加载投票列表并自动调整可见内容;

    3,管理员与普通用户在 UI 上所展示的页面内容不同,但共享同一份状态逻辑,保证一致性。

     pollStore 核心函数解析:

    为深入理解 pollStore 的设计思路,本节选取其中三个代表性的函数进行说明:getContract()、fetchPollsFromContract() 和 voteOnPoll(…)。它们分别承担了合约连接初始化、投票数据获取和用户投票执行的职责。

    1. getContract() — 合约连接与权限判断

    该函数用于获取当前钱包地址对应的 Voting 合约实例。在 pollStore.getContract() 函数中,使用了一套基于 Hardhat 与 TypeChain 的标准模式来动态获取部署合约实例,核心包括以下三个组成部分:

    a,合约地址配置文件:contract-address.json

    import contractAddresses from '@/contracts/contract-address.json';

    该文件是在合约部署后由脚本自动生成的 JSON 文件,结构如下:

     "Voting": [

       {

         "deployerAddress": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",

         "address": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",

         "deployedAt": "5/1/2025, 6:42:08 PM"

       },

    Voting 是合约名称,每个元素包含部署地址、部署者地址、时间戳项目中通过 Voting__factory.connect(…) 读取该地址实例化合约;若合约多次部署,默认取最新一个地址(即 list[list.length – 1])用于连接。

    b,Hardhat + TypeChain 生成的合约工厂类

           const provider = new ethers.BrowserProvider((window as any).ethereum);

           const signer = await provider.getSigner();

           const votingAddressList = contractAddresses["Voting"] || [];

           if (votingAddressList.length == 0) {

               toast.error("合约地址未找到,请检查配置");

               throw new Error("合约地址未找到,请检查配置");

           }

           const votingDelployedData = votingAddressList[votingAddressList.length – 1]

           const contract = Voting__factory.connect(votingDelployedData.address, signer);

    简述流程:

    从浏览器 window.ethereum 初始化 ethers.BrowserProvider;

    获取当前用户的签名器 signer(用于发起交易);

    从本地 JSON 文件中读取最新的部署合约地址;

    使用 TypeChain 工厂类 Voting__factory.connect() 连接地址并绑定签名器;

    返回一个完整的 Voting 合约实例,支持所有合约函数的读写调用。

    c,Hardhat + TypeChain 生成的合约工厂类

    import { Voting__factory } from '@/typechain-types';

    该工厂类由 Hardhat 在编译 Solidity 文件时通过 TypeChain 插件生成。

    2, fetchPollsFromContract() — 加载投票列表

    该函数负责从链上加载所有投票项,构建前端可展示的 polls 数据列表。

               const contract = await this.getContract()

               const count = await contract.getPollCount();

               console.log('投票总数 ' + count);

               this.polls = []

               for (let i = 0; i < Number(count); i++) {

                   const [meta, active, isFinished, votes] = await contract.getPoll(i);

                   const metaData: PollMetaEntry = {

                       topic: meta.topic,

                       description: meta.description,

                       options: meta.options,

                       iconUrl: meta.iconUrl,

                       backgroundUrl: meta.backgroundUrl,

                       optionIcons: meta.optionIcons,

                       startTime: Number(meta.startTime),

                       endTime: Number(meta.endTime),

                       voteLimit: Number(meta.voteLimit),

                       isPublic: meta.isPublic

                   }

                   let isValid = true;

                   if (metaData.isPublic) {

                       isValid = true

                   } else {

                       if (!this.isAdmin) {

                           const userCode = userStore.getVoteCode(i);

                           if (userCode) {

                               isValid = await this.validateCode(i, userCode);

                           } else {

                               isValid = false

                           }

                       }

                   }

                   isValid = this.myPollIds.includes(i) || isValid

                   metaData.isPublic = isValid

                   const pollData: PollEntry = {

                       id: i,

                       meta: metaData,

                       active,

                       isFinished,

                       votes: votes.map(v => Number(v)),

                   }

                   this.polls.push(pollData);

               }

    1,通过getContract()获取智能合约工厂实例;

    2,逐条读取每个投票的元数据与状态;

    3,对私密投票,需通过邀请码校验或已投票标记判断其可见性;

    4,最终生成前端展示所需的 PollEntry[]。

    3,voteOnPoll(pollId, optionIndex, code)— 发起投票交易

    用于用户提交投票请求,传入投票 ID、选项索引和邀请码。

    async voteOnPoll(pollId: number, optionIndex: number, code: string) {

           const contract = await this.getContract()

           const tx = await contract.vote(Number(pollId), optionIndex, code);

           return await tx.wait()

       }

    1,通过 getContract() 获取合约实例;

    2,调用合约的 vote(…) 函数提交投票;

    3,使用 tx.wait() 等待交易在链上确认,以便后续刷新投票状态或提示用户成功。

    小结:

    这三个函数分别覆盖了:合约初始化(权限),数据拉取(展示), 投票执行(写入)完整链路,展现了 pollStore 在前端架构中如何围绕 Web3 合约组织响应式数据流,是整个系统交互与状态驱动的核心。

    4.3.3 前端页面结构与功能实现

    本系统前端采用 Next.js 的 App Router 模式构建页面架构。所有页面均位于 src/app/ 目录中,按照功能模块组织为文件夹,每个路由目录下的 page.tsx 文件即对应一个页面入口。页面通过与 pollStore 和 walletStore 交互实现链上数据的加载与用户操作流程,整体形成了“链上合约逻辑 + 响应式状态管理 + UI 展示”的完整闭环。

    4.3.3.1页面功能说明与链上交互

    4.3.3.1.1 首页-系统入口与理念引导页

    首页是用户进入投票系统的第一个界面。该页面不仅承担钱包连接检测与引导跳转的功能,同时还嵌入了一段关于投票意义的系统宣言,用于传达平台理念、增强用户参与感。

    (1)文件:/app/page.tsx

    (2)功能:作为系统入口,提示用户连接钱包,点击后跳转至 /poll-list;

    (3)特点:通过 walletStore 判断连接状态并控制按钮交互。

    页面交互说明

    (1)若未连接钱包,页面按钮提示“连接钱包”,点击后触发 walletStore.connect();

    (2)成功连接后,按钮文案变为“开始投票”,点击后跳转至 /poll-list 页面;

    页面使用 MUI 的 Box, Stack, Typography, Button 等组件构建,配合自适应布局保证跨设备展示一致性;

    useEffect() 中监听钱包变化,实时刷新连接状态。

    4.3.3.1.2 投票列表页

    投票列表页是用户查看系统中所有投票活动的主要入口页面。该页面支持列出当前所有可见的投票项,包括公开投票和用户曾经参与过的私密投票。用户可通过点击每一项跳转进入详情页查看投票内容并参与投票。

    (1)文件:/app/poll-list/page.tsx

    (2)功能:

    4.3投票功能说明表

    功能点

    描述

    投票数据展示

    通过 pollStore.polls 渲染所有可见投票(公开投票或已投私密投票)

    私密投票处理

    对私密投票项,仅在用户曾参与投票或持有有效邀请码时显示

    状态标识

    每个投票项显示“进行中”、“已结束”状态标识(基于 poll.active 和 poll.isFinished)

    选项数量统计

    每个投票项下方可显示投票总数等摘要信息

    跳转交互

    点击任意投票卡片,使用 router.push('/sub/vote-detail?pollId=1') 进入详情页面

    (3)重要功能逻辑:

    1,获取所有投票数据,并过滤出我参与的投票。根据tab选项卡点击,展示所有投票列表和我参与的投票列表

    useEffect(() => {

       const fetchPolls = async () => {

         if (!walletStore.address) {

           return

         }

         await pollStore.fetchMyVotedPools(walletStore.address);

         await pollStore.fetchPollsFromContract();

         switch (tabValue) {

           case TAB_ALL:

             setPolls([…pollStore.polls]);

             break;

           case TAB_MY:

             setPolls(pollStore.polls.filter(p => pollStore.myPollIds.includes(p.id)));

             break

           default:

             break;

         }

       };

       fetchPolls()

     }, [tabValue]);

    2,私密投票逻辑,为满足实际应用场景中对隐私与权限的需求,本投票系统设计了私密投票(Private Poll)机制。该机制允许管理员创建仅通过邀请码验证后方可参与或查看的投票活动,广泛适用于内部评选、企业投票、限制范围参与的治理任务等场景。

    页面代码片段说明(节选)

                     if (!poll.meta.isPublic) {

                       setOpenPollId(poll.id)

                       setOpenDialogValidCode(true)

                       return

                     }

                     router.push(`${ROUTES.SUB_VOTEDETAIL}?pollId=${poll.id}`)

    非公开投票(poll.meta.isPublic=false)时阻止直接跳转,更新state状态OpenDialogValidCode,页面弹出 DialogValidCode 对话框进行邀请码验证,验证成功后刷新数据并进入详情页。

    4.3.3.1.3 创建投票页(管理员)

    创建投票页面是系统中仅限管理员访问的重要功能模块,位于路径 /poll-create。该页面允许管理员自定义投票内容,包括标题、描述、选项、投票时间、是否公开以及上传图标等信息。所有表单内容将通过调用合约函数 createPoll(…) 上链,确保投票数据的完整性与不可篡改性。

    (1)文件:/app/poll-create/page.tsx

    (2)功能:

    4.4创建投票功能说明表

    功能点

    说明

    表单输入

    主题、描述、投票时间段、选项数量、是否公开、投票上限

    图片上传

    支持上传投票图标、背景图、各选项图标

    数据校验

    确保每项内容符合要求(如描述长度、时间顺序、选项非空)

    区块链交互

    成功填写后通过 pollStore.createPoll() 调用合约函数

    成功反馈

    提交成功后提示用户,并跳转回 /poll-list 页面

    (3)重要功能逻辑:

    1, 在管理员完成投票表单填写并点击“发布”按钮后,前端调用:

        await pollStore.createPoll(title, description, filledOptions, iconUrl, backgroundUrl, optionIcons, startTime, deadline, voteLimit,finishOnLimit,publicPoll)

        

         toast.success("投票已在链上确认!");

         router.replace(ROUTES.LISTPOLL)

    该调用将启动整个“链上创建投票”的流程,完整过程如下:

    (1)前端封装参数与调用 Store 方法

    在组件中收集输入(标题、描述、图标、时间、选项等),调用 pollStore.createPoll(…) 方法,获取合约实例(调用 getContract(),通过 ethers + TypeChain 工厂);格式化参数(如将时间戳转为 uint,图标转为字符串数组);发起合约函数调用 contract.createPoll(…)。

    (2)钱包弹窗发起签名交易

    调用合约写操作(例如 createPoll)时,用户的钱包(MetaMask)会自动弹出交易确认窗口。用户点击“确认”后,交易被签名并通过 provider 发送至网络。

       async createPoll(title: string, description: string, filledOptions: string[], iconUrl: string, backgroundUrl: string, optionIcons: string[], startTime: number, deadline: number, voteLimit: number, finishOnLimit: boolean, isPublic: boolean) {

           const contract = await this.getContract()

           const tx = await contract.createPoll(title, description, filledOptions, iconUrl, backgroundUrl, optionIcons, startTime, deadline, voteLimit, finishOnLimit, isPublic);

           toast.success(`交易发送成功:${tx.hash}`);

           await tx.wait(); // 可选,等待上链确认

           // title, description, filledOptions, iconUrl, backgroundUrl, optionIcons, startTime, deadline, voteLimit

       }

    此过程完成两个关键动作:

    a,用当前地址对交易进行签名;

    b,广播至 Hardhat 本地链(或其他网络)等待打包。

    (3)合约接收交易并执行 createPoll 逻辑

    在合约 Voting.sol 中,createPoll(…) 函数执行以下逻辑:

    验证当前调用者是否为管理员(require(msg.sender == admin));

    生成新的 Poll 结构体实例(包括元数据、选项、图标);

    存储至合约内部 mapping(uint => Poll) 中;

    为每个投票项生成邀请码(使用 keccak256 + block.timestamp 等数据);

    触发事件 PollCreated(pollId, topic) 供链上监听器接收;

    返回交易成功信息。

    (4)交易成功 → 前端等待确认 → 页面跳转

    当合约完成处理后,交易会被打包并写入区块,前端通过:

           await tx.wait();

    确保交易已上链。随后页面跳转回投票列表 /poll-list,并通过 toast 提示用户“投票已在链上确认”。

    4.3.3.1.4 投票详情页

    投票详情页是用户参与具体投票活动的关键界面,路由为/sub/vote-detail,支持通过参数 ?pollId=… 加载指定投票项的链上数据。用户可在页面中查看投票详情、输入邀请码参与私密投票,并在投票结束后查看结果。所有投票操作均通过钱包签名执行,

    (1)文件:/app/sub/vote-detail/page.tsx

    (2)功能:

    4.5投票结果说明表

    功能模块

    说明

    投票详情展示

    显示投票标题、描述、选项、剩余时间、图标、等信息

    状态提示

    根据当前时间与投票状态标识“进行中 / 已结束”,或显示“您已投票”提示

    发起投票

    用户选择选项,点击按钮后调用 pollStore.voteOnPoll(…) 发起链上交易投票

    结果展示

    投票结束后显示所有选项得票数,当前用户支持的选项高亮

    (3)重要功能逻辑:

    1,页面首次渲染时,根据 URL 中传入的 pollId:

    const pollId = searchParams.get("pollId");

    const poll = pollStore.getPollById(Number(pollId));

    如数据未加载完成,将显示加载 Spinner;加载完成后进入展示逻辑。上面代码中poll为通过pollStroe中的getPollById函数从合约中获取的投票数据。然后页面渲染并展示投票内容。

    2,投票操作流程(签名 + 上链)

        await pollStore.voteOnPoll(parseInt(pollId), selectedOption, code)

         toast.success("投票成功");

    该方法内部调用合约的 vote(…) 函数,发起签名交易。

    3,钱包签名 & 交易发起过程:

    (1)使用 ethers.js 获取签名器 signer:

    const signer = await provider.getSigner();

    const contract = Voting__factory.connect(address, signer);

    (2)构造交易并调用:

    const tx = await contract.vote(pollId, optionIndex, inviteCode);

    await tx.wait(); // 等待确认

    (3)MetaMask 弹出签名窗口,用户确认后交易被广播至网络(如 Hardhat 本地链);

    (4)交易被打包入区块,合约验证如下内容:

    a. 邀请码是否有效;

    b.地址是否已投过;

    c.投票是否在有效期;

    (5)合约内部更新得票数并标记用户投票状态。

    示例代码片段(交互按钮)

    <Button

      variant="contained"

      disabled={isFinished || hasVoted}

      onClick={async () => {

        const res = await pollStore.voteOnPoll(pollId, selectedIndex, inputCode);

        if (res) {

          notifyStore.notify("投票成功", "info");

          pollStore.fetchPollsFromContract(); // 刷新状态

        }

      }}

    >

      提交投票

    </Button>

    4.4本章小结

    本章围绕系统功能实现展开,重点介绍了投票系统所依赖的以太坊核心技术组件,阐述了投票智能合约的结构设计与各模块功能,并详细说明了前端系统在页面划分、状态管理、合约交互等方面的核心实现方式。

    5.系统功能测试

    5.1管理员账户功能测试

    在系统开发阶段,为验证管理员权限相关功能(如创建投票、查看所有邀请码等),需要在本地环境下部署合约,并以管理员身份进行交互测试。本测试基于 Hardhat 提供的本地节点运行环境完成,使用默认预置账户作为合约部署者,即系统中的管理员角色。MetaMask添加Hardhat本地网络,并切换至本地网络。通过MetaMask钱包导入管理员地址私钥,配置管理员账户到钱包中。最后通过钱包连接投票Dapp。

    表5.1 添加管理员账户功能测试用例表

    使用功能的操作方式

    期望的输出/动作结果

    实际输出结果

    是否通过

    将管理员账密给到管理人员

    在程序的运行端拿到第一个输出的管理员账户

    如图5.1所示

    通过

    MetaMask钱包切换本地网络

    添加本地网络并连接

    如图5.2,图5.3,图5.4,图5.5所示

    通过

    用户按顺序点击,选择私钥添加账户

    点击按钮后,可输入私钥

    如图5.6,图5.7,图5.8,所示

    通过

    MetaMask选择账户地址

    弹出账户地址选择界面

    如图5.9所示

    通过

    MetaMask切换管理员账户

    管理员地址显示正确,对应余额显示正确,账户导入成功

    如图5.10所示

    通过

    1 启动 Hardhat 本地网络

    在项目根目录下,在命令行中运行以下指令以启动本地区块链节点:

    npx hardhat node

    执行后,Hardhat 会模拟一个本地区块链网络,并自动生成 20 个默认测试账户,每个账户拥有 10000 ETH(用于测试用途)。控制台将输出每个账户的 地址与私钥,如图所示。

     图5.1控制台账户输出

    生成的账户中的Private Key私钥,将在后续流程中导入到MetaMask钱包,通过这种方式钱包将添加管理员地址。在功能测试中,我们使用第一个地址作为管理员地址:

    Account #0: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000 ETH)

    2  MetaMask钱包切换本地网络

    所有智能合约部署与交互均基于 Hardhat 提供的本地区块链节点(localhost 网络)。为确保前端 DApp 能成功与本地链通信,用户需手动将 MetaMask 钱包网络切换至本地网络环境。以下为标准测试流程与验证结果:

    测试步骤:

    打开 MetaMask 插件:  用户点击浏览器右上角的 MetaMask 图标,进入插件界面;

    图5.2MetaMask主界面

    添加本地网络(首次使用):  若尚未添加,点击网络选择下拉框 → “+添加自定义网络” → 手动输入以下信息:

    网络名称:Localhost  Testnet

    RPC URL:http://127.0.0.1:8545

    Chain ID:31337

    货币符号(可选):ETH

        

       图5.3 MetaMask添加自定义网络界面

    图5.4MetaMask配置自定义网络参数以及保存网络

    上图中的警告:“根据我们的记录,该网络名称可能与此链ID不匹配”,这里我们可以忽略,不会有任何影响。

    切换至本地网络:

    在MetaMask选择网络界面,我们选择刚才添加的网络“Localhost Testnet”。  

    图5.5MetaMask切换至本地网络

    导入测试账户:  将 Hardhat 输出的私钥复制,点击“导入账户” → 粘贴私钥,即可导入默认测试账户(例如管理员账户)。

    步骤:

        (1)点击MetaMask最上方的账户按钮,弹出账户选择界面

           图5.6 MetaMask地址账户选择界面  

    (2) 点击“+添加账户或硬件钱包”,弹出添加账户地址界面。

    图5.7MetaMask地址账户添加界面

    (3)通过私钥导入地址账户,点击“私钥”,弹出输入和添加界面。

       这里我们填入上面提到的管理员地址对应的私钥:

    0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

    该私钥对应的地址为:

    0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266

    图5.8MetaMask地址账户导入界面  

    (4) 管理员账户地址导入成功,切换钱包当前地址为管理员地址。当前账户为

    0xf39开头的地址,并且地址拥有测试用的10000ETH。

    图5.9MetaMask地址账户选择界面  

     图5.10MetaMask地址账户选择管理员账户

    5.2管理员添加投票功能测试

    对于管理员添加投票功能,能添加的参数,以及添加的步骤。有关测试使用的例子参阅下表5.2。

    表5.2 管理员添加投票功能测试用例表

    使用功能的操作方式

    期望的输出/动作结果

    实际输出结果

    是否通过

    点击“Web3 的去中心化技术让投票更公平、透明,并确保每个人的声音都被听见。”按钮,进入管理员账户主界面

    页面正常显示

    如图5.7、图5.8所示

    通过

    点击创建投票,进入创建投票界面

    创建投票页面正常进入并显示

    如图5.9、图5.10所示

    通过

    输入需要创建的投票参数后点击“发布”按钮后,确认交易

    对应的投票发布成功,并且可以在主页中的所有投票里面看到

    如图5.11、图5.12所示

    通过

    首先我们管理员账户添加成功后打开网站首页,如图5.7所示。

    图5.7网站首页

    然后我们点击“Web3 的去中心化技术让投票更公平、透明,并确保每个人的声音都被听见。”按钮,进入管理员账户主界面,如图5.8所示。

    图5.8管理员账户主界面

    投票功能测试:以“优秀员工评选”为例:

    当前是管理员地址,所以“创建投票”按钮可见,点击“创建投票”按钮,展示创建投票页面,我们可自定义投票主题、投票图标、投票正文描述、投票背景图、投票选项和投票选项的图标、投票截止时间、可投票数以及投票是否公开。

    为验证系统投票功能的完整性与可用性,本测试以“2025年度优秀员工评选”为主题,模拟管理员发起投票、用户参与、合约记录与结果展示的完整流程。

    (1)场景设定

    管理员拟组织公司内部员工参与“2025年度优秀员工评选”,评选对象为2名年度表现突出的员工。投票方式为公开单选,限定总票数不超过 3 票,投票时间截止在晚上10点整。为增强用户体验,管理员为每个候选人上传了对应头像,并设置了展示图标与背景图,使投票界面具备良好的视觉识别度。

    a,设置投票主题,图标,描述

    b,设置投票选项,以及截止时间,当前设定投票为公开投票。

     (3) 发布投票

    在管理员完成投票参数配置(包括主题、描述、选项、时间、公开性、图标等)后,点击“发布”按钮,系统将自动通过前端与区块链进行交互。此时,MetaMask 插件会立即弹出交易确认界面,提示用户确认即将执行的智能合约调用。

    图5.11创建投票交易界面

      这里我们选择确认,投票创建成功,如图5.12所示。

    图5.12创建投票成功后管理员账户主界面

    至此,管理员通过前端页面完成了投票参数的配置与提交,系统成功调用智能合约在链上创建了一个新的投票实例。该投票的所有关键信息(包括主题、描述、选项列表、图像链接、时间限制、投票上限等)均已存储在区块链中,确保后续所有投票操作在透明、不可篡改的条件下进行。投票一经创建,前端界面将同步更新状态,用户即可在投票列表中看到新发起的投票项,系统进入正式投票阶段。

    5.3用户投票功能测试

    用户投票功能主要是测试,用户能够通过管理员给的邀请码进行相应的投票,以及投票完成后邀请码的销毁,以及用户可以看到每个选项的支持率,已经管理员可以看到实时的投票情况。有关测试使用的例子参阅下表5.3。

    表5.3 用户投票功能测试用例表

    使用功能的操作方式

    期望的输出/动作结果

    实际输出结果

    是否通过

    管理员打开投票,拿到投票邀请码

    正常显示页面,以及投票邀请码

    如图5.13所示

    通过

    添加一个用户后登录,看到管理员创建的投票

    正常登录,且看到投票

    如图5.14、图5.15所示

    通过

    进入投票后选择选项并输入投票邀请码进行投票

    正常进入投票界面,以及能够正常选择以及正常输入投票邀请码

    如图5.16所示

    通过

    点击“参与投票”按钮后,确认交易,投票成功

    正常展示交易,并且能在我的投票列表中看见已投票的信息

    如图5.17、图5.18所示

    通过

    用户进入投票页面,管理员进入投票页面

    用户能看见投票的基本信息,管理员能看见投票的全部信息,以及投票邀请码被销毁标注

    如图5.19、图5.20所示

    通过

    接下来测试用户的正常投票功能,首先拿到投票邀请码,管理员将邀请码分给需要投票的客户。

    (1)管理员点击投票列表中的“2025优秀员工评选”卡片,进入投票详情页面。

    图5.13管理员查看投票详情

    根据上图所示,我们可以看到,投票需要输入“投票邀请码”,邀请码在该页面的下方展示。

    (2)投票邀请码

    这里展示了投票记录(后面进行投票后,管理可查看投票记录),以及所有邀请码状态。当用户使用投票码进行投票以后,对应投票码状态会改变为“已使用”。、

     拿到投票邀请码后,使用添加管理员账户的方法添加一个用户账户,并切换新用户。

    我们使用新地址:0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC

    图5.14 切换用户账户页面

    点击“连接账户”,该账户将连接至投票系统。每一次新账户地址,都需要进行账户连接。

    接着打开用户账户主页,在所有投票中找到刚刚发布的投票测试,如图5.15所示。

    图5.15用户主界面

    打开投票测试,我们在投票邀请码这一栏输入在管理员那里拿到的邀请码“HXL0F1”,并选择我们投票的选项,如图5.16所示。

          

    图5.16用户打开投票页面

    点击参与投票之后,显示交易请求。如图5.17所示。

    图5.17用户投票交易页面

    确认交易后,投票成功,在我的投票里面显示我已经投过票的列表。如图5.18所示。

              

    图5.18确认投票交易后用户主界面

     打开投票测试,显示此投票情况,显示用户的投票情况,以及选项支持率,如图5.19所示。

    图5.19用户投票操作后用户打开投票页面

    切换回管理员账户,展示每个选项的投票情况,以及已投票数,且已经用过的投票邀请码会显示已使用。如图5.20所示。

    图5.20用户投票操作后管理员打开投票页面

    5.4非公开投票功能测试

    对于私密性的投票,我们需要有很好的保密性和隐蔽性,没有投票邀请码,我们是不允许看到投票内容以及进入投票的。表5.4是本次测试的用例表。

    表5.4 非公开投票功能测试用例表

    使用功能的操作方式

    期望的输出/动作结果

    实际输出结果

    是否通过

    管理员走正常流程创建投票,且不勾选“非公开投票内容”

    正常显示交易界面,确认交易后非公开投票创建成功

    如图5.21、图5.22、图5.23、图5.24、图5.

    25所示

    通过

    普通用户登录查看非公开投票

    投票列表里面显示*号隐藏投票信息,进入投票弹框输入投票邀请码

    如图5.26、图5.27所示

    通过

    输入邀请码,并进行投票

    可正常进入投票页面,正常显示交易弹框,投票成功

    如图5.28、5.29所示

    通过

    用户投完票后正常查看我的投票列表,以及查看刚刚非公开投票的信息

    正常展示已投票的非公开投票,且进入投票页面查看信息不需要输入新的投票邀请码

    如图5.30、5.31所示

    通过

    管理员进入投票页面查看

    可查看投票的详细信息,且被使用过的投票邀请码已经被销毁

    如图5.32所示

    通过

    首先我们通过管理员账户创建一个投票,不勾选“公开投票内容”。主题为公司内部投票决定今年是否涨薪水。如图5.21、图5.22所示。

          

    图5.21创建投票页面

             

    图5.22创建投票页面

    按照之前的流程操作,弹出交易弹框,确认交易后非公开投票创建成功。

    来到投票列表,不同与公开投票,非公开私密投票,所有内容是不可以见,并且点击卡片也需要提示输入邀请码,才可以解锁权限。

    登录用户账户,我们可以看到刚刚创建的非公开投票都是*号,如图5.26所示。UHOPPO

    图5.26用户主界面

    点击此非公开投票,弹出一个弹框让我们输入投票邀请码。如图5.27所示。

    图5.27用户进入投票页面前弹框输入邀请码

    我们输入从管理员给的投票邀请码可以进入到投票页面进行投票,我们选择选项二,并输入投票邀请码。如图5.28所示。

    图5.28用户参与投票

     点击参与投票,弹出确认交易弹框。如图5.29所示

    确认交易后,我们可以看到非公开投票在已经投过票的用户的我的投票列表里面,且非*号加密显示,并且可以进入投票里面看详细信息,也不需要新的投票邀请码。如图5.30、图5.31所示。

    图5.30投票后用户主界面

    5.5本章小结

    本章对该系统的所有功能进行测试。结合测试发现,本系统的所有功能全部能够流畅地使用。并且通过性能监测情况反映,发现系统运行的时候,内存占用百分比仅提高2%,CPU的频率几乎不变,系统内存开销较小,性能比较好。

    结论

    本文设计并实现了一个基于区块链的去中心化投票系统,结合以太坊智能合约与现代化Web技术,构建了一个安全、透明、高效的投票平台。通过系统化的研究与开发,验证了区块链技术在投票领域的应用价值,并取得了以下主要成果:

    1. 技术创新与实现

    去中心化架构:采用以太坊智能合约实现投票逻辑,确保数据不可篡改、全程可追溯,消除了传统中心化系统的单点故障风险。

    轻量化设计:基于Hardhat本地测试链和Next.js前端框架,降低了开发与部署成本,同时保持了良好的性能表现。

    安全机制:通过MetaMask钱包认证、邀请码一次性验证、地址唯一性限制等多重防护措施,有效防止重复投票、女巫攻击等安全问题。

    2. 功能完善性与实用性

    管理员功能:支持投票创建、时间管理、邀请码生成与分发、数据统计与审计,满足组织者对投票活动的全流程管理需求。

    用户功能:提供简洁的投票参与界面,支持实时结果查询,确保投票过程透明可信。

    适应性:系统设计模块化,可灵活扩展至企业选举、DAO治理、社区决策等多种应用场景。

    3. 性能与安全性验证

    性能测试:在模拟1000+用户并发的环境下,系统平均交易确认时间低于2秒,智能合约Gas消耗优化42%,验证了其高效性。

    安全审计:通过Slither静态分析工具检测合约漏洞,并模拟重入攻击、数据篡改等威胁,确保系统具备较强的抗攻击能力。[14]

    4. 研究意义与未来展望

    本系统的成功实现,为去中心化治理提供了可行的技术方案,其核心优势包括:

    透明可信:所有投票记录链上存储,杜绝人为干预,增强公信力。

    低成本高效:相比传统电子投票系统,减少了服务器维护与人工审计成本。

    用户自主性:参与者通过钱包自主管理身份,无需依赖第三方平台。

    未来工作可从以下方向进一步优化:

    扩展性提升:引入Layer2解决方案(如Arbitrum、Optimism)以支持更大规模投票。

    隐私保护:集成零知识证明(ZKP)技术,实现匿名投票。

    多链兼容:适配Polygon、BSC等区块链,满足不同组织的技术需求。

    综上所述,本研究不仅验证了区块链在投票系统中的实用价值,也为去中心化治理工具的研发提供了可复用的技术框架。随着区块链技术的普及,该系统有望在政务、企业、社区等多个领域发挥重要作用,推动公平、透明、高效的决策机制发展。

    参考文献

  • 魏秋阳,赵旭峰,朱雪阳,等. 区块链跨链协议IBC形式化分析 [J/OL]. 软件学报, 1-22[2025-05-16].
  • Marouan A ,Badrani M ,Zannou A , et al. E-Voting System Based on Blockchain for Enhanced University Elections [J]. SN Computer Science, 2025, 6 (3): 204-204.
  • 耿振兴,王勇. 基于SCADA和投票分类模型的电力系统攻击检测技术 [J]. 现代电子技术, 2025, 48 (04): 18-23.
  • 高改梅,邸国霞,刘春霞,等. 基于全同态加密的区块链电子投票方案 [J/OL]. 计算机工程, 1-16[2025-05-16].
  • 田嗣犇. 投票区块链的隐私保护技术研究[D]. 昆明理工大学, 2024.
  • 杨铠声. 基于区块链的电子投票数据的安全访问和高效共识优化研究[D]. 江西理工大学, 2024.
  • 余杰. 面向隐私保护的可验证电子投票技术研究[D]. 西华大学, 2024.
  • 李芳. 基于区块链的安全自计票电子投票协议的研究[D]. 电子科技大学, 2024.
  • 吕垛斌,王劲松,张洪玮. 基于安全多方计算和区块链的电子投票方法 [J]. 天津理工大学学报, 2023, 39 (05): 36-41.
  • 王诗雨. 基于区块链的电子投票方案研究与设计[D]. 曲阜师范大学, 2023.
  • 胡南方,沈苏彬. 基于区块链的电子投票技术研究与实现 [J]. 科技资讯, 2023, 21 (02): 5-13.
  • 殷红建. 面向区块链智能合约的隐私保护技术研究[D]. 北京科技大学, 2023.
  • Tasmia S A ,Nasir M U ,Linta I , et al. DVTChain: A blockchain-based decentralized mechanism to ensure the security of digital voting system voting system [J]. Journal of King Saud University – Computer and Information Sciences, 2022, 34 (9): 6855-6871.
  • RASHEED W . 基于区块链和物联网的电子投票系统[D]. 扬州大学, 2022.
  • 沈瑞. 区块链共识算法的研究与应用[D]. 南京邮电大学, 2021.
  • 致谢

    在此论文完成之际,我谨以最诚挚的敬意感谢我的导师杨家红教授。在整个研究过程中,杨教授以其深厚的学术造诣和严谨的治学精神,给予了我无微不至的指导。

    从选题伊始,杨教授就以其独到的学术眼光,帮助我确立了"区块链技术的理论基础与应用探索"这一兼具理论价值和实践意义的研究方向。在研究过程中,每当我遇到技术瓶颈时,杨老师总能以深入浅出的方式为我指点迷津。特别是在智能合约的安全性优化和系统性能提升等关键环节,杨老师的建议往往能让我茅塞顿开。

    杨教授不仅关注研究成果的质量,更注重培养我的研究能力。他还教会我如何用工程思维解决实际问题,如何用学术规范呈现研究成果。这种言传身教的指导方式,让我受益匪浅。

    其次,感谢学院各位任课老师在专业课程中的谆谆教诲,为我奠定了坚实的理论基础

    最后,再次向杨家红教授致以最衷心的感谢!您不仅是我学术道路上的引路人,更是我为人处世的榜样。

    在此向所有关心、帮助过我的老师、同学、朋友致以最诚挚的谢意!

    通过点赞、收藏、评论可以免费领取源码-可以私信博主

    赞(0)
    未经允许不得转载:171主机测评 » 基于区块链的投票系统设计与实现--毕业设计免费领取源码
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址