- pragma solidity >=0.7.0 <0.9.0;
- 7 K7 l2 ]2 J6 g/ }5 G
- //投票实验
- contract Ballot{
- struct Voter{0 V6 b9 q/ L2 y. Y
- uint weight;//投票(单票)权重8 o" Y/ e# n& M5 C
- bool voted;//是否投过票,true为投过票,bool类型默认值为false
- address delegate;//想要委托投票的节点地址,address默认值为0x0
- uint vote;//想要投票的节点的索引值(被投票节点信息用一维数组proposals存储)
- }
-
- struct Proposal{//被投票节点的相关参数
- bytes32 name;//被投票节点的姓名标识! u& O9 _# O k7 R8 F, n
- uint voteCount;//累积被投票数1 n4 ^ O( h. e& A( v- z4 E
- }+ I) T0 S' l+ s- k0 @
-
- address public chairperson;//投票管理员地址
- mapping(address => Voter) public voters;//地址对投票节点的信息的映射1 N9 ^2 c) r: ]; T% M- V: A2 L
- Proposal[] public proposals;//一维数组存储被投票节点信息
- 0 ^ K* E( N1 ~
- //构造方法、构造函数5 k7 k, Y' t2 L) D
- //solidity和其他语言不一样,构造函数仅在部署合约时调用一次,后续调用合约不调用其构造函数6 d) u Q/ u9 O9 D! s$ o
- //且一个合约只能有一个构造函数,不能进行构造函数重载
- constructor(bytes32[] proposalNames) public{
- chairperson = msg.sender;//将第一次调用该合约的节点设置为管理员
- voters[chairperson].weight = 1;//将管理员投票权置为1! @' Q" A, a! M j, @8 V
- . A; L+ M( q- D0 o; ?1 H5 s
- for(uint i=0; i<proposalNames.length; i++){
- //将所有被投票人姓名初始化进一维数组proposals,并将其对应票数初始化为0票
- //.push(),括号中内容需要强调数据类型,eg:arr.push(uint(6));
- proposals.push(Proposal({
- name:proposalNames[i],
- voteCount:02 Z+ ]: U. z+ g, P& P. r
- }));
- }+ i; ^: Z, H3 e3 K, J
- }; A6 ~) B4 v& @( E! n5 J
-
- //由管理员授权可投票节点 c0 [) J+ e7 | j. q, x
- function giveRightToVote(address voter) public{/ w. S; W0 [8 u) r0 o0 i
- //require中判断条件为false时,输出字符串"xxx...",异常会被抛出,程序执行会被挂起,
- //未消耗的gas会被退回,合约状态会回退到初始状态
- require(
- msg.sender == chairperson,"Only chairperson can give right to vote."
- );//执行此function的节点一定为管理员节点
- require(2 e8 [" N1 Y9 N& m
- !voters[voter].voted,"The voter already voted.": q6 Q: {0 ?; x; H6 Q8 `
- );//若voter没投过票- l, v, r1 {& j6 [
- require(voters[voter].weight == 0);7 ~9 b5 F" P- f4 P2 r. |
- //调用合约的人是管理员、待授权节点还没投过票、带授权节点投票权重为0时,进行授权9 z- y% {3 H* N6 X
- voters[voter].weight = 1;//上述三个require()均成立时,授权票数( `6 \8 c- T+ `9 a* [) [8 ?
- }
-
- //投票授权4 v1 f) }- |; m5 s& o S4 U& K
- function delegate(address to) public{
- Voter storage sender = voters[msg.sender];
- require(!sender.voted, "You already voted.");
- require(to != msg.sender,"Self-delegation is disallowed.");
- //sender满足的条件:要有投票权限、没有投过票、被授权节点不是自己6 _. l+ A# U4 J; x( ~+ _! Y$ r
- , y" D9 e$ Q9 X ~# r) o
- //判断代理节点地址是否为空:address(0)或者address(0x0)
- while(voters[to].delegate != address(0)){/ x2 A* [/ {9 v" A. \6 O+ J* N
- to = voters[to].delegate;//找到最终的代理节点% U7 [; T k1 G! j! q
- require(to != msg.sender,"Found loop in delegation.");//若代理节点最终是自己则回退到初始状态
- }
- 8 k/ k# r. ?5 t3 t4 k5 o) a
- sender.voted = true;//票权代理出去,状态改为已投票+ l8 k+ P1 o' f! i. X
- sender.delegate = to;//票权代理地址5 T% e( g% b8 f: g
- Voter storage delegate_ = voters[to];//取出代理节点状态6 m, R' w3 Y& ?, q
-
- //若代理节点已投过票,将新代理的票权投出去,反之则将代理节点票权加和
- if(delegate_.voted){
- proposals[delegate_.vote].voteCount += sender.weight;- |- L5 C! B! B* l# ?8 f
- }else{" D9 r) ]0 Q2 s0 i
- delegate_.weight += sender.weight;) `& m# \3 L6 W5 Z, e
- }
- }
- ! p4 _, ^7 z: D6 g! J0 I1 g
- function vote(uint proposal) public{8 i+ Q5 y: g) L
- Voter storage sender = voters[msg.sender];//通过地址获取对应投票信息
- require(!sender.voted,"Already voted.");//若sender未投过票
- sender.voted = true;//更改投票状态为已投过票, @" Z2 q" D7 c
- sender.vote = proposal;//保存已投票节点 q7 X) I! D. X; _3 B. Z$ X
- proposals[proposal].voteCount += sender.weight;//票权加和1 i" |0 n$ Q+ X( R/ _. u3 ~
- }6 F) W& b4 \( @2 C
- / |' F3 J9 t! T! w7 D4 c4 f* z
- //返回票数最多的节点在一维数组proposals中的索引
- function winningProposal() public view returns(uint winningProposal_){
- uint winningVoteCount = 0;
- for(uint p=0;p<proposals.length;p++){" }# K2 A1 [2 _+ t
- if(proposals[p].voteCount > winningVoteCount){: B/ v; e' M$ U" k# w
- winningVoteCount = proposals[p].voteCount;: m$ |+ S6 P* J, S- a: }
- winningProposal_ = p;( r$ @9 J% x* b
- }
- }
- } ^" A+ q2 \+ s
- //输出票数最多的节点name% e8 |3 k& ~- R& R$ x! C% X6 R' l8 g
- function winnerName() public view returns(bytes32 winnerName_){7 _3 A1 A- d( a! r( i8 P
- winnerName_ = proposals[winningProposal()].name;
- }
- }
solidity投票智能合约代码
BlockQ
发表于 2022-11-11 20:33:36
160
0
0
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
成为第一个吐槽的人