The payable keyword in Solidity and how to send and receive Ether
In this tutorial, we are going to learn about the payable keyword in Solidity and how to use it to send and receive Ether in your smart contract.
In this tutorial, we are going to learn about the payable keyword in Solidity and how to use it to send and receive Ether in your smart contract.
Here are a few examples of what you can do with the payable
keyword:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
contract PayableKeyword {
address[] public donators;
// Marking the construcor as payable allows to initialise your contract with some Ether
constructor() payable {
donators = [];
}
// A function that is payable can be called allong with some Ether
// That Ether will then be in the smart contract
// A non-payable function will throw a function if called along with some Ether
function donate() public payable {
donators.push(msg.sender);
// The amount of Eth sent is stored in msg.value
amountDonated += msg.value;
}
// This function allows you to withdraw the Ether that the contract has
function withdrawAll() public {
// get the amount of Ether the contract has
uint256 amount = address(this).balance;
// Send all the Ether to a payable address
// If it's an address and not a payable address, it will fail
(bool success, ) = payable(msg.sender).call{value: amount}("");
require(success, "Failed to send Ether");
}
}
How to receive Ether in your smart contract
To allow users to send Ether to your contract along with calling a function, that function needs to be marked as payable
.
Here is an example:
function deposit() external payable {
deposits += msg.value;
}
The amount of Ether that was sent along with calling that payable function will be stored in msg.value
. That amount will be in Wei
, meaning it is an integer that has 18 decimals of precision.
One of the use cases of msg.value
is to know if the user has sent enough Ether to pay for something.
If the function is not payable and the user tries to call it and send some Ether along with it, it will revert and throw an error.
Same for your constructor, if you want to fund your contract when you deploy it, the constructor needs to use the payable
keyword.
Here is an example:
constructor() payable {
initialBalance = msg.value;
}
How to get the Ether balance of your smart contract
Once you allowed users to send Ether to your smart contract, you might need to know, at any point in time, what's the amount of Ether that is stored in the smart contract.
To do that, we get the address of the smart contract using address(this)
and then just read the .balance
property:
address(this).balance;
That works with all variables of type address
so if you want to read the balance of an address, just read the balance
property of that variable.
How to send Ether from your smart contract
We've covered that part more in details here:
https://www.0xdev.co/how-to-send-a-transaction-in-solidity-from-a-smart-contract/
But to summarise, if you want to send Ether from your smart contract, you need to convert the address of the smart contract into a payable
address.
Payable addresses are a type of their own and they are different than the address
type. The difference is that payable
addresses can send and receive Ether and you can check their balance and non-payable addresses can't.
Here is an example:
function withdrawAll() public {
uint256 = address(this).balance;
(bool success, ) = payable(msg.sender).call{value: amount}("");
}
And that's it 🎉
Thank you for reading this article