# ALL about sending Ether - Transfer, Call , Send **Published by:** [IAMOTI](https://paragraph.com/@iamoti/) **Published on:** 2024-08-30 **URL:** https://paragraph.com/@iamoti/all-about-sending-ether-transfer-call-send ## Content Sending Ether in Solidity: A Comprehensive Technical Guide Introduction Sending Ether is a fundamental operation in Ethereum smart contracts. Over time, the recommended methods for transferring Ether have evolved due to security considerations and changes in the Ethereum protocol. This article will explore the three main methods of sending Ether: transfer(), send(), and call(), discussing their technical aspects, pros, cons, and current best practices. The Three Methods of Sending Ether 1. transfer() The transfer() function was introduced in later versions of Solidity as a safer alternative for sending Ether. Syntax: receivingAddress.transfer(amount); Key Features: Has a fixed gas stipend of 2300 gas Automatically reverts the transaction if the transfer fails Throws an exception on failure, allowing the calling contract to handle the error Initial Appeal: Automatic reversion: If the transfer failed, the transaction would automatically revert. Fixed gas stipend: It forwarded a fixed amount of 2300 gas to the receiving contract. Limitations and Issues: The fixed gas stipend can cause problems if gas costs change May fail if the receiving contract's fallback function requires more than 2300 gas Relies on fixed gas costs, making it vulnerable to network upgrades that change opcode gas costs Current Status: No longer recommended due to its reliance on fixed gas costs. 2. send() The send() function is similar to transfer() but with slightly different behavior. Syntax: bool success = receivingAddress.send(amount); Key Features: Also has a fixed gas stipend of 2300 gas Returns a boolean indicating success or failure Does not automatically revert the transaction on failure Limitations: Shares the same gas stipend limitations as transfer() Requires manual checking of the return value and error handling Current Status: Not recommended due to the same issues as transfer(). 3. call() The call() function is currently the recommended method for sending Ether. Syntax: (bool success, bytes memory data) = receivingAddress.call{value: amount}(""); Key Features: Allows for customizable gas limits Returns a boolean for success/failure and any return data More flexible, allowing for function calls along with Ether transfers Advantages: Not limited by fixed gas stipends Can adapt to changes in gas costs Provides more control over the transaction Allows transfer of data with ether Considerations: Requires careful implementation to prevent re-entrancy attacks Needs manual checking of the return value and error handling The Impact of Changing Opcode Gas Costs The fundamental issue with transfer() and send() lies in their reliance on a fixed gas stipend, which becomes problematic when gas costs for opcodes change. The Ethereum network periodically undergoes upgrades that can alter the gas costs of various operations, including storage operations (SSTORE and SLOAD). The Constantinople Upgrade: A Case Study The Constantinople upgrade in 2019 provides a clear example of how network changes can affect existing smart contracts. This upgrade aimed to optimize the network by reducing gas costs for certain SSTORE operations. While this change was beneficial in many ways, it had an unexpected consequence for contracts relying on transfer() and send(). Prior to the upgrade, the 2300 gas stipend was insufficient to perform storage operations, which was seen as a security feature preventing reentrancy attacks. However, the reduced gas costs meant that this stipend could now potentially allow for storage modifications, opening up new attack vectors. Best Practices for Sending Ether Given the lessons learned from the transfer() and send() deprecation, here are some best practices for sending Ether: Use call() instead of transfer() or send(): This is the current recommendation from the Ethereum community. Implement reentrancy guards: When using call(), always protect against reentrancy attacks. Check return values: Always check the success boolean returned by call() and handle failures appropriately. **Follow the checks-effects-interactions patternn ** Example Implementation // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract SafeEtherSender { // Reentrancy guard bool private locked = false; modifier noReentrant() { require(!locked, "No reentrancy"); locked = true; _; locked = false; } function sendEther(address payable _to, uint256 _amount) public payable noReentrant { // Perform any necessary checks require(_amount <= address(this).balance, "Insufficient balance"); // Use call to send Ether (bool success, ) = _to.call{value: _amount}(""); require(success, "Failed to send Ether"); // Emit an event or perform any post-send operations emit EtherSent(_to, _amount); } event EtherSent(address indexed to, uint256 amount); } Conclusion The evolution of Ether sending methods in Solidity serves as an important reminder of the dynamic nature of blockchain networks. While transfer() and send() were once considered safe methods for sending Ether, changes in the Ethereum protocol have made them less reliable. The current best practice is to use call() with proper safeguards against reentrancy and other potential vulnerabilities. This method offers more flexibility and resilience to network changes, but it requires developers to implement additional security measures. As the Ethereum ecosystem continues to evolve, it's crucial for developers to create flexible, adaptable smart contracts that can withstand changes in the underlying protocol. By understanding the reasons behind the shift away from transfer() and send(), and adopting best practices, developers can create more robust and future-proof smart contracts. Always stay updated with the latest Ethereum security recommendations and be prepared to adapt your code as the ecosystem evolves. Regular audits and updates to smart contracts are essential to ensure they remain secure and functional in the face of network changes. Reference https://solidity-by-example.org/sending-ether/ https://blockchain-academy.hs-mittweida.de/courses/solidity-coding-beginners-to-intermediate/lessons/solidity-2-sending-ether-receiving-ether-emitting-events/topic/sending-ether-send-vs-transfer-vs-call/ https://www.immunebytes.com/blog/transfer-in-solidity-why-you-should-stop-using-it/ https://github.com/ethereum/solidity/issues/7455 ## Publication Information - [IAMOTI](https://paragraph.com/@iamoti/): Publication homepage - [All Posts](https://paragraph.com/@iamoti/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@iamoti): Subscribe to updates - [Twitter](https://twitter.com/IAM0TI): Follow on Twitter