contracts.rst 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. Contracts
  2. =========
  3. Constructors and contract instantiation
  4. ---------------------------------------
  5. When a contract is deployed, the contract storage is initialized to the initializer values provided,
  6. and any constructor is called. A constructor is not required for a contract. A constructor is defined
  7. like so:
  8. .. include:: ../../examples/polkadot/flipper.sol
  9. :code: solidity
  10. A constructor can have any number of arguments.
  11. If a constructor has arguments, they must be supplied when the contract is deployed.
  12. If a contract is expected to receive value on instantiation, the constructor should be declared ``payable``.
  13. .. note::
  14. Solang allows naming constructors in the Polkadot target:
  15. .. include:: ../examples/polkadot/constructor_named.sol
  16. :code: solidity
  17. Constructors without a name will be called ``new`` in the metadata.
  18. Note that constructor names are only used in the generated metadata. For contract instantiation,
  19. the correct constructor matching the function signature will be selected automatically.
  20. Instantiation using new
  21. _______________________
  22. Contracts can be created using the ``new`` keyword. The contract that is being created might have
  23. constructor arguments, which need to be provided. While on Polkadot and Ethereum constructors return the address
  24. of the instantiated contract, on Solana, the address is either passed to the call using the ``{program_id: ...}`` call
  25. argument or is declared above a contract with the ``@program_id`` annotation. As the constructor does not return
  26. anything and its purpose is only to initialize the data account, the syntax ``new Contract()``is not idiomatic on Solana.
  27. Instead, a function ``new`` is made available to call the constructor.
  28. .. tabs::
  29. .. group-tab:: Polkadot
  30. .. include:: ../examples/polkadot/contract_new.sol
  31. :code: solidity
  32. .. group-tab:: Solana
  33. .. include:: ../examples/solana/contract_new.sol
  34. :code: solidity
  35. The constructor might fail for various reasons, for example ``require()`` might fail here. This can
  36. be handled using the :ref:`try-catch` statement, else errors cause the transaction to fail.
  37. .. note::
  38. On Solana, the :ref:`try-catch` statement is not supported, as any failure will
  39. cause the entire transaction to fail.
  40. .. _sending_values:
  41. Sending value to the new contract
  42. _________________________________
  43. It is possible to send value to the new contract. This can be done with the ``{value: 500}``
  44. syntax, like so:
  45. .. include:: ../examples/polkadot/contract_payable.sol
  46. :code: solidity
  47. The constructor should be declared ``payable`` for this to work.
  48. .. note::
  49. If no value is specified, then on Polkadot the minimum balance (also know as the
  50. existential deposit) is sent.
  51. .. note::
  52. On Solana, this functionality is not available.
  53. Setting the salt, gas, and address for the new contract
  54. _______________________________________________________
  55. .. note::
  56. The gas or salt cannot be set on Solana. However, when creating a contract
  57. on Solana, the address of the new account must be set using ``address:``.
  58. When a new contract is created, the address for the new contract is a hash of the input
  59. (the encoded constructor arguments) to the new contract and the salt. A contract cannot be
  60. created twice with the same input and salt. By giving a different salt, the same input
  61. can be used twice for a new contract. The salt can be set using the
  62. ``{salt: hex"439d399ee3b5b0fae6c8d567a8cbfa22d59f8f2c5fe308fd0a92366c116e5f1a"}``
  63. syntax, or if it is omitted, then a random value is used.
  64. Specifying a salt will remove the need for generating a random value at runtime, however
  65. care must be taken to avoid using the same salt more than once. Creating a contract twice
  66. with the same salt and arguments will fail. The salt is of type ``bytes32``.
  67. If gas is specified, this limits the amount gas the constructor for the new contract
  68. can use. gas is a ``uint64``.
  69. .. include:: ../examples/polkadot/contract_gas_limit.sol
  70. :code: solidity
  71. .. _solana_constructor:
  72. Solana constructors
  73. ___________________
  74. Solidity contracts are coupled to a data account, which stores the contract's state variables on the blockchain.
  75. This account must be initialized before calling other contract functions, if they require one. A contract constructor
  76. initializes the data account and can be called with the ``new`` function. When invoking the constructor from another
  77. contract, the data account to initialize appears in the IDL file and is identified as ``contractName_dataAccount``.
  78. In the example below, the IDL for the instruction ``test`` requires the ``hatchling_dataAccount`` account to be
  79. initialized as the new contract's data account.
  80. .. include:: ../examples/solana/contract_address.sol
  81. :code: solidity
  82. When there are no call arguments to a constructor call, the compiler will automatically create
  83. the ``AccountMeta`` array the constructor call needs. Due to the impossibility to track account ordering in
  84. private, internal and public functions, such a call argument is only allowed in functions with ``external``
  85. visibility. This automatic account management only works, however, if there is a single instantiation of
  86. a particular contract type.
  87. Alternatively, the data account to be initialized can be provided using the ``accounts`` call argument. In this case,
  88. one needs to instantiate a fixed length array of type ``AccountMeta`` to pass to the call. The array must contain all
  89. the accounts the transaction is going to need, in addition to the data account to be initialized.
  90. For the creation of a contract, the data account must the **first** element in such a vector and the system account
  91. ``11111111111111111111111111111111`` must also be present. If the constructor one is calling has the
  92. :ref:`@payer annotation <payer_seeds_bump>`, the payer account should appear in the array as well. Moreover, the
  93. ``is_signer`` and ``is_writable`` bool flags need to be properly set, according to the following example:
  94. .. include:: ../examples/solana/create_contract_with_metas.sol
  95. :code: solidity
  96. The sequence of the accounts in the ``AccountMeta`` array matters and must follow the
  97. :ref:`IDL ordering <account_management>`.
  98. .. _solana_contract_call:
  99. Calling a contract on Solana
  100. ____________________________
  101. A call to a contract on Solana follows a different syntax than that of Solidity on Ethereum or Polkadot. As contracts
  102. cannot be a variable, calling a contract's function follows the syntax ``Contract.function()``. If the contract
  103. definition contains the ``@program_id`` annotation, the CPI will be directed to the address declared inside the
  104. annotation.
  105. If that annotation is not present, the program address must be manually specified with the ``{program_id: ... }`` call
  106. argument. When both the annotation and the call argument are present, the compiler will forward the call to the address
  107. specified in the call argument.
  108. .. include:: ../examples/solana/contract_call.sol
  109. :code: solidity
  110. Base contracts, abstract contracts and interfaces
  111. -------------------------------------------------
  112. Solidity contracts support object-oriented programming. The style Solidity is somewhat similar to C++,
  113. but there are many differences. In Solidity we are dealing with contracts, not classes.
  114. Specifying base contracts
  115. _________________________
  116. To inherit from another contract, you have to specify it as a base contract. Multiple contracts can
  117. be specified here.
  118. .. include:: ../examples/contract_inheritance.sol
  119. :code: solidity
  120. In this case, contract ``a`` inherits from both ``b`` and ``c``. Both ``func1()`` and ``func2()``
  121. are visible in contract ``a``, and will be part of its public interface if they are declared ``public`` or
  122. ``external``. In addition, the contract storage variables ``foo`` and ``bar`` are also available in ``a``.
  123. Inheriting contracts is recursive; this means that if you inherit a contract, you also inherit everything
  124. that that contract inherits. In this example, contract ``a`` inherits ``b`` directly, and inherits ``c``
  125. through ``b``. This means that contract ``b`` also has a variable ``bar``.
  126. .. include:: ../examples/contract_recursive_inheritance.sol
  127. :code: solidity
  128. Virtual Functions
  129. _________________
  130. When inheriting from a base contract, it is possible to override a function with a newer function with the same name.
  131. For this to be possible, the base contract must have specified the function as ``virtual``. The
  132. inheriting contract must then specify the same function with the same name, arguments and return values, and
  133. add the ``override`` keyword.
  134. .. include:: ../examples/virtual_functions.sol
  135. :code: solidity
  136. If the function is present in more than one base contract, the ``override`` attribute must list all the base
  137. contracts it is overriding.
  138. .. include:: ../examples/virtual_functions_override.sol
  139. :code: solidity
  140. Calling function in base contract
  141. _________________________________
  142. When a virtual function is called, the dispatch is *virtual*. If the function being called is
  143. overridden in another contract, then the overriding function is called. For example:
  144. .. include:: ../examples/base_contract_function_call.sol
  145. :code: solidity
  146. Rather than specifying the base contract, use ``super`` as the contract to call the base contract
  147. function.
  148. .. include:: ../examples/super_contract_function_call.sol
  149. :code: solidity
  150. If there are multiple base contracts which the define the same function, the function of the first base
  151. contract is called.
  152. .. include:: ../examples/contract_multiple_inheritance.sol
  153. :code: solidity
  154. Specifying constructor arguments
  155. ________________________________
  156. If a contract inherits another contract, then when it is instantiated or deployed, then the constructor for
  157. its inherited contracts is called. The constructor arguments can be specified on the base contract itself.
  158. .. include:: ../examples/inherited_constructor_arguments.sol
  159. :code: solidity
  160. When ``a`` is deployed, the constructor for ``c`` is executed first, then ``b``, and lastly ``a``. When the
  161. constructor arguments are specified on the base contract, the values must be constant. It is possible to specify
  162. the base arguments on the constructor for inheriting contract. Now we have access to the constructor arguments,
  163. which means we can have runtime-defined arguments to the inheriting constructors.
  164. .. include:: ../examples/inherited_constructor_runtime_arguments.sol
  165. :code: solidity
  166. The execution is not entirely intuitive in this case. When contract ``a`` is deployed with an int argument of 10,
  167. then first the constructor argument or contract ``b`` is calculated: 10+2, and that value is used as an
  168. argument to constructor ``b``. constructor ``b`` calculates the arguments for constructor ``c`` to be: 12+3. Now,
  169. with all the arguments for all the constructors established, constructor ``c`` is executed with argument 15, then
  170. constructor ``b`` with argument 12, and lastly constructor ``a`` with the original argument 10.
  171. Abstract Contracts
  172. __________________
  173. An ``abstract contract`` is one that cannot be instantiated, but it can be used as a base for another contract,
  174. which can be instantiated. A contract can be abstract because the functions it defines do not have a body,
  175. for example:
  176. .. include:: ../examples/abstract_contract.sol
  177. :code: solidity
  178. This contract cannot be instantiated, since there is no body or implementation for ``func2``. Another contract
  179. can define this contract as a base contract and override ``func2`` with a body.
  180. Another reason why a contract must be abstract is missing constructor arguments. In this case, if we were to
  181. instantiate contract ``a`` we would not know what the constructor arguments to its base ``b`` would have to be.
  182. Note that contract ``c`` does inherit from ``a`` and can specify the arguments for ``b`` on its constructor,
  183. even though ``c`` does not directly inherit ``b`` (but does indirectly).
  184. .. include:: ../examples/abstract_contract_inheritance.sol
  185. :code: solidity