@@ -728,7 +728,7 @@ that has the same data representation as the input, whereas ``toUFixed256x18`` r
728
728
Function Types
729
729
--------------
730
730
731
- Function types are the types of functions. Variables of function type
731
+ Function types are the types of functions. Variables of a function type
732
732
can be assigned from functions and function parameters of function type
733
733
can be used to pass functions to and return functions from function calls.
734
734
Function types come in two flavours - *internal * and *external * functions:
@@ -743,6 +743,20 @@ contract internally.
743
743
External functions consist of an address and a function signature and they can
744
744
be passed via and returned from external function calls.
745
745
746
+ Note that public functions of the current contract can be used both as an
747
+ internal and as an external function. To use ``f `` as an internal function,
748
+ just use ``f ``, if you want to use its external form, use ``this.f ``.
749
+
750
+ If a function type variable is not initialised, calling it results
751
+ in a :ref: `Panic error<assert-and-require> `. The same happens if you call a function after using ``delete ``
752
+ on it.
753
+
754
+ .. note ::
755
+ Lambda or inline functions are planned but not yet supported.
756
+
757
+ Declaration syntax
758
+ ^^^^^^^^^^^^^^^^^^
759
+
746
760
Function types are notated as follows:
747
761
748
762
.. code-block :: solidity
@@ -759,7 +773,8 @@ omitted. Note that this only applies to function types. Visibility has
759
773
to be specified explicitly for functions defined in contracts, they
760
774
do not have a default.
761
775
762
- Conversions:
776
+ Conversions
777
+ ^^^^^^^^^^^
763
778
764
779
A function type ``A `` is implicitly convertible to a function type ``B `` if and only if
765
780
their parameter types are identical, their return types are identical,
@@ -788,18 +803,10 @@ Which makes it possible to assign a ``payable`` function pointer to a ``non-paya
788
803
function pointer ensuring both types behave the same way, i.e, both cannot be used
789
804
to send ether.
790
805
791
- If a function type variable is not initialised, calling it results
792
- in a :ref: `Panic error<assert-and-require> `. The same happens if you call a function after using ``delete ``
793
- on it.
794
-
795
806
If external function types are used outside of the context of Solidity,
796
807
they are treated as the ``function `` type, which encodes the address
797
808
followed by the function identifier together in a single ``bytes24 `` type.
798
809
799
- Note that public functions of the current contract can be used both as an
800
- internal and as an external function. To use ``f `` as an internal function,
801
- just use ``f ``, if you want to use its external form, use ``this.f ``.
802
-
803
810
A function of an internal type can be assigned to a variable of an internal function type regardless
804
811
of where it is defined.
805
812
This includes private, internal and public functions of both contracts and libraries as well as free
@@ -828,7 +835,8 @@ Libraries are excluded because they require a ``delegatecall`` and use :ref:`a d
828
835
convention for their selectors <library-selectors>`.
829
836
Functions declared in interfaces do not have definitions so pointing at them does not make sense either.
830
837
831
- Members:
838
+ Members
839
+ ^^^^^^^
832
840
833
841
External (or public) functions have the following members:
834
842
@@ -843,6 +851,59 @@ External (or public) functions have the following members:
843
851
respectively. See :ref: `External Function Calls <external-function-calls >` for
844
852
more information.
845
853
854
+ .. _function-type-value-stability-across-contract-updates :
855
+
856
+ Value stability across contract updates
857
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
858
+
859
+ An important aspect to consider when using values of function types is whether the value will
860
+ remain valid if the underlying code changes.
861
+
862
+ The state of the blockchain is not completely immutable and there are multiple ways to place
863
+ different code under the same address:
864
+
865
+ - Directly deploying different code using :ref: `salted contract creation<salted-contract-creations> `.
866
+ - Delegating to a different contract via :ref: `DELEGATECALL<delegatecall> `
867
+ (upgradeable code behind a proxy contract is a common example of this).
868
+ - Account abstraction as defined by `EIP-7702 <https://eips.ethereum.org/EIPS/eip-7702 >`_.
869
+
870
+ External function types can be considered as stable as contract's ABI, which makes them very portable.
871
+ Their ABI representation always consists of a contract address and a function selector and it is
872
+ perfectly safe to store them long-term or pass them between contracts.
873
+ While it is possible for the referenced function to change or disappear, a direct external call
874
+ would be affected the same way, so there is no additional risk in such use.
875
+
876
+ In case of internal functions, however, the value is an identifier that is strongly tied to
877
+ contract's bytecode.
878
+ The actual representation of the identifier is an implementation detail and may change between
879
+ compiler versions or even :ref: `between different backends<internal-function-pointers-in-ir> `.
880
+ Values assigned under a given representation are deterministic (i.e. guaranteed to remain the same
881
+ as long as the source code is the same) but are easily affected by changes such as adding, removing
882
+ or reordering of functions.
883
+ The compiler is also free to remove internal functions that are never used, which may affect other identifiers.
884
+ Some representations, e.g. one where identifiers are simply jump targets, may be affected by
885
+ virtually any change, even one completely unrelated to internal functions.
886
+
887
+ To counter this, the language limits the use of internal function types outside of the context in
888
+ which they are valid.
889
+ This is why internal function types cannot be used as parameters of external functions (or in any
890
+ other way that is exposed in contract's ABI).
891
+ However, there are still situations where it is up to the user to decide whether their use is safe or not.
892
+ For example long-term storage of such values in state variables is discouraged, but may be safe if
893
+ the contract code is never going to be updated.
894
+ It is also always possible to side-step any safeguards by using inline assembly.
895
+ Such use always needs careful consideration.
896
+
897
+ .. note ::
898
+ The removal of unused internal functions only takes into account explicit references to
899
+ such functions by name.
900
+ Implicit references, such as assigning a new value to a function type variable in inline assembly
901
+ may still lead to the removal of the function if it is not also referenced explicitly elsewhere
902
+ in the source.
903
+
904
+ Examples
905
+ ^^^^^^^^
906
+
846
907
Example that shows how to use the members:
847
908
848
909
.. code-block :: solidity
@@ -966,6 +1027,3 @@ Another example that uses external function types:
966
1027
exchangeRate = response;
967
1028
}
968
1029
}
969
-
970
- .. note ::
971
- Lambda or inline functions are planned but not yet supported.
0 commit comments