In Solidity, address payable and address (non-payable) are both used to store Ethereum addresses, but they have critical differences in functionality:
1. Key Difference: Ability to Receive Ether
| Feature | address payable | address (normal) |
|---|---|---|
| Can receive Ether | ✅ Yes (via transfer, send, call) | ❌ No |
| Convertible | Can be converted to address | Must be explicitly converted to payable |
| Use Case | Receiving funds, refunds, withdrawals | Storing addresses without Ether transfers |
2. How to Use Them
address payable (For Ether Transfers)
address payable public owner = payable(msg.sender);
function withdraw() public {
owner.transfer(address(this).balance); // ✅ Works
}
address (Normal, No Ether Transfers)
address public user = 0x...;
function doSomething() public {
// user.transfer(1 ether); ❌ Fails! Compiler error.
payable(user).transfer(1 ether); // ✅ Must convert first
}
3. Conversion Rules
-
From
addresstopayable:
Usepayable(...)(only works for accounts with a payable fallback function).address normalAddress = 0x...; address payable payableAddress = payable(normalAddress); // ✅ -
From
payabletoaddress:
Automatic (no explicit conversion needed).address payable owner = payable(msg.sender); address normalAddress = owner; // ✅
4. Why the Distinction?
- Security: Prevents accidental Ether transfers to addresses not designed to handle funds (e.g., contracts without payable functions).
- Gas Optimization: Compiler enforces checks to avoid failed transactions (saving gas).
5. When to Use Each
- Use
address payablefor:- Contract owners (to withdraw funds).
- Recipients of Ether payments.
- Use
addressfor:- Storing non-fund-related addresses (e.g., token holders).
- Contracts that don’t accept Ether.
Example: Safe Ether Transfer
function sendEther(address recipient) public payable {
address payable payableRecipient = payable(recipient); // Convert first
payableRecipient.transfer(msg.value); // ✅ Secure transfer
}
TL;DR
address payable: Can send/receive Ether.address: Just an identifier (no Ether transfers unless converted).- Always convert to
payablebefore transferring funds!
This design helps prevent bugs like locking Ether in contracts accidentally.