There are many ways to send Ether

There are several ways to use Solidity to transfer Ether. Here’s a quick review of the options.

1. Transfer (Deprecated)

payable(recipient).transfer(1 ether);

Simple enough, just take a payable address and use the built in transfer function. This reverts on failure, and only fowards 2300 gas to the recipient, the idea there being it’d be hard to perform reentrancy with such little gas left. However, EIP-1884 made some operations more gas expensive, so the idea that “oh 2300 gas is enough to do something useful” is not always true. For this reason, transfer() is now deprecated.

2. Send (Deprecated)

bool success = payable(recipient).send(1 ether);
require(success, "ETH send failed");

This is basically option 1 but without automatic reversion on failure. Instead your code has to explicitly check for failure and handle it. This .send() option is also deprecated, for the same reason as option 1.

3. Call with value (Use this)

(bool success, ) = payable(recipient).call{value: 1 ether}("");
require(success, "ETH transfer failed");

At last, an option that has stood the test of time! Making a “call with value” forwards all remaining gas unless manually limited with:

(bool success, ) = payable(recipient).call{value: 1 ether, gas: 5000}("");

We have to manually check for failure, so no automatic reversions. By default all gas is forwarded so there is a risk of reentrancy. This is the favoured way to send Ether at the time of writing.

4. Bonus Method - Wrap Call in OpenZeppelin Helper (Use this)

import "@openzeppelin/contracts/utils/Address.sol";
...
using Address for address;
...
recipient.sendValue(1 ether);

Using the OpenZeppelin Address library there is a helper function that lets us .sendValue(). This just wraps option 3 “call with value” and reverts if there is any issue, so there is no need to inspect booleans and we end up with a nice one-liner.

5. Bonus Method - Self Destruct (Deprecated)

For completeness, I’ll document the fact that if a contract self-destructs, it can force-send Ether to any address and bypass that address’s functions for receiving Ether, if there are any. In short, the Ether cannot be rejected by the nominated Ether-receiving address. However, self-destruct itself is deprecated and is likely going to be limited or removed in future.