Solidity Advanced: Sending and Receiving ETH in Smart Contracts

·

Introduction to ETH Transactions in Solidity

Ethereum transactions are fundamental to smart contract functionality. This guide explores the mechanisms for sending and receiving ETH within Solidity contracts, covering essential functions like payable, receive(), fallback(), and transfer methods (transfer, send, call).


Receiving ETH in Smart Contracts

Solidity provides two specialized callback functions for handling ETH:

  1. receive(): Dedicated exclusively to ETH transfers.
  2. fallback(): Triggered when calling non-existent functions or receiving ETH with data.

Payable Functions

A function marked with payable can accept ETH. Example:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
contract Payable {
    function deposit() external payable {}
    function getBalance() external view returns(uint) {
        return address(this).balance;
    }
}

Receive Function

Fallback Function

Key Differences Between receive and fallback

Featurereceive()fallback()
Trigger ConditionETH transfers onlyNo function match or ETH with data
Data HandlingNo dataAccepts data

Sending ETH from Smart Contracts

Solidity offers three primary methods to send ETH:

1. transfer()

2. send()

3. call()

Comparison Table

MethodReverts?Gas LimitReturn Value
transferYes2300None
sendNo2300bool
callNoCustom(bool, bytes)

Best Practices for ETH Transactions

  1. Use call for Forward Compatibility: Lower risk of gas-related failures.
  2. Validate Outcomes: Always check return values for send/call.
  3. Gas Considerations: Account for receiver logic complexity.

👉 Explore advanced Solidity patterns


FAQ Section

Q1: Why use receive() over fallback() for ETH transfers?

A: receive() is specifically optimized for pure ETH transfers without data, making it gas-efficient and clearer in intent.

Q2: When does fallback() execute?

A: When:

Q3: Is transfer() still safe to use?

A: While simple, its fixed gas limit can cause failures if the recipient’s logic exceeds 2300 gas. Prefer call with checks.

Q4: How to handle failed send() or call()?

A: Use require or conditional logic to revert or retry:

(bool success,) = _to.call{value: amount}("");
require(success, "Transfer failed");

Conclusion

Mastering ETH transactions involves understanding receive mechanisms, sending methods, and gas management. Adopt call for flexibility and always include failure handling.

👉 Learn more about smart contract security