diff options
author | chriseth <c@ethdev.com> | 2016-06-28 23:29:08 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-07-04 21:27:53 +0800 |
commit | 2df142c49618138ba7f38f32a76022caecc68abb (patch) | |
tree | 0d67461efc8993c9eeca5573b46f6ff6c5055d94 /docs/solidity-by-example.rst | |
parent | 48238c9f1452b1326851af053c782734d0f67101 (diff) | |
download | dexon-solidity-2df142c49618138ba7f38f32a76022caecc68abb.tar.gz dexon-solidity-2df142c49618138ba7f38f32a76022caecc68abb.tar.zst dexon-solidity-2df142c49618138ba7f38f32a76022caecc68abb.zip |
Security Considerations
Diffstat (limited to 'docs/solidity-by-example.rst')
-rw-r--r-- | docs/solidity-by-example.rst | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst index 6fa70be4..7dd51f00 100644 --- a/docs/solidity-by-example.rst +++ b/docs/solidity-by-example.rst @@ -291,15 +291,32 @@ activate themselves. /// End the auction and send the highest bid /// to the beneficiary. function auctionEnd() { + // It is a good guideline to structure functions that interact + // with other contracts (i.e. they call functions or send Ether) + // into three phases: + // 1. checking conditions + // 2. performing actions (potentially changing conditions) + // 3. interacting with other contracts + // If these phases are mixed up, the other contract could call + // back into the current contract and modify the state or cause + // effects (ether payout) to be perfromed multiple times. + // If functions called internally include interaction with external + // contracts, they also have to be considered interaction with + // external contracts. + + // 1. Conditions if (now <= auctionStart + biddingTime) throw; // auction did not yet end if (ended) throw; // this function has already been called + + // 2. Effects + ended = true; AuctionEnded(highestBidder, highestBid); + // 3. Interaction if (!beneficiary.send(highestBid)) throw; - ended = true; } function () { @@ -476,7 +493,8 @@ high or low invalid bids. var amount = pendingReturns[msg.sender]; // It is important to set this to zero because the recipient // can call this function again as part of the receiving call - // before `send` returns. + // before `send` returns (see the remark above about + // conditions -> effects -> interaction). pendingReturns[msg.sender] = 0; if (!msg.sender.send(amount)) throw; // If anything fails, this will revert the changes above @@ -490,11 +508,11 @@ high or low invalid bids. if (ended) throw; AuctionEnded(highestBidder, highestBid); + ended = true; // We send all the money we have, because some // of the refunds might have failed. if (!beneficiary.send(this.balance)) throw; - ended = true; } function () { |