2

In the Solidity docs it says:

There are some dangers in using send: The transfer fails if the call stack depth is at 1024 (this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order to make safe Ether transfers, always check the return value of send, use transfer or even better: Use a pattern where the recipient withdraws the money. (emphasis mine).

What does that mean and can someone show me an example of using this pattern?

2

Adding to @manuhalo's answer, here's the withdrawal example in Solidity docs:

This is an example of the withdrawal pattern in practice in a contract where the goal is to send the most money to the contract in order to become the “richest”

contract WithdrawalContract {
    address public richest;
    uint public mostSent;

    mapping (address => uint) pendingWithdrawals;

    function WithdrawalContract() payable {
        richest = msg.sender;
        mostSent = msg.value;
    }

    function becomeRichest() payable returns (bool) {
        if (msg.value > mostSent) {
            pendingWithdrawals[richest] += msg.value;
            richest = msg.sender;
            mostSent = msg.value;
            return true;
        } else {
            return false;
        }
    }

    function withdraw() returns (bool) {
        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;
        }
    }
}

pendingWithdrawals is a mapping tracking the recipients. When someone becomeRichest, instead of paying off the previous richest address, it becomes the responsibility of the previous richest address to withdraw their funds.

See the full example to compare it with an intuitive but exploitable approach.

The pattern where the recipient withdraws the money is also preferable to a contract attempting to pay multiple recipients. For example, if there's too many recipients, there might not be enough gas to pay all recipients. Or a malicious recipient could refuse payment as an attempt to poison the contract and prevent payments to everyone else. By making each recipient withdraw their funds, a malicious recipient can only prevent their own withdrawal.

2

I assume you want to know what the part in bold means. If that's correct, essentially store the value that a recipient is owed in a mapping (i.e. from address to amount), then have a withdraw function that can be called by the recipient, which checks the mapping to see if the caller has any "credit" and transfers that amount to the recipient. An example is shown in the documents you cited; another can be found in the zeppelin library.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.