使用solidity+web3.js+matemask写一个投票DAPP

422 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

需求和实现效果

1、每个账号只能投一票

2、记录一共有多少个候选人

3、记录每个候选人的票数

4、所有账户都能看到每一个候选人以及他们的得票情况

合约实现

需求一:

我们只需要使用mapping来记录每一个账户的投票情况,使用bool类型:

mapping(address => bool) public voters; //address为投票者账户,判断是否投票,并且为pubic公开。

需求二:

我们需要知晓候选人的基本信息,这时我们就需要使用结构体

struct CandidateInformat { 
uint id;
string name; // 候选人的名字
uint voteCount; //投票总数 }

使用一个变量来保存一共有多少候选人

uint public candidatesCount

使用id来查找候选人信息

mapping(uint => CandidateInformat) public candidateInformats

投票功能实现

主要有两个功能 1、添加候选人(添加候选人信息,候选人总人数加一) 2、投票(选择候选人,得票数加一)

    function addCandidate (string memory _name) private {
        candidatesCount ++; //候选人+1
        candidateInformats[candidatesCount] = CandidateInformat(candidatesCount, _name, 0);  //将信息添加进结构体中···
    }

投票就是在对应的候选人的voteCount加1,同时这个函数需要一个参数即给哪一个候选人投票,另外需要进行一些合法性检查: 候选人是有效的,投票人必须没有投过票。所以得使用require来返回错误信息

function vote (uint _candidateId) public {
      require(!voters[msg.sender],"候选人无效"); //msg.sender为当前操作者
      require(_candidateId > 0 && _candidateId <= candidatesCount);
      
      voters[msg.sender] = true;
      CandidateInformats[_candidateId].voteCount ++;
  }

事件

在用户投票之后,应该及时的刷新页面, 这就需要用到事件监听了 定义一个事件:

    // voted event
    event votedEvent ( 
        uint indexed _candidateId  
    );

在投票后写触发事件

emit votedEvent(_candidateId);//如果改变则事件被触发

完整合约:


//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

mapping(address => bool) public voters;

struct CandidateInformat {
    uint id;
    string name;  // 候选人的名字
    uint voteCount;
}
event votedEvent ( uint indexed _candidateId );
uint public candidatesCount

mapping(uint => CandidateInformat) public CandidateInformats

 function addCandidate (string memory _name) private {
        candidatesCount ++; //候选人+1
        candidateInformats[candidatesCount] = CandidateInformat(candidatesCount, _name, 0);  //将信息添加进结构体中···
    }
    
    
     function vote (uint _candidateId) public {
        require(!voters[msg.sender],"候选人无效"); //msg.sender为当前操作者
        require(_candidateId > 0 && _candidateId <= candidatesCount);
        
        voters[msg.sender] = true;
        candidates[_candidateId].voteCount ++;
    }
    
    emit votedEvent(_candidateId);

这是合约部分,详情可见登链社区