本报告详细记录了一个小型区块链应用的实验过程,旨在探索区块链技术在解决特定实际问题中的可行性与优势,实验内容为设计并实现一个基于以太坊区块链的去中心化投票系统,报告涵盖了实验背景、目标、技术选型、系统设计、实现步骤、测试结果、遇到的问题与解决方案,以及对实验的总结与展望,通过本次实验,我们深入理解了智能合约的编写与部署流程,体验了区块链应用的构建方法,并对区块链的去中心化、透明性和不可篡改性等特性有了直观的认识。
实验背景与目标
1 实验背景 随着区块链技术的快速发展,其去中心化、数据不可篡改、透明可追溯等特性使其在金融、供应链、物联网、版权保护等多个领域展现出巨大潜力,对于初学者而言,区块链技术仍存在一定的入门门槛,为了更好地理解和掌握区块链技术的核心原理与应用开发方法,我们决定进行一个小型区块链应用实验。
2 实验目标
- 掌握至少一种主流区块链平台(如以太坊)智能合约的基本开发语言(如Solidity)和开发工具。
- 设计并实现一个具有实际应用场景的小型区块链应用——去中心化投票系统。
- 验证区块链技术在投票场景下的优势,如投票结果的透明性、防篡改性。
- 识别并解决实验过程中可能遇到的技术难题,积累区块链应用开发经验。
技术选型与工具
- 区块链平台: 以太坊(Ethereum) - 作为目前最成熟、生态最丰富的智能合约平台,拥有完善的开发工具和社区支持。
- 智能合约语言: Solidity - 以太坊最主流的智能合约编程语言,语法类似JavaScript,易于上手。
- 开发环境:
- Remix IDE: 在线集成开发环境,无需本地配置,支持Solidity代码编写、编译、部署和测试,非常适合初学者和小型项目。
- MetaMask: 浏览器插件钱包,用于与以太坊测试网络进行交互,管理账户和私钥。
- 测试网络: Ropsten 或 Sepolia - 以太坊的公共测试网络,可以免费获取测试以太坊(ETH)用于合约部署和交易测试。
- 版本控制: Git - 用于管理代码版本。
系统设计
1 需求分析 本去中心化投票系统主要需求如下:
- 创建投票: 指定用户(如投票发起人)可以创建一个新的投票主题,包含投票描述、选项列表、投票截止时间等。
- 参与投票: 系统中的用户(拥有以太坊账户)可以对已开放的投票进行投票,每个用户对每个选项只能投票一次。
- 查询投票: 任何人都可以查询当前所有投票的详细信息,包括投票主题、选项、各选项得票数、投票状态(进行中/已结束)等。
- 投票结果: 投票截止后,系统自动公布最终投票结果,且结果不可篡改。
2 智能合约设计
我们将核心逻辑封装在一个名为 VotingSystem 的智能合约中,合约主要功能模块及状态变量设计如下:
-
状态变量:
votingOwner: address - 记录投票合约的部署者/发起人。votings: mapping(uint256 => Voting) - 存储所有投票信息的映射,键为投票ID,值为投票结构体。votingCount: uint256 - 已创建投票的总数,用于生成唯一投票ID。voters: mapping(uint256 => mapping(address => bool)) - 记录每个投票中哪些用户已经投过票,防止重复投票。
-
投票结构体 (Voting):
title: string - 投票标题。description: string - 投票描述。options: string[] - 投票选项数组。votesCount: uint256[] - 每个选项对应的得票数数组。deadline: uint256 - 投票截止时间戳。isFinished: bool - 投票是否已结束。
-
事件 (Events):
VotingCreated(uint256 votingId, string title, address creator)- 投票创建事件。Voted(uint256 votingId, address voter, uint256 optionIndex)- 投票事件。
-
核心函数:
constructor()- 合约构造函数,初始化votingOwner。createVoting(string memory _title, string memory _description, string[] memory _options, uint256 _deadline)- 由votingOwner调用,创建新投票。vote(uint256 _votingId, uint256 _optionIndex)- 由用户调用,对指定投票的指定选项进行投票。getVoting(uint256 _votingId)- 查询指定投票的详细信息。getVotingsCount()- 获取已创建投票的总数。finishVoting(uint256 _votingId)- (可选)由votingOwner或合约逻辑在截止后自动标记投票结束,本实验中采用在vote函数中自动判断截止时间。
实现步骤
-
环境搭建:
- 安装并配置MetaMask浏览器插件,切换到以太坊测试网络(如Sepolia),获取测试ETH。
- 打开Remix IDE(https://remix.ethereum.org/)。
-
智能合约编写:
- 在Remix IDE中创建一个新的
.sol文件(如VotingSystem.sol)。 - 根据上述系统设计,使用Solidity语言编写
VotingSystem智能合约的代码,注意处理边界条件,如投票选项索引越界、重复投票、投票已截止等。
- 在Remix IDE中创建一个新的
-
编译合约:
在Remix IDE的“Compile”标签页,选择合适的Solidity编译版本(如0.8.7),点击“Compile VotingSystem.sol”按钮,确保编译无错误。
-
部署合约:
- 切换到“Deploy & Run Transactions”标签页。
- 在“ENVIRONMENT”下拉菜单中选择“Injected Provider - MetaMask”,此时Remix会连接到MetaMask钱包。
- 确认MetaMask显示的是正确的测试网络和账户。
- 点击“Deploy”按钮,MetaMask会弹出交易确认窗口,确认并支付少量 gas 费用,合约部署成功后,会显示合约地址。
-
测试合约功能:
- 在部署成功的合约实例下,使用Remix IDE的“Deployed Contracts”区域调用合约的各个函数进行测试。
- 创建投票: 调用
