The withdraw pattern in Solidity
Pull, don't push: zero the balance before sending.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
// Pull, don't push: zero the balance before sending anything.
contract StallPayouts {
mapping(address => uint256) public owed;
function credit(address vendor) external payable {
owed[vendor] += msg.value;
}
function withdraw() external {
uint256 amount = owed[msg.sender];
require(amount > 0, "nothing owed");
owed[msg.sender] = 0; // effects before interaction
(bool ok, ) = msg.sender.call{value: amount}("");
require(ok, "send failed");
}
}
How it works
- Credits accumulate in
owed; nobody is paid unasked. - The balance zeroes before the send — effects first.
call{value: amount}("")sends; the bool is checked.
Keywords and builtins used here
addressboolcontractexternalfunctionmappingpayablepublicrequireuint256
The run, in numbers
- Lines
- 19
- Characters to type
- 505
- Tokens
- 95
- Three-star pace
- 55 tpm
At the three-star pace of 55 tokens a minute, this run takes about 104 seconds.
Step 3 of 3 in Ether & events, step 13 of 28 in Language basics.