vote
The following contracts are quite complex, but show a lot of solidity features. Implement a voting contract. Of course, the main problem with electronic voting is how to allocate the right to vote to the right people and how to prevent manipulation. We will not solve all of the problems here, but at least we will show how to conduct a commission vote so that the votes are automatically and completely transparent.
The idea is to create a contract every time you vote, providing a short name for each option. The founder of the contract that then acts as Chairman will have the right to vote separately for each address.
People behind the address can choose to vote for themselves or delegate their votes to the people they trust.
At the end of the poll, the winning Winningproposal () will return the proposal with the largest number of votes.
pragma solidity ^0.4.11;
@title vote with the delegation. Contract Ballot {//This declares a new complex type that will later be used for the variable.
It will represent an elector. struct Voter {uint weight;//weighted bool voted accumulated by the delegation; If true, that person has already voted for address delegate; Who voted for the uint vote;
Poll suggested indicator}//This is the type of individual proposal. struct Proposal {BYTES32 name; Abbreviation (up to bytes) uint Votecount;
Cumulative number of votes} Address public Chairperson;
This declares a state variable that stores a "voter" structure for each possible address.
Mapping (address = voter) public voters;
An array of dynamic-size "proposal" structures.
Proposal[] public proposals;
Create a new poll select one of the "Proposalnames".
Function ballot (bytes32[] proposalnames) {chairperson = Msg.sender;
Voters[chairperson].weight = 1;
For each provided proposal name, create a new proposal object and add it to the end of the array. for (UINT i = 0; i < proposalnames.length; i++) {//' proposal ({...} ) ' Create a temporary proposal object, and ' Proposals.push (...
) ' Append it to the end of ' proposal '. Proposals.push (Proposal ({Name: Proposalnames[i], votecount:0}); }//Give "voter" the right to vote.
Can only be called by "Chairperson". function Giverighttovote (address voter) {//If the ' require ' parameter evaluates to ' false ', it terminates and restores all changes to state and ether balances. If a function call is incorrect, it is usually a good idea.
However, it is important to note that this is currently going to consume all the gas provided (the plan will change in the future).
Require ((Msg.sender = = Chairperson) &&!voters[voter].voted && (voters[voter].weight = 0));
Voters[voter].weight = 1;
}///delegate The vote to the voter "to".
function delegate (address to) {//Assign reference voter storage sender = Voters[msg.sender];
Require (!sender.voted);
Self-authorization is not allowed.
Require (to! = Msg.sender);
As long as ' to ' also transfers the delegation. In general, such loops are very dangerous, because if they run too long, they may need more gas than is available in the block.
In this case, the agent will not execute, but in other cases, this cycle may result in the contract being completely "jammed".
while (voters[to].delegate! = Address (0)) {to = Voters[to].delegate;
We found the circle in the delegation, not allowed.
Require (to! = Msg.sender); }//Because ' sender ' is a reference, so this modifies the ' VOter [Msg.sender]. voted ' sender.voted = true;
Sender.delegate = to;
Voter storage delegate = Voters[to];
if (delegate.voted) {//If the representative has voted, increase the number of votes directly proposals[delegate.vote].votecount + = Sender.weight;
} else {//If the representative does not vote, increase her weight.
Delegate.weight + = Sender.weight;
}////Give your ticket (including the delegate to you) the proposal ' Proposals[proposal].name '.
Function vote (UINT proposal) {Voter storage sender = Voters[msg.sender];
Require (!sender.voted);
Sender.voted = true;
Sender.vote = proposal;
If ' proposal ' exceeds the range of the array, this will automatically throw and restore all changes.
Proposals[proposal].votecount + = Sender.weight;
///@dev calculate the winning proposal for all previous votes.
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;
}}}//Call the Winningproposal () function to get the index of the winner contained in the proposal array, and then return the winner's name Function Winnername () constant
Returns (Bytes32 winnername) {winnername = Proposals[winningproposal ()].name;
}
}
The Require method in the above example means that if the condition inside is false, the subsequent code is not executed, which is equivalent to return false. Possible Improvements
Currently, many transactions are required to assign voting rights to all participants. Can you think of a better way? Blind Auction
In this section, we will show how easy it is to create a completely blind auction contract in Ethereum. We'll start with a public auction where everyone can see all the bids and then extend the contract to a blind auction, and it's impossible to see the actual bids until the end of the bidding period. Simple Public Bidding
The general idea of the following simple auction contract is that everyone can send bids during the bidding period. The bid already includes remittance/Ethernet to bind the bidder to the bid. If the highest bid is raised, the previous highest bidder gets her money back. After the tender period ends, the contract formalities must be deducted manually, the beneficiary can receive the payment-the contract cannot be put into use by itself.
pragma solidity ^0.4.11; Contract Simpleauction {//Auction parameters.
Time is the absolute Unix timestamp (seconds from 1970-01-01) or time period (in seconds).
Address public beneficiary;
UINT public auctionstart;
UINT public biddingtime;
Current status of the auction address public highestbidder;
UINT public highestbid;
Allow revocation of previous bids mapping (address = uint) pendingreturns;
Finally set to true, do not allow any changes to bool ended;
The event that will be triggered when the change occurs.
Event highestbidincreased (address bidder, uint amount);
Event auctionended (address winner, uint amount);
The following is the so-called Natspec comment, identified by three slashes.
Displayed when the user is asked to confirm the transaction.
On behalf of the beneficiary address "_beneficiary", create a simple auction with "_biddingtime" second bid time. function simpleauction (UINT _biddingtime, address _beneficiary) {beneficiary = _beneficiary
;
Auctionstart = Now;
Biddingtime = _biddingtime;
}//Bid with this transaction at the price of the auction.
If the auction is not won, the value will be refunded. Function Bid () payable {//No necessary parameters, all information is already part of the transaction.
Features that require payment of the keyword are able to receive ether.
If the bid period ends, the call resumes. Require (now <= (Auctionstart + biddingtime));
If the bid is not high, send money back.
Require (Msg.value > Highestbid);
The IF (Highestbidder! = 0) {//is a security risk by simply using Highestbidder.send (highestbid) to send back funds because it can execute an non-trusted contract.
It is always safer for recipients to collect their own money.
Pendingreturns[highestbidder] + = highestbid;
} Highestbidder = Msg.sender;
Highestbid = Msg.value;
Highestbidincreased (Msg.sender, Msg.value);
}///extract too high a bid.
function Withdraw () returns (BOOL) {UINT amount = Pendingreturns[msg.sender];
if (Amount > 0) {//It is important to set it to zero, because the recipient can call this function again as part of the receive call before send is returned.
Pendingreturns[msg.sender] = 0;
if (!msg.sender.send (amount)) {//Do not need to call throw here, just reset the amount owed by pendingreturns[msg.sender] = amount;
return false;
}} return true;
}///Close the auction and send the highest bid to the beneficiary. function Auctionend () {//will interact with other contracts (calling methodYes or send ether) The function is divided into three stages which is a good guideline//1. Check condition//2. Perform the action (potential change condition)//3.
Interact with other contracts//if these phases are mixed up, another contract can be recalled to the current contract, and the state is modified or the effect (ether payment) is executed multiple times.
If functions that are called internally include interactions with external contracts, they must also be considered as interacting with the external contract. 1. Condition require (now >= (Auctionstart + biddingtime)); Auction did not yet end require (!ended); This function has already been called//2.
Affects ended = true;
Auctionended (Highestbidder, highestbid); 3.
Interactive Beneficiary.transfer (highestbid); }
}
Blind Auction
Previous public auctions were extended to the following blind auctions. The advantage of a blind auction is that there is no time pressure at the end of the bid period. A blind auction on a transparent computing platform may sound like a contradiction, but cryptography comes in handy.
during the tender period , the bidder does not actually send the bid, but only a hash version. Since it is now considered almost impossible to find two (long enough) values equal to the hash value, the bidder bids. After the tender period is over, bidders must disclose the bids: They send value unencrypted, and the contract check hash value is the same value provided during the tender period.
Another challenge is how to simultaneously auction bundling and blindness: the only way to prevent bidders from not shipping after the auction ends is to send them along with the bid. Anyone can see this value when the Ethereum value shift cannot be blinded.
The following contract resolves this issue by accepting any value that is greater than the maximum bid. Since this of course can only be checked during the revelation phase, some bids may be ineffective, which makes sense (and even provides a clear sign that the invalid bid can be set to a high value transfer): Bidders can bid by placing several high or low void bids.
pragma solidity ^0.4.11;
Contract Blindauction {struct Bid {bytes32 blindedbid;
UINT Deposit;
} address public beneficiary;
UINT public auctionstart;
UINT public biddingend;
UINT public revealend;
BOOL public ended;
Mapping (address = bid[]) public bids;
Address public highestbidder;
UINT public highestbid;
Allow revocation of previous bids mapping (address = uint) pendingreturns;
Event auctionended (Address winner, uint highestbid); Modifiers are a convenient way to validate function input.
' Only before ' applies to the following ' bid ': The new function body is the modifier 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) {b
Eneficiary = _beneficiary;
Auctionstart = Now;
Biddingend = Now + _biddingtime;
Revealend = Biddingend + _revealtime; }///through this substitution to achieveBlind bids: ' _blindedbid ' = keccak256 (value, fake, secret). If the bid is displayed correctly during the exposure phase, the sent ether can only be returned. If the ether sent with the bid is at least "value", the "false" is not true and the bid is valid. Setting false to true and sending an inaccurate amount is a way to hide the actual bid but still make the required deposit.
Multiple bids can be placed on the same address.
Function bid (BYTES32 _blindedbid) payable Onlybefore (biddingend) {Bids[msg.sender].push (Bid ({
Blindedbid: _blindedbid, deposit:msg.value}); }///reveal your blind bids.
You will get all the right blind invalid bids and refunds for all bids unless it is the highest. function reveal (uint[] _values, bool[] _fake, bytes32[] _secret) onlyafter (Biddingen
d) Onlybefore (revealend) {UINT length = bids[msg.sender].length;
require (_values.length = = length);
require (_fake.length = = length);
require (_secret.length = = length);
UINT Refund;
for (UINT i = 0; i < length; i++) {var bid = Bids[msg.sender][i];
VAR (value, fake, secret) = (_values[i], _fake[i], _secret[i]); if (bid.blindedbid! = keccak256 (value, fake, secret)) {//bid actually not disclosed//refund deposit
Continue
} refund + = Bid.deposit; if (!fake && bid.deposit >= value) {if (Placebid (Msg.sender, value)) Refun
D-= value;
The sender may not be able to claim the same deposit again.
Bid.blindedbid = bytes32 (0);
} msg.sender.transfer (refund);
}//This is an "internal" feature, which means that it can only be called from the contract itself (or derived contracts). function Placebid (address bidder, UINT value) internal returns (bool success) {if (Value <= hi
Ghestbid) {return false;
} if (Highestbidder! = 0) {//refund the person with the highest previous bid.
Pendingreturns[highestbidder] + = highestbid;
} highestbid = value;
Highestbidder = bidder;
return true;
}///extract too high a bid. function withdraw () {UINT amount = Pendingreturns[msg.senDer];
if (Amount > 0) {//It is important to set it to zero, because the receiver can call this function again as part of the receive call before send sends back (see the comments above about condition-> Effects-> Interactions).
Pendingreturns[msg.sender] = 0;
Msg.sender.transfer (amount);
}///Close the auction and send the highest bid to the beneficiary.
function Auctionend () onlyafter (revealend) {require (!ended);
Auctionended (Highestbidder, highestbid);
ended = true;
We send all the money because some refunds may fail.
Beneficiary.transfer (this.balance); }
}
Secure Remote Purchase
pragma solidity ^0.4.11;
Contract Purchase {UINT public value;
Address public seller;
Address public buyer;
Enum State {Created, Locked, Inactive} The state public state;
Ensure that ' msg.value ' was an even number.
Division would truncate if it is an odd number.
Check via multiplication that it wasn ' t an odd number.
function Purchase () payable {seller = Msg.sender;
value = MSG.VALUE/2;
Require ((2 * value) = = Msg.value);
} modifier condition (bool _condition) {require (_condition);
_;
} modifier Onlybuyer () {require (Msg.sender = = buyer);
_;
} modifier Onlyseller () {require (Msg.sender = = seller);
_;
} modifier instate (state _state) {require (state = = _state);
_;
} event aborted ();
Event purchaseconfirmed ();
Event itemreceived ();
Abort the purchase and reclaim the ether. Can only is CalLed by the seller before///the contract is locked.
function abort () Onlyseller instate (state.created) {aborted ();
state = state.inactive;
Seller.transfer (this.balance);
}///Confirm the purchase as buyer.
Transaction have to include ' 2 * value ' ether.
The ether'll be locked until confirmreceived//is called.
function Confirmpurchase () instate (state.created) condition (Msg.value = = (2 * value)) payable
{purchaseconfirmed ();
Buyer = Msg.sender;
state = state.locked;
}///Confirm that buyer received the item.
This would release the locked ether.
function confirmreceived () Onlybuyer instate (state.locked) {itemreceived ();
It is important to change the state first because//otherwise, the contracts called using ' send ' below
Can call in again here. State = State.inactive; Note:this actually allows both the buyer and the seller to//block the refund-the withdraw pattern should b
E used.
Buyer.transfer (value);
Seller.transfer (this.balance);
}
}