diff --git a/docs/examples/blind-auction.rst b/docs/examples/blind-auction.rst index 790237cf6..92a755973 100644 --- a/docs/examples/blind-auction.rst +++ b/docs/examples/blind-auction.rst @@ -4,12 +4,10 @@ Blind Auction ************* -In this section, we will show how easy it is to create a -completely blind auction contract on Ethereum. -We will start with an open auction where everyone -can see the bids that are made and then extend this -contract into a blind auction where it is not -possible to see the actual bid until the bidding +In this section, we will show how easy it is to create a completely blind +auction contract on Ethereum. We will start with an open auction where +everyone can see the bids that are made and then extend this contract into a +blind auction where it is not possible to see the actual bid until the bidding period ends. .. _simple_auction: @@ -17,16 +15,12 @@ period ends. Simple Open Auction =================== -The general idea of the following simple auction contract -is that everyone can send their bids during -a bidding period. The bids already include sending -money / ether in order to bind the bidders to their -bid. If the highest bid is raised, the previously -highest bidder gets her money back. -After the end of the bidding period, the -contract has to be called manually for the -beneficiary to receive their money - contracts cannot -activate themselves. +The general idea of the following simple auction contract is that everyone can +send their bids during a bidding period. The bids already include sending money +/ Ether in order to bind the bidders to their bid. If the highest bid is +raised, the previously highest bidder gets their money back. After the end of +the bidding period, the contract has to be called manually for the beneficiary +to receive their money - contracts cannot activate themselves. :: @@ -161,38 +155,31 @@ activate themselves. Blind Auction ============= -The previous open auction is extended to a blind auction -in the following. The advantage of a blind auction is -that there is no time pressure towards the end of -the bidding period. Creating a blind auction on a -transparent computing platform might sound like a -contradiction, but cryptography comes to the rescue. +The previous open auction is extended to a blind auction in the following. The +advantage of a blind auction is that there is no time pressure towards the end +of the bidding period. Creating a blind auction on a transparent computing +platform might sound like a contradiction, but cryptography comes to the +rescue. -During the **bidding period**, a bidder does not -actually send her bid, but only a hashed version of it. -Since it is currently considered practically impossible -to find two (sufficiently long) values whose hash -values are equal, the bidder commits to the bid by that. -After the end of the bidding period, the bidders have -to reveal their bids: They send their values -unencrypted and the contract checks that the hash value -is the same as the one provided during the bidding period. +During the **bidding period**, a bidder does not actually send their bid, but +only a hashed version of it. Since it is currently considered practically +impossible to find two (sufficiently long) values whose hash values are equal, +the bidder commits to the bid by that. After the end of the bidding period, +the bidders have to reveal their bids: They send their values unencrypted and +the contract checks that the hash value is the same as the one provided during +the bidding period. -Another challenge is how to make the auction -**binding and blind** at the same time: The only way to -prevent the bidder from just not sending the money -after they won the auction is to make her send it -together with the bid. Since value transfers cannot -be blinded in Ethereum, anyone can see the value. +Another challenge is how to make the auction **binding and blind** at the same +time: The only way to prevent the bidder from just not sending the money after +they won the auction is to make them send it together with the bid. Since value +transfers cannot be blinded in Ethereum, anyone can see the value. -The following contract solves this problem by -accepting any value that is larger than the highest -bid. Since this can of course only be checked during -the reveal phase, some bids might be **invalid**, and -this is on purpose (it even provides an explicit -flag to place invalid bids with high value transfers): -Bidders can confuse competition by placing several -high or low invalid bids. +The following contract solves this problem by accepting any value that is +larger than the highest bid. Since this can of course only be checked during +the reveal phase, some bids might be **invalid**, and this is on purpose (it +even provides an explicit flag to place invalid bids with high value +transfers): Bidders can confuse competition by placing several high or low +invalid bids. :: @@ -296,24 +283,6 @@ high or low invalid bids. msg.sender.transfer(refund); } - // This is an "internal" function which means that it - // can only be called from the contract itself (or from - // derived contracts). - function placeBid(address bidder, uint value) internal - returns (bool success) - { - if (value <= highestBid) { - return false; - } - if (highestBidder != address(0)) { - // Refund the previously highest bidder. - pendingReturns[highestBidder] += highestBid; - } - highestBid = value; - highestBidder = bidder; - return true; - } - /// Withdraw a bid that was overbid. function withdraw() public { uint amount = pendingReturns[msg.sender]; @@ -339,4 +308,22 @@ high or low invalid bids. ended = true; beneficiary.transfer(highestBid); } + + // This is an "internal" function which means that it + // can only be called from the contract itself (or from + // derived contracts). + function placeBid(address bidder, uint value) internal + returns (bool success) + { + if (value <= highestBid) { + return false; + } + if (highestBidder != address(0)) { + // Refund the previously highest bidder. + pendingReturns[highestBidder] += highestBid; + } + highestBid = value; + highestBidder = bidder; + return true; + } } \ No newline at end of file diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst index d00e2bbc1..f675586dd 100644 --- a/docs/examples/micropayment.rst +++ b/docs/examples/micropayment.rst @@ -354,17 +354,6 @@ The full contract expiration = now + duration; } - function isValidSignature(uint256 amount, bytes memory signature) - internal - view - returns (bool) - { - bytes32 message = prefixed(keccak256(abi.encodePacked(this, amount))); - - // check that the signature is from the payment sender - return recoverSigner(message, signature) == sender; - } - /// the recipient can close the channel at any time by presenting a /// signed amount from the sender. the recipient will be sent that amount, /// and the remainder will go back to the sender @@ -391,6 +380,17 @@ The full contract selfdestruct(sender); } + function isValidSignature(uint256 amount, bytes memory signature) + internal + view + returns (bool) + { + bytes32 message = prefixed(keccak256(abi.encodePacked(this, amount))); + + // check that the signature is from the payment sender + return recoverSigner(message, signature) == sender; + } + /// All functions below this are just taken from the chapter /// 'creating and verifying signatures' chapter. diff --git a/docs/examples/modular.rst b/docs/examples/modular.rst index 928d473bc..a3d932b09 100644 --- a/docs/examples/modular.rst +++ b/docs/examples/modular.rst @@ -38,9 +38,6 @@ and the sum of all balances is an invariant across the lifetime of the contract. event Transfer(address from, address to, uint amount); event Approval(address owner, address spender, uint amount); - function balanceOf(address tokenOwner) public view returns (uint balance) { - return balances[tokenOwner]; - } function transfer(address to, uint amount) public returns (bool success) { balances.move(msg.sender, to, amount); emit Transfer(msg.sender, to, amount); @@ -62,4 +59,8 @@ and the sum of all balances is an invariant across the lifetime of the contract. emit Approval(msg.sender, spender, tokens); return true; } + + function balanceOf(address tokenOwner) public view returns (uint balance) { + return balances[tokenOwner]; + } } diff --git a/docs/examples/safe-remote.rst b/docs/examples/safe-remote.rst index 9ba3c4c85..d79c6526e 100644 --- a/docs/examples/safe-remote.rst +++ b/docs/examples/safe-remote.rst @@ -31,19 +31,11 @@ you can use state machine-like constructs inside a contract. uint public value; address payable public seller; address payable public buyer; + enum State { Created, Locked, Release, Inactive } // The state variable has a default value of the first member, `State.created` State public state; - // Ensure that `msg.value` is an even number. - // Division will truncate if it is an odd number. - // Check via multiplication that it wasn't an odd number. - constructor() public payable { - seller = msg.sender; - value = msg.value / 2; - require((2 * value) == msg.value, "Value has to be even."); - } - modifier condition(bool _condition) { require(_condition); _; @@ -78,6 +70,15 @@ you can use state machine-like constructs inside a contract. event ItemReceived(); event SellerRefunded(); + // Ensure that `msg.value` is an even number. + // Division will truncate if it is an odd number. + // Check via multiplication that it wasn't an odd number. + constructor() public payable { + seller = msg.sender; + value = msg.value / 2; + require((2 * value) == msg.value, "Value has to be even."); + } + /// Abort the purchase and reclaim the ether. /// Can only be called by the seller before /// the contract is locked.