Learning Objectives – after this chapter you will be able to:
  • Write payable functions and read msg.value.
  • Use address payable and check a contract’s balance.
  • Compare transfer, send and call for sending Ether.
  • Send Ether safely using checks-effects-interactions and the withdrawal pattern.
Solidity Payable Function
  • A payable function is a function that can receive Ether together with the call. The amount sent is available in msg.value (in wei) and is added to the contract’s balance automatically.
  • A function without the payable keyword rejects any Ether sent to it – the transaction reverts.
  • A payable function can also be called with zero Ether; use require(msg.value > 0) (or an exact amount) if a payment is mandatory.
  • The contract’s current balance is address(this).balance.
All about Payable
  • payable functions – function deposit() external payable { } – receive Ether with a call.
  • receive / payable fallback – receive plain Ether that is sent without calling a named function (Chapter 23). The old unnamed function () payable syntax was replaced by receive() and fallback() in Solidity 0.6.0.
  • payable constructor – lets Ether be sent at deployment (Chapter 17).
  • address payable – the address type that can receive Ether through transfer/send. Convert with payable(addr), e.g. payable(msg.sender).
Methods for Sending Ether
MethodGas forwardedOn failureRecommendation
to.transfer(amount)Fixed 2300Reverts automaticallySimple, but can fail if the recipient is a contract needing more than 2300 gas.
to.send(amount)Fixed 2300Returns false (no revert)Must check the result, e.g. require(to.send(x)). Rarely used.
to.call{value: amount}("")All remaining gas (adjustable)Returns (bool success, bytes data)Recommended today – check success and protect against reentrancy.
The old syntax address.call.value(amount)() was removed in Solidity 0.7.0. Use address.call{value: amount}(""), and set gas explicitly only when needed with {value: amount, gas: g}.
Sending Ether Safely
  • Checks – Effects – Interactions: first check conditions, then update your contract’s state (e.g. set the balance to 0), and only then send Ether. This prevents reentrancy, where the recipient calls back into your function before the state is updated.
  • Withdrawal (pull) pattern: instead of pushing payments to many users in one loop, record what each user is owed and let each user withdraw it. One failing recipient then cannot block everyone else.
  • Always check the result of send and call.
  • Amounts are in wei; write 1 ether or 0.5 ether for readability.
Example : Deposits and Safe Withdrawals
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract EtherWallet {
    mapping(address => uint) public balances;

    event Deposit(address indexed user, uint amount);
    event Withdrawal(address indexed user, uint amount);

    // payable: accepts Ether, amount in msg.value
    function deposit() external payable {
        require(msg.value > 0, "Send some Ether");
        balances[msg.sender] += msg.value;
        emit Deposit(msg.sender, msg.value);
    }

    // withdrawal (pull) pattern with checks-effects-interactions
    function withdraw(uint amount) external {
        require(balances[msg.sender] >= amount, "Insufficient balance");   // checks
        balances[msg.sender] -= amount;                                      // effects
        (bool ok, ) = payable(msg.sender).call{value: amount}("");          // interaction
        require(ok, "Transfer failed");
        emit Withdrawal(msg.sender, amount);
    }

    function contractBalance() external view returns (uint) {
        return address(this).balance;
    }

    // plain Ether sent to the contract is credited to the sender
    receive() external payable {
        balances[msg.sender] += msg.value;
        emit Deposit(msg.sender, msg.value);
    }
}
Key Takeaways
  • Only payable functions (and receive/payable fallback) accept Ether; the amount is msg.value.
  • Prefer call{value: x}("") and always check its result.
  • Update state before sending Ether, and let users withdraw instead of pushing payments.
Download | Print      E-Notes

The PDF E-Notes are the earlier printable version of this chapter. The notes on this page are the latest, revised version.

Video : Payable Functions and Sending Ether
Resource File
Question / Answer (15 questions)

Answer : A function marked payable can receive Ether with the call. The amount sent is available in msg.value (in wei) and is added to the contract’s balance.

Answer : The transaction reverts, so the Ether is not accepted.

Answer : Yes. To require payment, add a check such as require(msg.value > 0) or require(msg.value == price).

Answer : With address(this).balance, which returns the balance in wei.

Answer : address payable is an address type that has the transfer and send members for receiving Ether. A plain address is converted with payable(addr).

Answer : addr.transfer(amount), addr.send(amount) and addr.call{value: amount}("").

Answer : Both forward a fixed 2300 gas. transfer reverts automatically if sending fails; send returns false instead, so its result must be checked.

Answer : It forwards enough gas for recipients that are contracts with more complex receive logic and returns a success flag. The developer must check the flag and guard against reentrancy.

Answer : Since Solidity 0.7.0 the syntax is address.call{value: amount}(""); gas can be set with {value: amount, gas: g}.

Answer : A function first checks all conditions, then updates the contract’s own state, and only at the end interacts with other addresses (e.g. sends Ether). This prevents reentrancy attacks.

Answer : An attack in which the recipient of an external call calls back into the vulnerable function before its state is updated, for example withdrawing the same balance repeatedly.

Answer : Instead of sending Ether to many users in one transaction, the contract records how much each user is owed and each user calls withdraw() to collect it. One failing recipient cannot block the others.

Answer : They do not revert on failure; they return false. Ignoring the result could make the contract believe a payment succeeded when it did not.

Answer : receive() external payable, or a fallback() marked payable.

Answer : In wei. Amounts can be written with units such as 1 ether, 0.01 ether or 1 gwei.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. Which keyword allows a function to receive Ether?

Show Answer

Correct Answer : B. payable
Only payable functions accept Ether.

Q2. Which method returns false instead of reverting when sending fails?

Show Answer

Correct Answer : B. send
send returns a bool; transfer reverts.

Q3. The recommended way to send Ether in modern Solidity is:

Show Answer

Correct Answer : C. addr.call{value: x}("") with a success check
call{value:} with a checked result, plus reentrancy protection.

Q4. In checks-effects-interactions, Ether should be sent:

Show Answer

Correct Answer : D. After updating state
State updates (effects) come before interactions.

Q5. address(this).balance returns:

Show Answer

Correct Answer : A. The contract’s Ether balance in wei
It is the current contract’s balance in wei.

Bibliography/References

The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.

  1. Solidity Team. (n.d.). Types (value types, reference types, mappings, operators, conversions). Solidity Documentation. https://docs.soliditylang.org/en/latest/types.html
  2. Solidity Team. (n.d.). Units and Globally Available Variables. Solidity Documentation. https://docs.soliditylang.org/en/latest/units-and-global-variables.html
  3. Solidity Team. (n.d.). Security Considerations. Solidity Documentation. https://docs.soliditylang.org/en/latest/security-considerations.html
  4. ethereum.org. (n.d.). Smart contract security. Ethereum Developer Documentation. https://ethereum.org/en/developers/docs/smart-contracts/security/
  5. Showwcase. (n.d.). Payable functions in Solidity. https://www.showwcase.com/show/33658/payable-functions-in-solidity
  6. Modi, R. (2018). Solidity Programming Essentials: A beginner’s guide to build smart contracts for Ethereum and blockchain. Packt Publishing. ISBN 978-1-78883-138-3.