29

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?
50

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;
};
| improve this answer | |
  • 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. – Jakub Wojciechowski 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
  • 1
    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? – Jakub Wojciechowski 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
6

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
  }
}
| improve this answer | |
  • 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? – David 天宇 Wong Sep 27 '17 at 12:31
  • 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
3

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 { }
| improve this answer | |
1

A heads up for Solidity 0.6.0: there have been some pretty major changes to the way a fallback payable 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.

So what you have to do is replace this:

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

With either:

receive() external payable { ... }

Or:

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

But ideally you should go with receive.

| improve this answer | |

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.