Understanding ETH Transactions in Smart Contracts
Smart contracts on the Ethereum blockchain can both send and receive ETH (Ether) natively. This functionality enables a wide range of financial applications without intermediaries. Below we explore four key patterns for handling ETH within contracts.
1. Basic ETH-Receiving Contract
How It Works
Contracts receive ETH through a special payable fallback function. This default function executes when ETH is sent to the contract address without calling a specific method.
pragma solidity ^0.4.24;
contract SimpleReceivingContract {
function () payable public {}
function withdrawToOwner(address owner) public {
selfdestruct(owner);
}
}Key Points:
- The
payablemodifier allows ETH reception selfdestruct(address)sends all contract ETH to the specified address- After destruction, contract code becomes unusable
2. Auto-Refund Contract Pattern
Use Case
When accepting fixed payments (e.g., 1 ETH tickets), automatically refund excess amounts to prevent overpayment.
pragma solidity ^0.4.24;
contract AutoRefund {
address owner;
uint256 public constant TICKET_PRICE = 1 ether;
constructor() public {
owner = msg.sender;
}
function () public payable {
require(msg.value >= TICKET_PRICE);
if (msg.value > TICKET_PRICE) {
uint256 refundAmount = msg.value - TICKET_PRICE;
msg.sender.transfer(refundAmount);
}
}
}Features:
- Rejects payments below ticket price via
require - Calculates refund amount mathematically
- Uses
transfer()for secure refunds (2300 gas limit)
๐ Explore more Ethereum development patterns
3. Instant Forwarding Contract
Design Pattern
For scenarios requiring immediate fund movement, this contract forwards received ETH to a predefined owner address.
pragma solidity ^0.4.24;
contract ForwardingContract {
address public owner;
constructor() public {
owner = msg.sender;
}
function () payable public {
owner.transfer(msg.value);
}
}Advantages:
- No ETH accumulation in contract
- Gas costs paid by sender
- Simple and auditable code
4. Withdrawal Pattern with Ownership Controls
Secure ETH Management
This pattern implements proper access controls for fund withdrawal, following best practices for contract security.
pragma solidity ^0.4.24;
contract ManagedWithdrawal {
address public owner;
uint public balance;
modifier onlyOwner {
require(msg.sender == owner);
_;
}
constructor() public {
owner = msg.sender;
}
function () public payable {
balance += msg.value;
}
function withdraw() public onlyOwner {
owner.transfer(balance);
balance = 0;
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
owner = newOwner;
}
}Security Features:
- Explicit withdrawal function
- Ownership transfer capability
- State variable tracking balance
- Zero-address check
๐ Learn advanced Solidity security practices
FAQ: ETH Handling in Smart Contracts
Q: Can contracts receive ETH without a payable function?
A: No. The payable modifier is required for any function receiving ETH, including fallback functions.
Q: What's safer - transfer() or send()?
A: transfer() reverts on failure and has gas limits, making it safer than send() which returns false on failure.
Q: How do I handle variable payment amounts?
A: Implement validation logic in your payable function using require() statements.
Q: Can contracts pay other contracts?
A: Yes. Contracts can send ETH to other contracts if they have payable functions.
Q: What happens to ETH sent to destroyed contracts?
A: Funds become unrecoverable. Always withdraw funds before self-destructing.
Q: Why use withdrawal patterns instead of direct transfers?
A: Withdrawal patterns prevent reentrancy attacks and give users control over gas costs.
Key Takeaways
- Always mark ETH-receiving functions as
payable - Implement proper access controls for withdrawals
- Consider gas costs and security implications of transfer methods
- Test refund logic thoroughly to prevent fund loss
- Document expected ETH amounts and behaviors clearly
For further reading on Ethereum's financial infrastructure, consult the official Solidity documentation and security guidelines. The patterns shown here form the foundation for more complex DeFi applications.