Sending 0 eth to an address fails, but only if it is a contract.
@public
@payable
def __default__():
pass
@public
def send_0(a: address, amount: wei_value):
send(a, amount)
I tested this by creating two instances of this contract in Remix. Calling send_0 with an amount of 0 and a contract address reverts, else it succeeds.
This is by design. The @payable decorator ensures that msg.value > 0
I see. Thanks for the clarification!
Do you think this is clear from the docs though?
Not really. There is only a remark in the changelog "Functions without a @payable decorator now fail when called with nonzero wei." which is the converse of my question. It would be nice if all the decorators (@payable, @constant, @nonreentrant) could have their own section in the function documentation with a description of what they do.
@robinsierra thanks for your take. I think we should modify this issue to update the docs with a clearer explanation of what the @payable decorator does. I also believe that the "default" (fallback) function must be @payable by default, but @jacqueswww or @charles-cooper could correct me on that
There is a section in the docs: https://vyper.readthedocs.io/en/v0.1.0-beta.10/structure-of-a-contract.html#decorators.
But as always - please expand if you feel it's ambiguous :)
I think this something like this could be described there.
From default function section
If the function is annotated as @payable, this function is executed whenever the contract is sent Ether (without data). This is why the default function cannot accept arguments and return values - it is a design decision of Ethereum to make no differentiation between sending ether to a contract or a user address.
Ha!
I see this section is not rendering in the docs:
============================= ===========================================
Decorator Description
============================= ===========================================
`@public` Can be called from external contracts.
`@private` Can only be called within current contract.
`@constant` Does not alter contract state.
`@payable` The contract is open to receive Ether.
`@nonreentrant(<unique_key>)` Function can only be called once,
both externally and internally. Used to
prevent reentrancy attacks.
============================= ===========================================
https://github.com/ethereum/vyper/blob/master/docs/structure-of-a-contract.rst#decorators
This table shows on the docs now: https://vyper.readthedocs.io/en/v0.1.0-beta.11/structure-of-a-contract.html#decorators
Most helpful comment
Not really. There is only a remark in the changelog "Functions without a @payable decorator now fail when called with nonzero wei." which is the converse of my question. It would be nice if all the decorators (@payable, @constant, @nonreentrant) could have their own section in the function documentation with a description of what they do.