# Solidity: Transfer Ether Safely Today

By [backdoor](https://paragraph.com/@backdoor705) · 2022-09-18

---

Solidity: Transfer Ether Safely Today
=====================================

> From [https://solidity-by-example.org/sending-ether/](https://solidity-by-example.org/sending-ether/)

3 ways to send Ether:

![](https://storage.googleapis.com/papyrus_images/fcc82c24f52912d4cb2bff89113d523eae97ff3bf82f2b47481da0473f201334.png)

2 ways to receive Ether:

A contract receiving Ether must have at least one of the functions below

*   `receive() external payable`
    
*   `fallback() external payable`
    

`receive()` is called if `msg.data` is empty, otherwise `fallback()` is called.

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.13;
    
    contract ReceiveEther {
        /*
        Which function is called, fallback() or receive()?
    
               send Ether
                   |
             msg.data is empty?
                  / \
                yes  no
                /     \
    receive() exists?  fallback()
             /   \
            yes   no
            /      \
        receive()   fallback()
        */
    
        // Function to receive Ether. msg.data must be empty
        receive() external payable {}
    
        // Fallback function is called when msg.data is not empty
        fallback() external payable {}
    
        function getBalance() public view returns (uint) {
            return address(this).balance;
        }
    }
    
    contract SendEther {
        function sendViaTransfer(address payable _to) public payable {
            // This function is no longer recommended for sending Ether.
            _to.transfer(msg.value);
        }
    
        function sendViaSend(address payable _to) public payable {
            // Send returns a boolean value indicating success or failure.
            // This function is not recommended for sending Ether.
            bool sent = _to.send(msg.value);
            require(sent, "Failed to send Ether");
        }
    
        function sendViaCall(address payable _to) public payable {
            // Call returns a boolean value indicating success or failure.
            // This is the current recommended method to use.
            (bool sent, bytes memory data) = _to.call{value: msg.value}("");
            require(sent, "Failed to send Ether");
        }
    }
    

Recommend ways for call.value
-----------------------------

> Use `call.value` + patterns that eliminate reentrancy
> 
> [https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/](https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/)

### **Checks-Effects-Interactions Pattern**

1.  perform some **checks** (who called the function, are the arguments in range, did they send enough Ether, does the person have tokens, etc.)
    
2.  **effects** to the state variables of the current contract should be made.
    
3.  Interaction with other contracts should be the very last step in any function.
    

make sure that all your _interactions_ (external calls) happen at the end.

    contract Fixed {
        ...
        function withdraw() external {
        // 1. Checks
        require(balanceOf[msg.sender] > 0); 
            // 2. Effects
            uint256 amount = balanceOf[msg.sender];
            balanceOf[msg.sender] = 0;
        // 3. Interactions
            (bool success, ) = msg.sender.call.value(amount)("");
            require(success, "Transfer failed.");
        }
    }
    

### Use a Reentrancy Guard

    contract Guarded {
        ...
    
        bool locked = false;
    
        function withdraw() external {
            require(!locked, "Reentrant call detected!");
            locked = true;
            ...
            locked = false;
        }
    }
    

*   `ReentrancyGuard` by OpenZeppelin
    

[https://docs.openzeppelin.com/contracts/4.x/api/security#ReentrancyGuard](https://docs.openzeppelin.com/contracts/4.x/api/security#ReentrancyGuard)

[https://blog.openzeppelin.com/reentrancy-after-istanbul/](https://blog.openzeppelin.com/reentrancy-after-istanbul/)

---

*Originally published on [backdoor](https://paragraph.com/@backdoor705/solidity-transfer-ether-safely-today)*
