0
0
Blockchain / Solidityprogramming~5 mins

Withdrawal patterns in Blockchain / Solidity

Choose your learning style9 modes available
Introduction

Withdrawal patterns help safely move funds out of a smart contract. They avoid problems like losing money or blocking other actions.

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.