Example地址:https://solidity.readthedocs.io/en/develop/solidity-by-example.html#voting

Voting程序的功能:

这个智能合约实现了一种在区块链上公开投票的功能。

部署该智能合约的人称为chairperson(主席),主席的作用为:

1. 在合约部署时,创建一系列proposals(提案),供大家投票

2. 在合约部署后,主席有权邀请人来投票,对应于代码中的giveRightToVote(address)方法

投票者(包括主席和其他参与投票的人)的投票权重均为1,他们可以:

1. 给一个提案投票(每人只有一票,只能投一个提案)

2. 也可以将自己的投票权委托给另一个投票者,则被委托人的投票权重变为2(票数还是1,只能投一个提案),如果被委托人还没投票,则当他投票时,一票抵两票;如果被委托人已经投票,则给他所投的提案再加一票。

在区块链上实现这个功能的好处为:投票过程公开透明,不可篡改

程序分析:

pragma solidity ^0.4.;

/// 委托投票
contract Ballot {
// 投票人结构体
struct Voter {
uint weight; // 投票权重(可通过委托增加)
bool voted; // 是否已投票标识 ture-已投,false-未投
address delegate; // 委托人(可以委托另一人带自己投票)
uint vote; // 所投的提案(提案数组的下标)
} // 提案结构体
struct Proposal {
bytes32 name; // 提案名(最长32byte)
uint voteCount; // 累计票数
} address public chairperson; //主席(合约创建人地址) //声明一个投票人字典,类似python中的字典数据结构 voters = {addr1: voter1, addr2: voter2, addr3: voter3}
mapping(address => Voter) public voters; // 用于储存Proposal结构体的可变长数组
Proposal[] public proposals; /// 构造函数,只执行一次,传入提案数组
function Ballot(bytes32[] proposalNames) public {
chairperson = msg.sender; // 主席被初始化为delopy合约的人
voters[chairperson].weight = ; // 主席的权重为1 // 初始化提案数组为:名称 + 初始票数(0)
for (uint i = ; i < proposalNames.length; i++) {
// `Proposal({...})` 创建一个临时的Proposal对象
// `proposals.push(...)` 将其push进proposals数组中
proposals.push(Proposal({
name: proposalNames[i],
voteCount:
}));
}
} // 给予投票人投票的权利
function giveRightToVote(address voter) public {
// 通过require来做输入检查,如require中的运算结果为false,则合约终止运行,且不改变状态变量的值,退回gas消耗(旧版本可能没实现,新版本将实现)
require(
(msg.sender == chairperson) && //主席才能执行该方法
!voters[voter].voted && // 投票人没投过票
(voters[voter].weight == ) // 投票人权重为0
);
voters[voter].weight = ; //给投票人赋权重为1
} /// 将自己投票权给另一人 `to`.
function delegate(address to) public {
// 声明Voter sender为引用类型变量,意味着在delegate()方法内对sender做的改变将会传递到方法外
Voter storage sender = voters[msg.sender];
require(!sender.voted); //要求sender在转让投票权前,自己未投票 // 不能将投票权转移给自己
require(to != msg.sender); // 当投票代表`to`也委托给别人时,寻找到最终的投票代表,将投票权转让
// 通常来说,这样的循环结构有点危险,如果执行时间长,可能会将gas消耗殆尽,gas消耗完时合约可能不执行或被卡住.
while (voters[to].delegate != address()) {
to = voters[to].delegate; // 有可能死循环,加以下检查.
require(to != msg.sender);
} // 通过引用传递修改voters[msg.sender]的属性,投票权被转让后标记为已投票
sender.voted = true;
sender.delegate = to; Voter storage delegate_ = voters[to];
if (delegate_.voted) {
//如果委托的投票代表已经投票了,直接修改票数
proposals[delegate_.vote].voteCount += sender.weight;
} else {
//如果投票代表还没有投票,则修改其投票权重。
delegate_.weight += sender.weight;
}
} /// 投出你的选票(包括委托给你的选票)
function vote(uint proposal) public {
Voter storage sender = voters[msg.sender];
require(!sender.voted);
sender.voted = true;
sender.vote = proposal; // If `proposal` is out of the range of the array,
// this will throw automatically and revert all
// changes.
//数组下标越界自动报错
proposals[proposal].voteCount += sender.weight;
} /// 根据当前所有的投票计算出当前的胜出提案.
// view关键字代表不对状态变量进行更新操作(但可以查看),会减少gas消耗
function winningProposal() public view
returns (uint winningProposal_)
{
uint winningVoteCount = ;
for (uint p = ; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal_ = p;
}
}
} //获得胜出提案的名称
function winnerName() public view
returns (bytes32 winnerName_)
{
winnerName_ = proposals[winningProposal()].name;
}
}

