- pragma solidity >=0.7.0 <0.9.0;9 D# Q2 }; D6 c/ b. I. o! v
- + e8 o# f& h( p; ~1 V! m8 @ M5 V- `
- //投票实验2 b4 e+ T: E, D9 ^( A, i. k' T2 c
- contract Ballot{
- struct Voter{/ c0 u6 M1 o$ I5 h' z+ Z
- uint weight;//投票(单票)权重0 d( @# u) F9 w6 }" N# L& h0 f0 R
- bool voted;//是否投过票,true为投过票,bool类型默认值为false( E" C' Z7 T) A
- address delegate;//想要委托投票的节点地址,address默认值为0x09 M' u! h) ]/ ^ d
- uint vote;//想要投票的节点的索引值(被投票节点信息用一维数组proposals存储)
- }
- . Q- z& D: ]3 m6 ]4 w, u9 G
- struct Proposal{//被投票节点的相关参数2 S- c* y n1 O: h
- bytes32 name;//被投票节点的姓名标识) W0 t1 C/ n( J+ j
- uint voteCount;//累积被投票数( [) x( P- @/ ~* V) h9 w% D
- }. I: N% U/ w# } n& w* p* L" b- x
-
- address public chairperson;//投票管理员地址: N; z/ @) L% h# @$ k
- mapping(address => Voter) public voters;//地址对投票节点的信息的映射4 s' a, R7 N+ c6 Q2 ?$ D+ t2 ]$ R
- Proposal[] public proposals;//一维数组存储被投票节点信息+ }0 ^5 x8 [7 e0 U4 D
-
- //构造方法、构造函数
- //solidity和其他语言不一样,构造函数仅在部署合约时调用一次,后续调用合约不调用其构造函数
- //且一个合约只能有一个构造函数,不能进行构造函数重载4 W& x2 |& u: [* a+ K
- constructor(bytes32[] proposalNames) public{2 ~$ O1 X' W/ G
- chairperson = msg.sender;//将第一次调用该合约的节点设置为管理员
- voters[chairperson].weight = 1;//将管理员投票权置为1- v& s( d8 g- J
- ( b9 z4 I' X0 L; o2 ^+ {
- for(uint i=0; i<proposalNames.length; i++){
- //将所有被投票人姓名初始化进一维数组proposals,并将其对应票数初始化为0票
- //.push(),括号中内容需要强调数据类型,eg:arr.push(uint(6));5 d8 s) a5 C- s& _
- proposals.push(Proposal({
- name:proposalNames[i],
- voteCount:0
- }));
- }* T; ?/ ?6 p8 b
- }
- / \3 \' A e9 W% V: ]
- //由管理员授权可投票节点
- function giveRightToVote(address voter) public{6 E8 j$ _1 f3 x! V: O- i
- //require中判断条件为false时,输出字符串"xxx...",异常会被抛出,程序执行会被挂起,
- //未消耗的gas会被退回,合约状态会回退到初始状态
- require(
- msg.sender == chairperson,"Only chairperson can give right to vote."
- );//执行此function的节点一定为管理员节点
- require(: T' c8 ^% Z% L, U! e
- !voters[voter].voted,"The voter already voted."( w/ H) w/ n o! r$ ]
- );//若voter没投过票
- require(voters[voter].weight == 0);# w4 Y) a9 f* ?
- //调用合约的人是管理员、待授权节点还没投过票、带授权节点投票权重为0时,进行授权
- voters[voter].weight = 1;//上述三个require()均成立时,授权票数
- }0 O' r# [/ k$ v0 Z
- 9 z0 k, g6 n- }- R
- //投票授权
- function delegate(address to) public{
- Voter storage sender = voters[msg.sender];
- require(!sender.voted, "You already voted.");6 q8 \4 x0 l) h2 L. w
- require(to != msg.sender,"Self-delegation is disallowed.");
- //sender满足的条件:要有投票权限、没有投过票、被授权节点不是自己
-
- //判断代理节点地址是否为空:address(0)或者address(0x0)
- while(voters[to].delegate != address(0)){0 V! [; d% p7 S( M1 t% m0 }( t
- to = voters[to].delegate;//找到最终的代理节点
- require(to != msg.sender,"Found loop in delegation.");//若代理节点最终是自己则回退到初始状态
- }1 I k1 r3 H+ f- r# }8 o
-
- sender.voted = true;//票权代理出去,状态改为已投票: Q6 L2 Y# s# V% p8 B/ P" a
- sender.delegate = to;//票权代理地址( f% L% M7 O; c# V* ?
- Voter storage delegate_ = voters[to];//取出代理节点状态# b0 k# N! ?" ?" Y+ B9 h1 L
- 7 I2 O6 |! g5 d
- //若代理节点已投过票,将新代理的票权投出去,反之则将代理节点票权加和
- if(delegate_.voted){
- proposals[delegate_.vote].voteCount += sender.weight;
- }else{* T0 A( g3 G. r
- delegate_.weight += sender.weight;
- }+ m7 {0 h; a2 @4 \2 ^0 B# ~
- }
- / D- X+ M2 O K6 p4 h5 }1 I
- function vote(uint proposal) public{. a8 F0 [% A" C) l* V# o
- Voter storage sender = voters[msg.sender];//通过地址获取对应投票信息
- require(!sender.voted,"Already voted.");//若sender未投过票7 }- y2 N+ p X$ Y1 Q2 S+ U1 j
- sender.voted = true;//更改投票状态为已投过票
- sender.vote = proposal;//保存已投票节点% C6 Z& P& |' q3 r0 q: T7 G
- proposals[proposal].voteCount += sender.weight;//票权加和
- }! W7 U H$ } U
- : j$ R$ C2 b0 x' S3 o" _
- //返回票数最多的节点在一维数组proposals中的索引
- function winningProposal() public view returns(uint winningProposal_){
- uint winningVoteCount = 0;
- for(uint p=0;p<proposals.length;p++){6 z& `4 E1 X+ e4 C! o4 x8 `$ \% W
- if(proposals[p].voteCount > winningVoteCount){: [/ R Y8 j Y2 `9 _6 R
- winningVoteCount = proposals[p].voteCount;
- winningProposal_ = p;
- }) l$ X4 B- ^7 I$ K& P
- }
- }
- //输出票数最多的节点name* p8 W5 h+ ?8 G
- function winnerName() public view returns(bytes32 winnerName_){
- winnerName_ = proposals[winningProposal()].name;
- }3 [ {7 T3 C9 {( W' ]
- }
solidity投票智能合约代码
BlockQ
发表于 2022-11-11 20:33:36
240
0
0
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
成为第一个吐槽的人