- pragma solidity >=0.7.0 <0.9.0;, u1 X0 V9 ?% l0 S) _5 \; T' i' c& p
- : J: c1 v- {" z4 d
- //投票实验
- contract Ballot{
- struct Voter{1 K. |7 a; f" K- R6 c. p- s! U
- uint weight;//投票(单票)权重
- bool voted;//是否投过票,true为投过票,bool类型默认值为false
- address delegate;//想要委托投票的节点地址,address默认值为0x05 q/ ~% Y1 e4 s& r7 m8 W+ N
- uint vote;//想要投票的节点的索引值(被投票节点信息用一维数组proposals存储)
- }
-
- struct Proposal{//被投票节点的相关参数5 W, H2 k' i+ h, H4 ]+ j8 k5 [7 o
- bytes32 name;//被投票节点的姓名标识
- uint voteCount;//累积被投票数
- }$ `9 f+ k7 B! F. G
- * a" ]! ^7 [" s. H; [1 C
- address public chairperson;//投票管理员地址7 x. r1 a! a& ^5 a
- mapping(address => Voter) public voters;//地址对投票节点的信息的映射
- Proposal[] public proposals;//一维数组存储被投票节点信息/ ~9 u: D$ x" M
- 5 A( H! s( Y" `6 D
- //构造方法、构造函数1 Q9 J# i" H. H( c4 F: r9 P
- //solidity和其他语言不一样,构造函数仅在部署合约时调用一次,后续调用合约不调用其构造函数
- //且一个合约只能有一个构造函数,不能进行构造函数重载
- constructor(bytes32[] proposalNames) public{2 z7 ^3 E& \7 v8 q6 ~/ ]
- chairperson = msg.sender;//将第一次调用该合约的节点设置为管理员
- voters[chairperson].weight = 1;//将管理员投票权置为1- N+ B$ C/ @8 A3 l4 j
- T7 ]% }3 E. X s( U/ u+ }5 E& g
- for(uint i=0; i<proposalNames.length; i++){
- //将所有被投票人姓名初始化进一维数组proposals,并将其对应票数初始化为0票
- //.push(),括号中内容需要强调数据类型,eg:arr.push(uint(6));+ @( v7 R9 n: \1 D7 u4 d& m' M: L
- proposals.push(Proposal({
- name:proposalNames[i],
- voteCount:08 ^: r. p! e2 F' A, K3 e
- }));' M' }1 R+ S* `, \" u
- }
- } Q9 e- m- v3 [) F, z2 h3 g
- # u& f' Q- m/ d4 q- g
- //由管理员授权可投票节点" H, A* C' u! ^0 P, o5 e9 R
- function giveRightToVote(address voter) public{% O& A4 [8 y; f& J7 e
- //require中判断条件为false时,输出字符串"xxx...",异常会被抛出,程序执行会被挂起,
- //未消耗的gas会被退回,合约状态会回退到初始状态9 J( ~, @; l6 m( w- E
- require(
- msg.sender == chairperson,"Only chairperson can give right to vote."& x% h/ F( H M; D
- );//执行此function的节点一定为管理员节点
- require(
- !voters[voter].voted,"The voter already voted."
- );//若voter没投过票/ a/ C$ C0 W& m3 X
- require(voters[voter].weight == 0);& i; R9 r+ V, g( Q' |3 r
- //调用合约的人是管理员、待授权节点还没投过票、带授权节点投票权重为0时,进行授权+ w7 t7 ~0 a6 N
- voters[voter].weight = 1;//上述三个require()均成立时,授权票数8 E, h/ t- k( d! B6 V6 i
- }% ^5 n5 _2 T# R
- / k7 z: Q8 r0 N0 |- c
- //投票授权
- function delegate(address to) public{6 |. p5 g9 E2 D% k4 N5 m
- Voter storage sender = voters[msg.sender];. l( _6 v. L i- K* q; \4 w2 }
- require(!sender.voted, "You already voted.");, J; f5 t4 l; x b& U: Q0 f! U* U
- require(to != msg.sender,"Self-delegation is disallowed.");+ D6 r! F8 e6 m& F
- //sender满足的条件:要有投票权限、没有投过票、被授权节点不是自己
- 8 `- I$ t7 \# e. F2 o# m( X
- //判断代理节点地址是否为空:address(0)或者address(0x0)3 ?. Y# Q. \9 z% c" F
- while(voters[to].delegate != address(0)){7 F9 I2 T9 v6 M$ a% M, Y% {
- to = voters[to].delegate;//找到最终的代理节点+ l4 a- s8 B* g1 U/ ^3 v
- require(to != msg.sender,"Found loop in delegation.");//若代理节点最终是自己则回退到初始状态4 ~4 F; W4 `: \8 ?" `
- }! i! S o: @* s* h
- 8 t9 i8 ]; ^8 x* h) q* W# m% X
- sender.voted = true;//票权代理出去,状态改为已投票8 \6 X- y6 L7 A g0 w
- sender.delegate = to;//票权代理地址
- Voter storage delegate_ = voters[to];//取出代理节点状态
-
- //若代理节点已投过票,将新代理的票权投出去,反之则将代理节点票权加和
- if(delegate_.voted){
- proposals[delegate_.vote].voteCount += sender.weight;
- }else{5 Q" h- ~1 [* Z% _2 r2 U! z
- delegate_.weight += sender.weight;4 P7 T& K* X6 T; C# B7 U- y) x* z, i
- }1 j4 J7 }/ X; v" y
- }
-
- function vote(uint proposal) public{
- Voter storage sender = voters[msg.sender];//通过地址获取对应投票信息7 |4 ^$ I( L1 E" w+ c9 T
- require(!sender.voted,"Already voted.");//若sender未投过票
- sender.voted = true;//更改投票状态为已投过票& v$ s4 y* k' [( G! H2 e
- sender.vote = proposal;//保存已投票节点 F0 I( i5 ~- s
- proposals[proposal].voteCount += sender.weight;//票权加和$ P* q1 B! z# u# Q0 f( B
- }
- - |9 e2 u6 w5 P, p& q
- //返回票数最多的节点在一维数组proposals中的索引
- function winningProposal() public view returns(uint winningProposal_){
- uint winningVoteCount = 0;
- for(uint p=0;p<proposals.length;p++){
- if(proposals[p].voteCount > winningVoteCount){
- winningVoteCount = proposals[p].voteCount;" g9 Q% v/ P( F; M) O) X
- winningProposal_ = p;
- }
- }
- }+ f8 [# z0 _+ W% L/ Q
- //输出票数最多的节点name
- function winnerName() public view returns(bytes32 winnerName_){
- winnerName_ = proposals[winningProposal()].name;- }5 s _* R3 _* I( b7 [6 w$ S
- }2 s1 y) Y- U3 A" p( i7 g' D; R- Z4 q2 h3 D
- }
solidity投票智能合约代码
BlockQ
发表于 2022-11-11 20:33:36
184
0
0
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
成为第一个吐槽的人