expressions.rst 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. Expressions
  2. ===========
  3. Solidity resembles the C family of languages. Expressions can use the following operators.
  4. Arithmetic operators
  5. ____________________
  6. The binary operators ``-``, ``+``, ``*``, ``/``, ``%``, and ``**`` are supported, and also
  7. in the assignment form ``-=``, ``+=``, ``*=``, ``/=``, and ``%=``. There is a
  8. unary operator ``-``.
  9. .. code-block:: solidity
  10. uint32 fahrenheit = celsius * 9 / 5 + 32;
  11. Parentheses can be used too, of course:
  12. .. code-block:: solidity
  13. uint32 celsius = (fahrenheit - 32) * 5 / 9;
  14. Operators can also come in the assignment form.
  15. .. code-block:: solidity
  16. balance += 10;
  17. The exponation (or power) can be used to multiply a number N times by itself, i.e.
  18. x :superscript:`y`. This can only be done for unsigned types.
  19. .. code-block:: solidity
  20. uint64 thousand = 1000;
  21. uint64 billion = thousand ** 3;
  22. Overflow checking is limited to types of 64 bits and smaller, if the `--math-overflow` command
  23. line argument is specified. No overflow checking is generated in `unchecked` blocks, like so:
  24. .. code-block:: solidity
  25. contract foo {
  26. function f(int64 n) public {
  27. unchecked {
  28. int64 j = n - 1;
  29. }
  30. }
  31. }
  32. .. warning::
  33. Overflow checking for types larger than ``int64`` (e.g. ``uint128``) is not implemented yet.
  34. Bitwise operators
  35. _________________
  36. The ``|``, ``&``, ``^`` are supported, as are the shift operators ``<<``
  37. and ``>>``. These are also available in the assignment form ``|=``, ``&=``,
  38. ``^=``, ``<<=``, and ``>>=``. Lastly there is a unary operator ``~`` to
  39. invert all the bits in a value.
  40. Logical operators
  41. _________________
  42. The logical operators ``||``, ``&&``, and ``!`` are supported. The ``||`` and ``&&``
  43. short-circuit. For example:
  44. .. code-block:: javascript
  45. bool foo = x > 0 || bar();
  46. bar() will not be called if the left hand expression evaluates to true, i.e. x is greater
  47. than 0. If x is 0, then bar() will be called and the result of the ``||`` will be
  48. the return value of bar(). Similarly, the right hand expressions of ``&&`` will not be
  49. evaluated if the left hand expression evaluates to ``false``; in this case, whatever
  50. ever the outcome of the right hand expression, the ``&&`` will result in ``false``.
  51. .. code-block:: javascript
  52. bool foo = x > 0 && bar();
  53. Now ``bar()`` will only be called if x *is* greater than 0. If x is 0 then the ``&&``
  54. will result in false, irrespective of what bar() would return, so bar() is not
  55. called at all. The expression elides execution of the right hand side, which is also
  56. called *short-circuit*.
  57. Conditional operator
  58. ____________________
  59. The ternary conditional operator ``? :`` is supported:
  60. .. code-block:: javascript
  61. uint64 abs = foo > 0 ? foo : -foo;
  62. Comparison operators
  63. ____________________
  64. It is also possible to compare values. For, this the ``>=``, ``>``, ``==``, ``!=``, ``<``, and ``<=``
  65. is supported. This is useful for conditionals.
  66. The result of a comparison operator can be assigned to a bool. For example:
  67. .. code-block:: javascript
  68. bool even = (value % 2) == 0;
  69. It is not allowed to assign an integer to a bool; an explicit comparision is needed to turn it into
  70. a bool.
  71. Increment and Decrement operators
  72. _________________________________
  73. The post-increment and pre-increment operators are implemented like you would expect. So, ``a++``
  74. evaluates to the value of ``a`` before incrementing, and ``++a`` evaluates to value of ``a``
  75. after incrementing.
  76. this
  77. ____
  78. The keyword ``this`` evaluates to the current contract. The type of this is the type of the
  79. current contract. It can be cast to ``address`` or ``address payable`` using a cast.
  80. .. code-block:: solidity
  81. contract kadowari {
  82. function nomi() public {
  83. kadowari c = this;
  84. address a = address(this);
  85. }
  86. }
  87. Function calls made via this are function calls through the external call mechanism; i.e. they
  88. have to serialize and deserialise the arguments and have the external call overhead. In addition,
  89. this only works with public functions.
  90. .. code-block:: solidity
  91. contract kadowari {
  92. function nomi() public {
  93. this.nokogiri(102);
  94. }
  95. function nokogiri(int a) public {
  96. // ...
  97. }
  98. }
  99. type(..) operators
  100. __________________
  101. For integer values, the minimum and maximum values the types can hold are available using the
  102. ``type(...).min`` and ``type(...).max`` operators. For unsigned integers, ``type(..).min``
  103. will always be 0.
  104. .. code-block:: javascript
  105. contract example {
  106. int16 stored;
  107. function func(int x) public {
  108. if (x < type(int16).min || x > type(int16).max) {
  109. revert("value will not fit");
  110. }
  111. stored = int16(x);
  112. }
  113. }
  114. The `EIP-165 <https://eips.ethereum.org/EIPS/eip-165>`_ interface value can be retrieved using the
  115. syntax ``type(...).interfaceId``. This is only permitted on interfaces. The interfaceId is simply
  116. an bitwise XOR of all function selectors in the interface. This makes it possible to uniquely identify
  117. an interface at runtime, which can be used to write a `supportsInterface()` function as described
  118. in the EIP.
  119. The contract code for a contract, i.e. the binary WebAssembly or BPF, can be retrieved using the
  120. ``type(c).creationCode`` and ``type(c).runtimeCode`` fields, as ``bytes``. In Ethereum,
  121. the constructor code is in the ``creationCode`` WebAssembly and all the functions are in
  122. the ``runtimeCode`` WebAssembly or BPF. Parity Substrate has a single WebAssembly code for both,
  123. so both fields will evaluate to the same value.
  124. .. code-block:: solidity
  125. contract example {
  126. function test() public {
  127. bytes runtime = type(other).runtimeCode;
  128. }
  129. }
  130. contract other {
  131. bool foo;
  132. }
  133. .. note::
  134. ``type().creationCode`` and ``type().runtimeCode`` are compile time constants.
  135. It is not possible to access the code for the current contract. If this were possible,
  136. then the contract code would need to contain itself as a constant array, which would
  137. result in an contract of infinite size.
  138. Ether and time units
  139. ____________________
  140. Any decimal numeric literal constant can have a unit denomination. For example
  141. ``10 minutes`` will evaluate to 600, i.e. the constant will be multiplied by the
  142. multiplier listed below. The following units are available:
  143. =========== =========================
  144. Unit Multiplier
  145. ``seconds`` 1
  146. ``minutes`` 60
  147. ``hours`` 3600
  148. ``days`` 86400
  149. ``weeks`` 604800
  150. ``wei`` 1
  151. ``ether`` 1_000_000_000_000_000_000
  152. =========== =========================
  153. Note that ``ether``, ``wei`` and the other Ethereum currency denominations are available when not
  154. compiling for Ethereum, but they will produce warnings.
  155. Casting
  156. _______
  157. Solidity is very strict about the sign of operations, and whether an assignment can truncate a
  158. value. You can force the compiler to accept truncations or differences in sign by adding a cast.
  159. Some examples:
  160. .. code-block:: solidity
  161. function abs(int bar) public returns (int64) {
  162. if (bar > 0) {
  163. return bar;
  164. } else {
  165. return -bar;
  166. }
  167. }
  168. The compiler will say:
  169. .. code-block:: none
  170. implicit conversion would truncate from int256 to int64
  171. Now you can work around this by adding a cast to the argument to return ``return int64(bar);``,
  172. however it would be much nicer if the return value matched the argument. Instead, implement
  173. multiple overloaded abs() functions, so that there is an ``abs()`` for each type.
  174. It is allowed to cast from a ``bytes`` type to ``int`` or ``uint`` (or vice versa), only if the length
  175. of the type is the same. This requires an explicit cast.
  176. .. code-block:: solidity
  177. bytes4 selector = "ABCD";
  178. uint32 selector_as_uint = uint32(selector);
  179. If the length also needs to change, then another cast is needed to adjust the length. Truncation and
  180. extension is different for integers and bytes types. Integers pad zeros on the left when extending,
  181. and truncate on the right. bytes pad on right when extending, and truncate on the left. For example:
  182. .. code-block:: solidity
  183. bytes4 start = "ABCD";
  184. uint64 start1 = uint64(uint4(start));
  185. // first cast to int, then extend as int: start1 = 0x41424344
  186. uint64 start2 = uint64(bytes8(start));
  187. // first extend as bytes, then cast to int: start2 = 0x4142434400000000
  188. A similar example for truncation:
  189. .. code-block:: javascript
  190. uint64 start = 0xdead_cafe;
  191. bytes4 start1 = bytes4(uint32(start));
  192. // first truncate as int, then cast: start1 = hex"cafe"
  193. bytes4 start2 = bytes4(bytes8(start));
  194. // first cast, then truncate as bytes: start2 = hex"dead"
  195. Since ``byte`` is array of one byte, a conversion from ``byte`` to ``uint8`` requires a cast.