🎓 A1Learner
🔍
0 of 50 lessons completed

Solidity Sending Ether

Sending ether means a contract pays ether out of its own balance to an address. This lesson uses two ways to pay, transfer and a low-level call.

transfer pays a chosen address

The vault pays an amount to the address it is given. A transfer that cannot complete reverts the whole call.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract Vault {
    function pay(address payable to, uint256 amount) public {
        to.transfer(amount);
    }
}

call sends ether and reports success

The low-level call form returns a bool instead of reverting. The function hands that flag back to its caller.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract Vault {
    function pay(address payable to, uint256 amount) public returns (bool) {
        (bool ok, ) = to.call{value: amount}("");
        return ok;
    }
}

Check the success flag before trusting a payment

A failed low-level call does not stop the function by itself. Requiring the flag to be true turns a failed payment into a revert.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract Vault {
    function payOrRevert(address payable to, uint256 amount) public {
        (bool ok, ) = to.call{value: amount}("");
        require(ok, "payment failed");
    }
}

Example

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract Vault {
    function payByTransfer(address payable to, uint256 amount) public {
        to.transfer(amount);
    }

    function payByCall(address payable to, uint256 amount) public returns (bool) {
        (bool ok, ) = to.call{value: amount}("");
        return ok;
    }
}

Key points

  • Contract balance: a contract can only send ether it actually holds.
  • Transfer: to.transfer(amount) pays ether out of the contract to that address.
  • Revert on failure: if a transfer cannot complete, the whole call reverts and no ether moves.
  • Low-level call: call{value: amount}("") is a flexible way to send ether that returns a success flag instead of reverting.
  • Success flag: always check the bool a low-level call returns before trusting that a payment happened.
  • Payable address: ether can only be sent to an address marked payable.

In this example, the Vault contract offers two payout functions. The payByTransfer function sends ether with transfer, so a failed payment reverts. The payByCall function sends ether with a low-level call and returns its success flag. Both pay out of the vault's own balance, so the vault keeps whatever it did not pay.

Note

transfer and call differ mainly in how failure is reported, not in the amount that moves.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Remix IDE

Exercise

A low-level call sends ether, but the payment cannot complete. What does the call give back?