mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add section about withdrawal pattern
This commit is contained in:
parent
e6a031d4e5
commit
efb48659dd
@ -2,6 +2,80 @@
|
|||||||
Common Patterns
|
Common Patterns
|
||||||
###############
|
###############
|
||||||
|
|
||||||
|
.. index:: withdrawal
|
||||||
|
|
||||||
|
*************************
|
||||||
|
Withdrawal from Contracts
|
||||||
|
*************************
|
||||||
|
|
||||||
|
The recommended method of sending funds after an effect
|
||||||
|
is with the withdrawal pattern. Although the most intuitive
|
||||||
|
aethod of sending Ether as a result of an effect is a
|
||||||
|
direct ``send`` call, this is not recommended as it
|
||||||
|
introduces a potential security risk. You may read
|
||||||
|
more about this on the :ref:`security_considerations` page.
|
||||||
|
|
||||||
|
This is an example of the withdrawal pattern in practice in
|
||||||
|
an Ether storage contract.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
contract WithdrawalPattern {
|
||||||
|
|
||||||
|
mapping (address => uint) etherStore;
|
||||||
|
mapping (address => uint) pendingReturns;
|
||||||
|
|
||||||
|
function sendEther(uint amount) {
|
||||||
|
if (amount < etherStore[msg.sender]) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
etherStore[msg.sender] -= amount;
|
||||||
|
pendingReturns[msg.sender] += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
function withdraw() {
|
||||||
|
uint amount = pendingReturns[msg.sender];
|
||||||
|
// It is important to zero the mapping entry
|
||||||
|
// before sending otherwise this could open
|
||||||
|
// the contract to a re-entrancy attack
|
||||||
|
pendingReturns[msg.sender] = 0;
|
||||||
|
if (!msg.sender.send(amount)) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function () {
|
||||||
|
etherStore[msg.sender] += msg.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
This is as opposed to the more intuitive sending pattern.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
contract SendPattern {
|
||||||
|
|
||||||
|
mapping (address => uint) etherStore;
|
||||||
|
|
||||||
|
function sendEther(uint amount) {
|
||||||
|
if (amount < etherStore[msg.sender]) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
etherStore[msg.sender] -= amount;
|
||||||
|
if (!msg.sender.send(amount)) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function () {
|
||||||
|
etherStore[msg.sender] += msg.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
An example of this pattern in a less contrived
|
||||||
|
application can be found on the :ref:`simple_auction`
|
||||||
|
example.
|
||||||
|
|
||||||
.. index:: access;restricting
|
.. index:: access;restricting
|
||||||
|
|
||||||
******************
|
******************
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
.. _security_considerations:
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
Security Considerations
|
Security Considerations
|
||||||
#######################
|
#######################
|
||||||
|
@ -191,6 +191,8 @@ contract into a blind auction where it is not
|
|||||||
possible to see the actual bid until the bidding
|
possible to see the actual bid until the bidding
|
||||||
period ends.
|
period ends.
|
||||||
|
|
||||||
|
.. _simple_auction:
|
||||||
|
|
||||||
Simple Open Auction
|
Simple Open Auction
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user