diff --git a/docs/control-structures.rst b/docs/control-structures.rst index d46e7a4a28..6304637728 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -48,7 +48,16 @@ External functions (marked with the ``@external`` decorator) are a part of the c A Vyper contract cannot call directly between two external functions. If you must do this, you can use an :ref:`interface `. .. note:: - For external functions with default arguments like ``def my_function(x: uint256, b: uint256 = 1)`` the Vyper compiler will generate ``N+1`` overloaded function selectors based on ``N`` default arguments. + For external functions with default arguments like ``def my_function(x: uint256, b: uint256 = 1)`` the Vyper compiler will generate ``N+1`` overloaded function selectors based on ``N`` default arguments. Consequently, the ABI signature for a function (this includes interface functions) excludes optional arguments when their default values are used in the function call. + + .. code-block:: vyper + + from ethereum.ercs import IERC4626 + + @external + def foo(x: IERC4626): + extcall x.withdraw(0, self, self) # keccak256("withdraw(uint256,address,address)")[:4] = 0xb460af94 + extcall x.withdraw(0) # keccak256("withdraw(uint256)")[:4] = 0x2e1a7d4d .. _structure-functions-internal: @@ -75,6 +84,14 @@ Or for internal functions which are defined in :ref:`imported modules ` def calculate(amount: uint256) -> uint256: return calculator_library._times_two(amount) +Marking an internal function as ``payable`` specifies that the function can interact with ``msg.value``. A ``nonpayable`` internal function can be called from an external ``payable`` function, but it cannot access ``msg.value``. + +.. code-block:: vyper + + @payable + def _foo() -> uint256: + return msg.value % 2 + .. note:: As of v0.4.0, the ``@internal`` decorator is optional. That is, functions with no visibility decorator default to being ``internal``. @@ -110,7 +127,7 @@ You can optionally declare a function's mutability by using a :ref:`decorator