Withdrawal patterns help safely move funds out of a smart contract. They avoid problems like losing money or blocking other actions.
0
0
Withdrawal patterns in Blockchain / Solidity
Introduction
When a user wants to take out their earned tokens from a contract.
When a contract needs to send funds to multiple users without risking errors.
When avoiding security issues like reentrancy attacks during fund transfers.
When you want to separate the logic of recording balances and sending money.
When handling refunds or payouts in a decentralized app.
Syntax
Blockchain / Solidity
mapping(address => uint) public balances;
function withdraw() public {
uint amount = balances[msg.sender];
require(amount > 0, "No funds to withdraw");
balances[msg.sender] = 0;
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}This example shows a simple withdrawal pattern in Solidity.
First, it checks the user's balance, then sets it to zero before sending funds.
Examples
This uses
transfer to send funds, which forwards limited gas and reverts on failure.Blockchain / Solidity
mapping(address => uint) public balances;
function withdraw() public {
uint amount = balances[msg.sender];
require(amount > 0, "No funds to withdraw");
balances[msg.sender] = 0;
payable(msg.sender).transfer(amount);
}This uses
call which is more flexible but requires careful handling to avoid security risks.Blockchain / Solidity
mapping(address => uint) public balances;
function withdraw() public {
uint amount = balances[msg.sender];
require(amount > 0, "No funds to withdraw");
balances[msg.sender] = 0;
(bool sent, ) = msg.sender.call{value: amount}("");
require(sent, "Failed to send Ether");
}This is the recommended pattern: update state before sending funds to prevent reentrancy.
Blockchain / Solidity
mapping(address => uint) public balances;
function withdraw() public {
uint amount = balances[msg.sender];
require(amount > 0, "No funds to withdraw");
balances[msg.sender] = 0;
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}Sample Program
This contract lets users deposit Ether and withdraw it safely using the withdrawal pattern.
It updates the user's balance before sending funds to avoid security issues.
Blockchain / Solidity
pragma solidity ^0.8.20; contract SimpleWithdrawal { mapping(address => uint) public balances; // Function to deposit Ether into contract function deposit() public payable { balances[msg.sender] += msg.value; } // Withdrawal pattern: update balance before sending function withdraw() public { uint amount = balances[msg.sender]; require(amount > 0, "No funds to withdraw"); balances[msg.sender] = 0; (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed"); } }
OutputSuccess
Important Notes
Always update user balances before sending funds to prevent reentrancy attacks.
Use call with checks instead of transfer for better gas handling.
Withdrawal patterns separate balance tracking from sending money, making contracts safer.
Summary
Withdrawal patterns help safely send funds from smart contracts.
Always update balances before transferring money.
This pattern prevents common security problems like reentrancy.