You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过新增合约实现多并行选举的管理与投票支持?

实现多场并行选举的合约设计方案

要支持多场选举同时进行,且允许选民参与所有选举,核心思路是创建一个选举管理/工厂合约,负责批量创建和管理独立的Election合约实例——每个实例对应一场独立选举,各自维护自身的候选人、选民授权与投票状态,天然支持选民跨多场选举参与投票。

原合约的问题分析

原Election合约的startElection函数是单实例初始化逻辑,无法同时运行多场;你写的ElectionList仅做简单地址映射,缺少创建和管理逻辑。我们需要重构为「工厂合约+独立选举实例」的模式。

解决方案代码

1. 选举管理合约(ElectionManager)

负责创建新选举、存储所有选举元数据,方便统一查询和管理:

//SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.5.0 <0.9.0;

import "./Election.sol";

contract ElectionManager {
    // 存储所有选举的核心信息
    struct ElectionInfo {
        address electionAddress;
        string electionName;
        address admin;
        bool isActive;
    }

    ElectionInfo[] public allElections;
    mapping(address => bool) public isElectionContract;

    // 创建新选举,调用者自动成为该选举的管理员
    function createElection(string calldata _electionName) external returns (address) {
        Election newElection = new Election(_electionName, msg.sender);
        allElections.push(ElectionInfo({
            electionAddress: address(newElection),
            electionName: _electionName,
            admin: msg.sender,
            isActive: true
        }));
        isElectionContract[address(newElection)] = true;
        return address(newElection);
    }

    // 获取当前存在的选举总数
    function getElectionCount() external view returns (uint) {
        return allElections.length;
    }

    // 标记选举为已结束(仅对应选举管理员可操作)
    function markElectionAsClosed(uint _electionIndex) external {
        require(_electionIndex < allElections.length, "无效的选举索引");
        ElectionInfo storage target = allElections[_electionIndex];
        require(msg.sender == target.admin, "仅该选举管理员可关闭");
        target.isActive = false;
    }
}

2. 重构后的选举合约(Election.sol)

将原startElection的初始化逻辑改为构造函数,确保每个合约实例创建时就绑定唯一的选举名称和管理员,避免重复初始化:

//SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.5.0 <0.9.0;

contract Election {
    struct Candidate {
        string name;
        uint numVotes;
    }

    struct Voter {
        string name;
        bool authorised;
        uint whom;
        bool voted;
    }

    address public owner;
    string public electionName;
    bool public electionStarted = true; // 合约创建即启动选举

    mapping(address => Voter) public voters;
    Candidate[] public candidates;
    uint public totalVotes;

    modifier ownerOnly() {
        require(msg.sender == owner, "仅管理员可操作");
        _;
    }

    // 构造函数:创建选举时直接初始化名称和管理员
    constructor(string memory _electionName, address _owner) {
        electionName = _electionName;
        owner = _owner;
    }

    function addCandidate(string memory _candidateName) ownerOnly external {
        candidates.push(Candidate(_candidateName, 0));
    }

    function authorizeVoter(address _voterAddress) ownerOnly external {
        voters[_voterAddress].authorised = true;
    }

    // 可选:允许选民自行设置姓名
    function setVoterName(string memory _name) external {
        voters[msg.sender].name = _name;
    }

    function getNumCandidates() external view returns (uint) {
        return candidates.length;
    }

    function vote(uint candidateIndex) external {
        require(!voters[msg.sender].voted, "你已在本次选举中投过票");
        require(voters[msg.sender].authorised, "你未获得本次选举的投票权限");
        require(candidateIndex < candidates.length, "无效的候选人索引");

        voters[msg.sender].whom = candidateIndex;
        voters[msg.sender].voted = true;

        candidates[candidateIndex].numVotes++;
        totalVotes++;
    }

    function getTotalVotes() external view returns (uint) {
        return totalVotes;
    }

    function candidateInfo(uint index) external view returns (Candidate memory) {
        require(index < candidates.length, "无效的候选人索引");
        return candidates[index];
    }

    function closeElection() ownerOnly external {
        electionStarted = false;
        // 清除候选人数据(可选,节省链上存储)
        uint n = candidates.length;
        for(uint i=0; i<n; i++){
            delete candidates[i];
        }
    }
}

核心逻辑说明

  • 独立选举实例:每调用一次ElectionManager.createElection,就生成一个全新的Election合约,各实例的数据(候选人、选民投票状态)完全隔离,选民可在不同选举合约中分别被授权、投票,天然支持参与多场选举。
  • 统一管理:ElectionManager存储所有选举的基本信息,方便前端或其他合约查询所有正在进行/已结束的选举。
  • 权限隔离:每场选举的管理员独立,只有对应管理员能添加候选人、授权选民、关闭选举,避免权限混乱。

内容的提问来源于stack exchange,提问作者Abhiram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:00:51