智能合约开发(4)——solidity实例

更新时间:2023-07-17 14:06:07 阅读: 评论:0

智能合约开发(4)——solidity实例
1.投票
这个合约⽐较复杂,但其中展⽰了很多的Solidity的特性。它实现了⼀个投票合约。电⼦投票的主要问题是如何给正确的⼈分配投票权,以及如何防⽌操纵。我们不会在这⾥解决所有问题,但我们会展⽰如何进⾏委派投票,以便记票⾃动且完全透明。
idea 是为每个选票创建⼀个合约,为每个投票提供⼀个短名称。合同的创造者作为主席将分别给予每个地址投票权。
地址背后的投票⼈可以选择他们⾃⼰进⾏投票或者委托投票权给他们信任的⼈。
投票时间结束的时候,winningProposal()将会返回获得票数最多的提案。
pragma solidity ^0.4.11;
//@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.nder;
voters[chairperson].weight = 1;
// 对提供的每⼀个提案名称
// 创建⼀个新的提案
// 对象添加到数组末尾
for (uint i = 0; i < proposalName.length; i++){
// 'Proposal({...})' 创建⼀个临时提案对象
// ‘proposals.push(...)' 添加到’proposal‘ 末尾
proposals.push(Proposal({
name:proposalName[i],
voteCount: 0
}));
}
}
// 给投票⼈’voter‘投票权
// 只能由主席’ chairperson' 调⽤
function giveRightToVote(address voter) {
//  如果 ‘ require‘ 计算结果为 ’fal‘
//  他将终⽌并返回所有更改
//  返回之前的状态和以太币
require((msg.nder == chairperson) && !voters[voter].voted && (voters[voter].weight == 0));
voters[voter].weight = 1;
voters[voter].weight = 1;
}
//委托你的投票权到⼀个投票代表’to‘
function delegate(address to){
// 指定引⽤
Voter storage nder = voters[msg.nder];//这⾥是引⽤的⽤法,nder表⽰内存中的这个结构        require(!nder.voted);//这句话是说这个⼈不能已经投过票了
// 不允许⾃⼰委托⾃⼰(不允许委托为调⽤者)。
require(to != msg.nder);
// Forward the delegation as long as
// 'to' also delegated
// ⼀般来说,这样的循环是⾮常危险的
// 因为如果它们运⾏时间太长
// 它们可能需要⽐block中可⽤的更多的gas
// 在这种情况下,delegation不会被执⾏
// 但在其他情况下,这样的循环
// 可能导致合约完全“卡住”
while (voters[to].delegate != address(0)) {
to = voters[to].delegate;
//我们在dele中发现了⼀个不被允许的循环
require(to != msg.nder);
}
// 因为’nder‘是⼀个引⽤
// 这⾥实际修改了’voters[msg.nder].voted'
nder.voted = true;
nder.delegate = to;
Voter storage delegate = voters[to];
if (delegate.voted){
// 如果委托的投票代表已经投票了,
// 则直接修改被投⼈的票数
proposals[delegate.vote].voteCount += nder.weight;
}el{
// 如果投票代表还没有投票
// 则修改其投票权重
delegate.weight += nder.weight;
}
}
// 投出你的选票(包括委托给你的选票)
// 给‘proposals[proposal].name'
function vote(uint proposal) {
Voter storage nder = voters[msg.nder];
require(!nder.voted);
nder.voted = true;
nder.vote = proposal;
// 如果’proposal‘索引超出了给定的提案数组范围,
// 将会⾃动抛出异常,并撤销所有的改变
proposals[proposal].voteCount += nder.weight;
}
// @dev 根据当前所有的投票计算出当前的胜出提案
function winningProposal() constant returns (uint winningProposal)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++){
winningVoteCount = proposals[p].voteCount;
winningProposal = p;
}
}
}
护理评价}
//调⽤WinningProposal() 函数得到
// 包含在提案数组中获胜者的index
// 并返回获胜者的名字
function winnerName() constant returns (butes32 winnerName)
{
winnerName = proposals[winningProposal()].name;
}
}
2 . 盲拍
在本节中,将展⽰在以太坊上创建盲拍合约是多么容易。我们将从⼀个每个⼈都可以看到出价公开的拍卖开始,然后将这个合约扩展到⼀个在竞标期结束之前不可能看到实际的出价的盲拍。
2.1 ⼀个简单的公开拍卖
以下简单拍卖合约的总体思路是每个⼈都可以在拍卖期间内发出他们的出价。为了保证竞拍⼈得到他们的竞拍,出价包括阿发送⾦
额/ether。如果出现了新的最⾼出价,之前的最⾼出价这就可以拿回她的钱了。在竞拍期结束后,受益⼈必须⼿动调⽤合约收取他的钱——合约不能激活⾃⼰。
pragma solidity ^0.4.11
contract SimpleAuction{
// 拍卖的参数
// 时间是unix绝对时间戳(⾃1970-01-01 以来的秒数)
// 或者是以秒为单位的出块时间
address public beneficiary;
uint public auctionEnd;
// 当前的拍卖状态
address public highestBidder;
uint public highestBid;
// 允许撤回之前的竞拍
mapping(address => uint) pendingReturns;
// 在结束时设置为trrue在拒绝任何改变
bool ended;
爱你一生歌曲原唱// 当改变时将会触发的Event
event HighestBidIncread(address bidder, uint amount);
琴字开头的成语event AuctionEnded(address winner, uint amount);
// 下⾯是⼀个叫做natspec的特殊注释,
// 有3个连续的斜杠标记,当询问⽤户确实交易事务是显⽰
/// 创建⼀个简单的合约使⽤
/// ’_biddingTime‘表⽰竞拍时间
/// ’_beneficiary‘表⽰受益⼈地址
function SimpleAuction(
uint _biddingTime,
address _beneficiary){
beneficiary = _beneficiary;
auctionEnd = now + _biddingTime;
}
/// 竞拍出价会随着交易事务⼀起发送
/// 只有在竞拍失败的时候才会退回
function bid() payable{
// 不需要任何参数
// 所有信息已经是交易事务的⼀部分。
// 需要秘钥⽀付函数需要的以太币
// 出价结束,撤销该调⽤
require (now <= auctionEnd);//Time
require (now <= auctionEnd);//Time
// 如果出价不是最⾼的
/
/ 返回money
require(msg.value > highestBid);
if (highestBidder != 0){
中国第一长寿村// ⽤简单的⽅式把钱寄回来
// highestBidder.nd(highestBid) 是⼀个不安全的因素
// 因为他可以执⾏不受信任的合约
// 让收款⼈⾃⼰收回钱总是⽐较安全的
pendingReturns[highestBidder] += highestBid;
}
highestBidder = msg.nder;
highestBid = msg.value;
HighestBidIncread(msg.nder,msg.value);
}
/// 撤回出价过⾼的竞拍
function withdraw() returns (bool) {
uint amount = pendingReturns[msg.nder];
if (amount > 0) {
// 把这个设置为0很重要
黄岛
// 因为收件⼈可以再次调⽤这个函数
// 在"nd"返回之前作为接受调⽤的⼀部分
pendingReturns[msg.nder] = 0;
if (!msg.nder.nd(amount)) {
/
/ 不需要调⽤这⾥,重置⾦额就⾏
pendongReturns[msg.nder] = amount;
return fal;
}//这⾥逻辑⼤致是,如果调⽤者收到退款,退款额就退0;没有收到就重置为原退款额
}
return true;
}
/// 结束竞拍,发出最⾼的竞价给拍卖⼈(受益者)
function auctionEnd(){
// 这是⼀个很好的指导思想,可以分三个阶段来构建与其他契约交互的函数(即它们调⽤函数或者发送Ether)
// 1.检查条件
// 2.执⾏操作(潜在的变化条件)
// 3.与其他合同交互
// 如果这两个阶段混在⼀起,另⼀个合同可以回到当前的合同中,并修改多次执⾏的状态或原因效果(以太付款)
// 如果内部调⽤的功能包括与外部合同的交互,他们还必须被视为与外部合同的交互.
// 1.条件
require(now >= auctionEnd);// auction didn't end yet(原教程这么说,但感觉更像是竞拍已结束啊..)
require(!ended);//这个函数已被调⽤
// 2. 效果
ended = true;
AuctionEnded(highestBidder, highestBid);
// 3. 交互作⽤
}
高的词语
}
2.2 盲拍
从上⾯公开拍卖的例⼦延伸到下⾯的例⼦:盲拍。盲拍的好处:招标期结束时没有时间压⼒(感觉像个病句。。)。利⽤密码学可以实现在⼀个透明的计算平台上创建⼀个盲拍。
在投标期间,投标⼈实际上并没有发出投标书,⽽只是⼀个被hash过的值。由于⽬前认为实际上不可能找到两个(⾜够长的)哈希值相等的值,所以投标⼈通过提交hash值来投标。在投标期结束后,投标⼈必须公开投标:未加密的发送其价格。并且合同检查hash值与投标期间提供的hash值是否相同。
⼀下合约通过接受任何⼤于最⾼出价的值来解决问题。因为只能在揭牌阶段(最后发送价格时)进⾏检查,所以有些出价可能是⽆效的,这样做的⽬的是(它提供⼀个显⽰的标志指出该竞拍是⽆效的,同时包含⾼额的保证⾦):竞拍⼈可以通过防⽌⼏个⽆效的⾼价和低价竞拍来混淆竞争对⼿。
pragma solidity ^0.4.11;
contract BlindAuction {
struct Bid{
bytes32 blindedBid;
uint deposit; // 保证⾦
}
address public beneficiary;
uint public biddingEnd;
uint public revealEnd;// 揭拍阶段
bool public ended;
mapping(address => Bid[]) public bids;
address public highestBidder;
uint public highestBid;
// 允许撤回之前的竞价
mapping(address => uint) pendingReturns;
/// Modifiers 是⼀个验证函数输⼊的⽅便⽅法
/// 'onlyBefore' 被应⽤到下⾯的'bid':
/// The new function body is the modifier's body where
/// '_' is replaced by the old function body.
modifier onlyBefore(uint _time) { require(now < _time); _; }
modifier onlyAfter(uint _time) { require(now > _time); _; }
// 修饰器,作⽤是放在函数前⾯,只有先执⾏修饰器的程序,在执⾏后⾯的,原函数的步骤相等与在_位置
function BlindAuction(
uint _biddingTime,
uint _revealTime,
address _beneficiary
){
beneficiary = _beneficiary;
biddingEnd = now + _biddingTime;
revealEnd = biddingEnd + _revealTime;
}// 设置⼀个盲拍
/// 放置⼀个盲拍出价使⽤ '_blindedBid' =  keccak256(value,fake,cret).
/// 发送的ether仅仅只在竞拍结束的揭拍后退还竞价正确的ether
/// 有效的投标是在投标是附带⼤于等于"value"的ether并且"fake" 不为true
/
// 设置"fake"为true或发送不合适的⾦额将会淹没真正的竞拍出价,但是仍然需要抵押保证⾦
/// 同⼀个地址可以放置多个竞拍
function bid(bytes32 _blindedBid)
payable
onlyBefore(biddingEnd)
{
bids[msg.nder].push(Bid({
blindedBid: _blindedBid,
deposit: msg.value
}));
}
/
// Reveal your blinded bids. You will get a refund for all
/// correctly blinded invalid bids and for all bids except for
/// the totally highest
function reveal(
uint[] _value,
bool[] _fake,
bytes32[] _cret

本文发布于:2023-07-17 14:06:07,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1101442.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:投票   竞拍   出价   结束   合约
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图