45

I have read many examples of payable functions, but I didn't understand any of them. Also, they talked about modifier in payable. My questions are:

  1. What exactly does payable() function do?
  2. Does this function take arguments?
65

First, payable is a modifier that can be added to a function. What you are most likely misinterpreting is a use case like:

function () public payable {}  

It's impossible to have payable() as a function name as it is a reserved keyword. You may use payable only in addition to existing functions like:

function deposit() payable {}
function register(address sender) payable {}

Second, payable allows a function to receive ether while being called as stated in docs. It's mandatory to include the payable keyword from Solidity 0.4.x. If you try to send ether using call, as follows:

token.foo.call.value("ETH_TO_BE_SENT")("ADDITIONAL_DATA")

to a function without a payable keyword, the transaction will be rejected.

Usually, there is a no name function to accept ether to be sent to a contract which is called a fallback function:

function () payable {}

But you may have more than one payable annotated functions that are used to perform different tasks, like registering a deposit to your contract:

function deposit() payable {
  deposits[msg.sender] += msg.value;
};
7
  • 1
    you mean payable() is fallback function ? According to Solidity document fallback function is that function which avoid from accident of transaction to unknown contract. Please make me clear .
    – Gopal ojha
    Jul 11 '17 at 6:17
  • Thx for spotting that. I've misspelt it in a hurry, it's all corrected now. Jul 11 '17 at 10:23
  • 2
    you mean without , p.recipient.call.value(p.amount)(p.data) , payable() function cannot be called?
    – Gopal ojha
    Jul 11 '17 at 10:42
  • 2
    The fallback function is mandatory for contracts to be able to receive ether transfers from solidity 0.4.x. Then, if you always throw inside this function your contract won't be able to accept any ether - preventing accidental sending. If you leave the body empty or add any non-throwing code you will keep the ether on contract balance. I hope it answers your question? Jul 11 '17 at 11:09
  • 1
    yes you are absolutely correct . But what if in the case of payable() ?
    – Gopal ojha
    Jul 11 '17 at 11:13
8

When someone transfers funds to your contract, the function with payable modifier executes automatically. Here is an example of a payable function.

contract token {    
  function () payable {
    create(msg.sender);
  }
  function create(address _beneficiary) payable{
    uint256 amount = msg.value;
    /// your logic
  }
}
3
  • 2
    Your answer did not make me clear. You make a loop .
    – Gopal ojha
    Jul 11 '17 at 6:20
  • 2
    so do both the fallback function and the create function gets called at the same time (since they both have payable)? So create gets called twice? Sep 27 '17 at 12:31
  • 1
    Payable is a modifier, not a function. As a modifier, it explicitly allows the function to receive ether. With out it, a function throws if a value of ether is sent in the transaction. It is used to permission or prevent intentional and accidental value transfers.
    – o0ragman0o
    Oct 7 '17 at 1:23
8

Update for Solidity ^0.6.0

There have been major changes to the way the fallback function is defined.

From the docs:

The unnamed function commonly referred to as “fallback function” was split up into a new fallback function that is defined using the fallback keyword and a receive ether function defined using the receive keyword.

What you have to do is replace this:

function () external [payable] { ... }

With this:

receive() external payable { ... }

Or this:

fallback() external [payable] { ... }

In most cases, you should implement only receive. As per the docs:

You should only need to implement the new fallback function if you are following an upgrade or proxy pattern.

Diagram

Here's a nice diagram from the solidity-by-example.org website that explains what fallback function is called based on calldata:

Which function is called, fallback() or receive()?

        send Ether
            |
        msg.data is empty?
            / \
        yes  no
        /     \
receive() exists?  fallback()
        /   \
    yes   no
    /      \
receive()   fallback()
1
  • 2
    This needs more upvotes!
    – Richard
    Jul 31 at 0:46
6

Each function with the payable modifier can receive funds. But what if funds are sent to your contract to a non payable function? For this the fallback payable function was defined, which can receive funds in any case funds are sent to the contract. This is why can see in many contracts some version of a function with noname and a payable modifier. Notice - this is a fallback payable function. But payable is not the function name, it has no name, its the function modifier.

function *noname* () payable { }
0

payable is a function modifier means it checks if a certain condition is met before starting to execute a function.

the condition for a payable modifier is that the msg.value should not be null. means the transactions must contain some ether. any functions with the payable() as the modifier will only execute if the transaction has some ethers.

and for the parameters as far as I know payable() does not create any parameters

1
  • That is not correct, you can still execute a payable function sending 0 ethers, for example if the function doesn't do anything with msg.value. Check the accepted answer.
    – Ismael
    Sep 2 at 4:06
0

Solidity 0.8.0 has breaking changes:

  • address payable is not a type anymore. Only address will be.
  • payable(address) will ensure an address will be payable.
  • payable(0) is valid and is an exception.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.