Voting 投票

思路是为每张选票创建一个合约,每个投票选项提供一个短名称。合约创建者作为会长将会给每个投票参与人各自的地址投票权。

地址后面的人们可以选择自己投票或者委托信任的代表人替他们投票。在投票结束后,winningProposal()将会返回获得票数最多的提案。

/// @title Voting with delegation.
/// @title 授权投票
contract Ballot
{
// 这里声明了复杂类型
// 将会在被后面的参数使用
// 代表一个独立的投票人。
struct Voter
{
uint weight; // 累积的权重。
bool voted; // 如果为真,则表示该投票人已经投票。
address delegate; // 委托的投票代表
uint vote; // 投票选择的提案索引号
} // 这是一个独立提案的类型
struct Proposal
{
bytes32 name; // 短名称(32字节)
uint voteCount; // 累计获得的票数
}
address public chairperson;
//这里声明一个状态变量,保存每个独立地址的`Voter` 结构
mapping(address => Voter) public voters;
//一个存储`Proposal`结构的动态数组
Proposal[] public proposals; // 创建一个新的投票用于选出一个提案名`proposalNames`.
function Ballot(bytes32[] proposalNames)
{
chairperson = msg.sender;
voters[chairperson].weight = 1; //对提供的每一个提案名称,创建一个新的提案
//对象添加到数组末尾
for (uint i = 0; i < proposalNames.length; i++)
//`Proposal({...})` 创建了一个临时的提案对象,
//`proposal.push(...)`添加到了提案数组`proposals`末尾。
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
} //给投票人`voter`参加投票的投票权,
//只能由投票主持人`chairperson`调用。
function giveRightToVote(address voter)
{
if (msg.sender != chairperson || voters[voter].voted)
//`throw`会终止和撤销所有的状态和以太改变。
//如果函数调用无效,这通常是一个好的选择。
//但是需要注意,这会消耗提供的所有gas。
throw;
voters[voter].weight = 1;
} // 委托你的投票权到一个投票代表 `to`。
function delegate(address to)
{
// 指定引用
Voter sender = voters[msg.sender];
if (sender.voted)
throw; //当投票代表`to`也委托给别人时,寻找到最终的投票代表
while (voters[to].delegate != address(0) &&
voters[to].delegate != msg.sender)
to = voters[to].delegate;
// 当最终投票代表等于调用者,是不被允许的。
if (to == msg.sender)
throw;
//因为`sender`是一个引用,
//这里实际修改了`voters[msg.sender].voted`
sender.voted = true;
sender.delegate = to;
Voter delegate = voters[to];
if (delegate.voted)
//如果委托的投票代表已经投票了,直接修改票数
proposals[delegate.vote].voteCount += sender.weight;
else
//如果投票代表还没有投票,则修改其投票权重。
delegate.weight += sender.weight;
} ///投出你的选票(包括委托给你的选票)
///给 `proposals[proposal].name`。
function vote(uint proposal)
{
Voter sender = voters[msg.sender];
if (sender.voted) throw;
sender.voted = true;
sender.vote = proposal;
//如果`proposal`索引超出了给定的提案数组范围
//将会自动抛出异常,并撤销所有的改变。
proposals[proposal].voteCount += sender.weight;
} ///@dev 根据当前所有的投票计算出当前的胜出提案
function winningProposal() constant
returns (uint winningProposal)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++)
{
if (proposals[p].voteCount > winningVoteCount)
{
winningVoteCount = proposals[p].voteCount;
winningProposal = p;
}
}
}
}

  

