aboutsummaryrefslogtreecommitdiffstats
path: root/docs/common-patterns.rst
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-05-03 20:36:32 +0800
committerGitHub <noreply@github.com>2017-05-03 20:36:32 +0800
commit68ef5810593e7c8092ed41d5f474dd43141624eb (patch)
tree36453acfef9495095dc47305d9b40c2cd3b63813 /docs/common-patterns.rst
parentf0d539ae05739e35336cc9cc8f44bd9798a95c28 (diff)
parent34b28ed760e8ba9b86f661c819fe489fb8403235 (diff)
downloaddexon-solidity-68ef5810593e7c8092ed41d5f474dd43141624eb.tar
dexon-solidity-68ef5810593e7c8092ed41d5f474dd43141624eb.tar.gz
dexon-solidity-68ef5810593e7c8092ed41d5f474dd43141624eb.tar.bz2
dexon-solidity-68ef5810593e7c8092ed41d5f474dd43141624eb.tar.lz
dexon-solidity-68ef5810593e7c8092ed41d5f474dd43141624eb.tar.xz
dexon-solidity-68ef5810593e7c8092ed41d5f474dd43141624eb.tar.zst
dexon-solidity-68ef5810593e7c8092ed41d5f474dd43141624eb.zip
Merge pull request #2219 from ethereum/develop
Release for version 0.4.11
Diffstat (limited to 'docs/common-patterns.rst')
-rw-r--r--docs/common-patterns.rst55
1 files changed, 24 insertions, 31 deletions
diff --git a/docs/common-patterns.rst b/docs/common-patterns.rst
index a2d7ce71..acef13b7 100644
--- a/docs/common-patterns.rst
+++ b/docs/common-patterns.rst
@@ -23,12 +23,12 @@ contract in order to become the "richest", inspired by
`King of the Ether <https://www.kingoftheether.com/>`_.
In the following contract, if you are usurped as the richest,
-you will recieve the funds of the person who has gone on to
+you will receive the funds of the person who has gone on to
become the new richest.
::
- pragma solidity ^0.4.0;
+ pragma solidity ^0.4.11;
contract WithdrawalContract {
address public richest;
@@ -52,17 +52,12 @@ become the new richest.
}
}
- function withdraw() returns (bool) {
+ function withdraw() {
uint amount = pendingWithdrawals[msg.sender];
// Remember to zero the pending refund before
// sending to prevent re-entrancy attacks
pendingWithdrawals[msg.sender] = 0;
- if (msg.sender.send(amount)) {
- return true;
- } else {
- pendingWithdrawals[msg.sender] = amount;
- return false;
- }
+ msg.sender.transfer(amount);
}
}
@@ -70,7 +65,7 @@ This is as opposed to the more intuitive sending pattern:
::
- pragma solidity ^0.4.0;
+ pragma solidity ^0.4.11;
contract SendContract {
address public richest;
@@ -83,12 +78,8 @@ This is as opposed to the more intuitive sending pattern:
function becomeRichest() payable returns (bool) {
if (msg.value > mostSent) {
- // Check if call succeeds to prevent an attacker
- // from trapping the previous person's funds in
- // this contract through a callstack attack
- if (!richest.send(msg.value)) {
- throw;
- }
+ // This line can cause problems (explained below).
+ richest.transfer(msg.value);
richest = msg.sender;
mostSent = msg.value;
return true;
@@ -100,12 +91,16 @@ This is as opposed to the more intuitive sending pattern:
Notice that, in this example, an attacker could trap the
contract into an unusable state by causing ``richest`` to be
-the address of a contract that has a fallback function
-which consumes more than the 2300 gas stipend. That way,
-whenever ``send`` is called to deliver funds to the
-"poisoned" contract, it will cause execution to always fail
-because there will not be enough gas to finish the execution
-of the fallback function.
+the address of a contract that has a fallback function
+which fails (e.g. by using ``revert()`` or by just
+conssuming more than the 2300 gas stipend). That way,
+whenever ``transfer`` is called to deliver funds to the
+"poisoned" contract, it will fail and thus also ``becomeRichest``
+will fail, with the contract being stuck forever.
+
+In contrast, if you use the "withdraw" pattern from the first example,
+the attacker can only cause his or her own withdraw to fail and not the
+rest of the contract's workings.
.. index:: access;restricting
@@ -135,7 +130,7 @@ restrictions highly readable.
::
- pragma solidity ^0.4.0;
+ pragma solidity ^0.4.11;
contract AccessRestriction {
// These will be assigned at the construction
@@ -152,8 +147,7 @@ restrictions highly readable.
// a certain address.
modifier onlyBy(address _account)
{
- if (msg.sender != _account)
- throw;
+ require(msg.sender == _account);
// Do not forget the "_;"! It will
// be replaced by the actual function
// body when the modifier is used.
@@ -169,7 +163,7 @@ restrictions highly readable.
}
modifier onlyAfter(uint _time) {
- if (now < _time) throw;
+ require(now >= _time);
_;
}
@@ -190,8 +184,7 @@ restrictions highly readable.
// This was dangerous before Solidity version 0.4.0,
// where it was possible to skip the part after `_;`.
modifier costs(uint _amount) {
- if (msg.value < _amount)
- throw;
+ require(msg.value >= _amount);
_;
if (msg.value > _amount)
msg.sender.send(msg.value - _amount);
@@ -232,7 +225,7 @@ reached at a certain point in **time**.
An example for this is a blind auction contract which
starts in the stage "accepting blinded bids", then
transitions to "revealing bids" which is ended by
-"determine auction autcome".
+"determine auction outcome".
.. index:: function;modifier
@@ -276,7 +269,7 @@ function finishes.
::
- pragma solidity ^0.4.0;
+ pragma solidity ^0.4.11;
contract StateMachine {
enum Stages {
@@ -293,7 +286,7 @@ function finishes.
uint public creationTime = now;
modifier atStage(Stages _stage) {
- if (stage != _stage) throw;
+ require(stage == _stage);
_;
}