Solidity by Example详解 - Voting的更多相关文章

  1. 详解 Solidity 事件Event - 完全搞懂事件的使用

    很多同学对Solidity 中的Event有疑问,这篇文章就来详细的看看Solidity 中Event到底有什么用? 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊. ...

  2. truffle使用详解

    truffle使用详解 truffle是什么 Truffle测试环境 安装truffle truffle项目结构解析 文件编译 truffle的配置文件 移植 与合约进行交互 1.truffle是什么 ...

  3. django用户投票系统详解

    投票系统之详解 1.创建项目(mysite)与应用(polls) django-admin.py startproject mysite python manage.py startapp polls ...

  4. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  5. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  6. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

  7. Java 字符串格式化详解

    Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...

  8. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  9. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

随机推荐

  1. git 版本控制的简单应用

    一.通过 honebrew 安装git , 教程参考:http://brew.sh/index_zh-cn.html 也可对比参考:http://book.51cto.com/art/201107/2 ...

  2. 开源项目-网上公开http代理爬取、简单分类

    爬取网上公开免费代理(http/socks),解析入库,可满足需要切换IP的场景(爬虫.投票等)需求. 项目地址: https://github.com/Jwnie/proxyservice 1.采用 ...

  3. B站标题/子标题/url爬取示例(requests+re)

    #coding:utf-8 __author__ = "zhoumi" 3 import requests import re import urllib ''' 本文档目的在于获 ...

  4. SpringMvc出现Jsp页面不能正常解析成html网页

    <!-- Spring mvc配置 --> <servlet> <servlet-name>springMvc</servlet-name> <s ...

  5. CentOS7上安装并配置Nginx、PHP、MySql

    一.Nginx 1.安装nginx yum install nginx 2.启动nginx systemctl start nginx 除了systemctl start nginx之外,常用的相关命 ...

  6. Qt 5.9.4 如何静态编译和部署?

    Qt 5.9.4 如何静态编译和部署? MSVC2015 x86 静态编译 Qt 部署静态库 VS2015 部署静态库 1. MSVC2015 x86 静态编译 1.1 Qt 官网下载最新源代码 立即 ...

  7. SDL 2.0 如何在 windows 上使用?

    https://wiki.libsdl.org/APIByCategory http://adolfans.github.io/sdltutorialcn/sdl-2-dot-0-tutorial-i ...

  8. python开发concurent.furtrue模块:concurent.furtrue的多进程与多线程&协程

    一,concurent.furtrue进程池和线程池 1.1 concurent.furtrue 开启进程,多进程&线程,多线程 # concurrent.futures创建并行的任务 # 进 ...

  9. Fabric单节点安装备忘

    安装文档:http://www.cnblogs.com/studyzy/p/7437157.html 安装上面的文档安装成功,但是过程中遇到一些问题. 一.go的源码包可能下载不下来,因为被墙,go官 ...

  10. 总结MySQL大数据量下如何进行优化

    写在建库前: 在确定数据库业务后.建立数据库表格时,就应对一些常见问题有所考虑,以避免在数据增长一段时间后再做应对,可能造成时间及维护成本增加: 数据的月增量,年增量 数据的快速增长点 是否需要触发器 ...