Solidity 编程实例--投票的更多相关文章

  1. Solidity 文档--第三章:Solidity 编程实例

    Solidity 编程实例 Voting 投票 接下来的合约非常复杂,但展示了很多Solidity的特性.它实现了一个投票合约.当然,电子选举的主要问题是如何赋予投票权给准确的人,并防止操纵.我们不能 ...

  2. Solidity 编程实例--Blind Auction 盲拍

    接下来扩展前面的公开拍卖成为一个盲拍.盲拍的特点是拍卖结束以前没有时间压力.在一个透明的计算平台上创建盲拍系统听起来可能有些矛盾,但是加密算法能让你脱离困境. During the bidding p ...

  3. Solidity 编程实例--简单的公开拍卖

    通常简单的公开拍卖合约,是每个人可以在拍卖期间发送他们的竞拍出价.为了实现绑定竞拍人的到他们的拍卖,竞拍包括发送金额/ether.如果产生了新的最高竞拍价,前一个最高价竞拍人将会拿回他的钱.在竞拍阶段 ...

  4. PHP多进程编程实例

    这篇文章主要介绍了PHP多进程编程实例,本文讲解的是在Linux下实现PHP多进程编程,需要的朋友可以参考下 羡慕火影忍者里鸣人的影分身么?没错,PHP程序是可以开动影分身的!想完成任务,又觉得一个进 ...

  5. c#摄像头编程实例 (转)

    c#摄像头编程实例 摄像头编程 安装摄像头后,一般可以找到一个avicap32.dll文件 这是一个关于设想头的类 using  system;using  System.Runtime.Intero ...

  6. JAX-RS 2.0 REST客户端编程实例

    JAX-RS 2.0 REST客户端编程实例 2014/01/28 | 分类: 基础技术, 教程 | 0 条评论 | 标签: JAX-RS, RESTFUL 分享到:3 本文由 ImportNew - ...

  7. Android studio 下JNI编程实例并生成so库

    Android studio 下JNI编程实例并生成so库 因为公司需要为Android相机做美颜等图像后期处理,需要使用JNI编程,最近学了下JNI,并且在Android Studio下实现了一个小 ...

  8. hadoop2.2编程:使用MapReduce编程实例(转)

    原文链接:http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.html 从网上搜到的一篇hadoop的编程实例,对于初学者真是帮助太大 ...

  9. python学习_数据处理编程实例(二)

    在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...

随机推荐

  1. 希尔排序的正确性 (Correctness of ShellSort)

    学希尔排序的时候,觉得有序性保持的性质十分神奇,但哪里都找不到数学证明.最后在Donald E. Knuth的The Art of Computer Programming中找到了(显然我没有读过这套 ...

  2. MAMP 访问时显示文件列表

    原文链接:他叫自己MR张 背景 MAMP是Mac下的一个PHP+Nginx+MySQL的集成环境,支持多站点,不同版本PHP. 今天有人请教MAMP如何显示文件列表的问题,这里记录一下. 知识补充 一 ...

  3. linux部署html代码到linux服务器,并进行域名解析

    本博客主要是说一下,如何将本地写好的html代码部署到linux服务器,并进行解析.下一篇博客将写一下,如何将html代码部署到阿里云服务器,并进行域名解析,以及在部署过程中遇到的问题和解决方法. 1 ...

  4. 基于STM32F429的TFT0.96屏幕驱动

    1.介绍TFT 2.Cube配置  该屏幕是用SPI通信的,但没有MISO引脚,意思是说该屏幕只能接收数据,但无法读取里面的数据,理论上说四线就能启动,但我弄不出,只能用六线. 在Cube上只要开启六 ...

  5. 去重合并两个有序链表之直接操作和Set集合操作

    两者思路对比: 直接操作:因为传入的是两个有序的链表,所以说我就直接以其中一个链表为基准,与另外一个链表比较,只将比返回值链表的最后一个记录的值大的插入,不将等值的插入,理论时间复杂度为O(n) Se ...

  6. Android图片的缩放效果

    一.概述 Android 图片要实现:手势滑动,双击变大,多点触控的效果. 其实是有一定难度的,我们需要用Matrix ,GestureDetector 等等需要完成一个复杂的逻辑才能实现,然而今天我 ...

  7. Spring Boot (二):模版引擎 Thymeleaf 渲染 Web 页面

    Spring Boot (二):模版引擎 Thymeleaf 渲染 Web 页面 在<Spring Boot(一):快速开始>中介绍了如何使用 Spring Boot 构建一个工程,并且提 ...

  8. .Net基础篇_学习笔记_第五天_流程控制while循环003

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  9. JAVA父类的静态方法能否被子类重写?

    静态: 在编译时所分配的内存会一直存在(不会被回收),直到程序退出内存才会释放这个空间,在实例化之前这个方法就已经存在于内存,跟类的对象没什么关系.子类中如果定义了相同名称的静态方法,并不会重写,而应 ...

  10. Python集训营45天—Day04 (函数)

    目录 1. 函数介绍 2. 函数的参数 3. 模块与函数 4. 递归函数 5. 匿名函数 6. 多返回值 python 的学习已经进入到第四天,前面几章我们已经学会了基本的变量操作,以及分支结构和循环 ...