polkadot.rst 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. Polkadot
  2. ========
  3. Solang works on Polkadot Parachains integrating a recent version of the ``contracts`` pallets.
  4. Solidity flavored for the Polkadot target has the following differences to Ethereum Solidity:
  5. - The address type is 32 bytes, not 20 bytes. This is what Substrate calls an "account".
  6. - An address literal has to be specified using the ``address"5GBWmgdFAMqm8ZgAHGobqDqX6tjLxJhv53ygjNtaaAn3sjeZ"`` syntax
  7. - ABI encoding and decoding is done using the `SCALE <https://docs.substrate.io/reference/scale-codec/>`_ encoding
  8. - Constructors can be named. Constructors with no name will be called ``new`` in the generated metadata.
  9. - There is no ``ecrecover()`` builtin function, or any other function to recover or verify cryptographic signatures at runtime
  10. - Only functions called via rpc may return values; when calling a function in a transaction, the return values cannot be accessed
  11. There is a solidity example which can be found in the
  12. `examples <https://github.com/hyperledger/solang/tree/main/examples>`_
  13. directory. Write this to flipper.sol and run:
  14. .. code-block:: bash
  15. solang compile --target polkadot flipper.sol
  16. Now you should have a file called ``flipper.contract``. The file contains both the ABI and contract wasm.
  17. It can be used directly in the
  18. `Contracts UI <https://contracts-ui.substrate.io/>`_, as if the contract was written in ink!.
  19. Builtin Imports
  20. ________________
  21. Some builtin functionality is only available after importing. The following types
  22. can be imported via the special import file ``polkadot``.
  23. .. code-block:: solidity
  24. import {Hash} from 'polkadot';
  25. import {chain_extension} from 'polkadot';
  26. Note that ``{Hash}`` can be omitted, renamed or imported via
  27. import object.
  28. .. code-block:: solidity
  29. // Now Hash will be known as InkHash
  30. import {Hash as InkHash} from 'polkadot';
  31. .. note::
  32. The import file ``polkadot`` is only available when compiling for the Polkadot target.
  33. Call Flags
  34. __________
  35. The Substrate contracts pallet knows several
  36. `flags <https://github.com/paritytech/substrate/blob/6e0059a416a5768e58765a49b33c21920c0b0eb9/frame/contracts/src/wasm/runtime.rs#L392>`_
  37. that can be used when calling other contracts.
  38. Solang allows a ``flags`` call argument of type ``uint32`` in the ``address.call()`` function to set desired flags.
  39. By default (if this argument is unset), no flag will be set.
  40. The following example shows how call flags can be used:
  41. .. include:: ../examples/polkadot/call_flags.sol
  42. :code: solidity
  43. Reverts and error data decoding
  44. _______________________________
  45. When a contract reverts, the returned error data is what the
  46. `EVM would return <https://docs.soliditylang.org/en/v0.8.20/control-structures.html#panic-via-assert-and-error-via-require>`_.
  47. ``assert()``, ``require()``, or ``revert()`` will revert the contract execution, where the revert reason (if any) is
  48. encoded as ``Error(string)`` and provided in the execution output. Solidity contracts can also revert with a ``Panic(uint256)``
  49. (please refer to the
  50. `Ethereum Solidity language documentation <https://docs.soliditylang.org/en/v0.8.20/control-structures.html#panic-via-assert-and-error-via-require>`_
  51. for more information about when ``Panic`` might be returned).
  52. Uncaught exceptions from calling and instantiating contracts or transferring funds will be bubbled
  53. up back to the caller.
  54. .. note::
  55. Solidity knows about ``Error``, ``Panic`` and custom errors. Please, also refer to the
  56. `Ethereum Solidity documentation <https://docs.soliditylang.org/en/latest/abi-spec.html#errors>`_,
  57. for more information.
  58. The metadata contains all error variants that the contract `knows` about in the ``lang_error`` field.
  59. .. warning::
  60. Never trust the error data.
  61. Solidity contracts do bubble up uncaught errors. This can lead to situations where the
  62. contract reverts with error data unknown to the contracts. Examples of this include
  63. bubbling up custom error data from the callee or error data from an ``ink!`` contract.
  64. The 4 bytes selector of the error data can be seen as the enum discriminator or index. However,
  65. because SCALE encoding does not allow index larger than 1 byte, the hex-encoded error selector
  66. is provided as the path of the error variant type in the metadata.
  67. In the following example, the ``Panic`` variant of ``lang_error`` is of type ``10``, which looks like this:
  68. .. code-block:: json
  69. {
  70. "id": 10,
  71. "type": {
  72. "def": {
  73. "composite": {
  74. "fields": [
  75. {
  76. "type": 9
  77. }
  78. ]
  79. }
  80. },
  81. "path": [
  82. "0x4e487b71"
  83. ]
  84. }
  85. }
  86. From this follows that error data matching the ``Panic`` selector of `0x4e487b71` can be decoded
  87. according to type ``10`` (where the decoder must exclude the first 4 selector bytes).
  88. The general process of decoding the output data of Solang Solidity contracts is as follows:
  89. 1. The compiler of the contract must be Solang (check the ``compiler`` field in the contract metadata).
  90. 2. If the revert flag is **not** set, the contract didn't revert and the output should be decoded as specified in the message spec.
  91. 3. If the output length is smaller than 4 bytes, the error data can't be decoded (contracts may return empty error data, for example if ``revert()`` without arguments is used).
  92. 4. If the first 4 bytes of the output do **not** match any of the selectors found in ``lang_error``, the error can't be decoded.
  93. 5. **Skip** the selector (first 4 bytes) and decode the remaining data according to the matching type found in `lang_error`.