aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/assembly.rst95
-rw-r--r--docs/solidity-by-example.rst9
-rw-r--r--docs/solidity-in-depth.rst2
-rw-r--r--docs/types.rst49
-rw-r--r--docs/units-and-global-variables.rst5
5 files changed, 102 insertions, 58 deletions
diff --git a/docs/assembly.rst b/docs/assembly.rst
index 91935293..90bfa1f1 100644
--- a/docs/assembly.rst
+++ b/docs/assembly.rst
@@ -4,22 +4,25 @@ Solidity Assembly
.. index:: ! assembly, ! asm, ! evmasm
-Solidity defines an assembly language that can also be used without Solidity.
-This assembly language can also be used as "inline assembly" inside Solidity
-source code. We start with describing how to use inline assembly and how it
-differs from standalone assembly and then specify assembly itself.
+Solidity defines an assembly language that you can use without Solidity and also
+as "inline assembly" inside Solidity source code. This guide starts with describing
+how to use inline assembly, how it differs from standalone assembly, and
+specifies assembly itself.
.. _inline-assembly:
Inline Assembly
===============
-For more fine-grained control especially in order to enhance the language by writing libraries,
-it is possible to interleave Solidity statements with inline assembly in a language close
-to the one of the virtual machine. Due to the fact that the EVM is a stack machine, it is
-often hard to address the correct stack slot and provide arguments to opcodes at the correct
-point on the stack. Solidity's inline assembly tries to facilitate that and other issues
-arising when writing manual assembly by the following features:
+You can interleave Solidity statements with inline assembly in a language close
+to the one of the virtual machine. This gives you more fine-grained control,
+especially when you are enhancing the language by writing libraries.
+
+As the EVM is a stack machine, it is often hard to address the correct stack slot
+and provide arguments to opcodes at the correct point on the stack. Solidity's inline
+assembly helps you do this, and with other issues that arise when writing manual assembly.
+
+Inline assembly has the following features:
* functional-style opcodes: ``mul(1, add(2, 3))``
* assembly-local variables: ``let x := add(2, 3) let y := mload(0x40) x := add(x, y)``
@@ -29,24 +32,38 @@ arising when writing manual assembly by the following features:
* switch statements: ``switch x case 0 { y := mul(x, 2) } default { y := 0 }``
* function calls: ``function f(x) -> y { switch x case 0 { y := 1 } default { y := mul(x, f(sub(x, 1))) } }``
-We now want to describe the inline assembly language in detail.
-
.. warning::
Inline assembly is a way to access the Ethereum Virtual Machine
- at a low level. This discards several important safety
- features of Solidity.
+ at a low level. This bypasses several important safety
+ features and checks of Solidity. You should only use it for
+ tasks that need it, and only if you are confident with using it.
-.. note::
- TODO: Write about how scoping rules of inline assembly are a bit different
- and the complications that arise when for example using internal functions
- of libraries. Furthermore, write about the symbols defined by the compiler.
+Syntax
+------
+
+Assembly parses comments, literals and identifiers in the same way as Solidity, so you can use the
+usual ``//`` and ``/* */`` comments. Inline assembly is marked by ``assembly { ... }`` and inside
+these curly braces, you can use the following (see the later sections for more details):
+
+ - literals, i.e. ``0x123``, ``42`` or ``"abc"`` (strings up to 32 characters)
+ - opcodes in functional style, e.g. ``add(1, mlod(0))``
+ - labels, e.g. ``name:``
+ - variable declarations, e.g. ``let x := 7``, ``let x := add(y, 3)`` or ``let x`` (initial value of empty (0) is assigned)
+ - identifiers (labels or assembly-local variables and externals if used as inline assembly), e.g. ``jump(name)``, ``3 x add``
+ - assignments (in "instruction style"), e.g. ``3 =: x``
+ - assignments in functional style, e.g. ``x := add(y, 3)``
+ - blocks where local variables are scoped inside, e.g. ``{ let x := 3 { let y := add(x, 1) } }``
+
+At the end of the ``assembly { ... }`` block, the stack must be balanced,
+unless you require it otherwise. If it is not balanced, the compiler generates
+a warning.
Example
-------
The following example provides library code to access the code of another contract and
-load it into a ``bytes`` variable. This is not possible at all with "plain Solidity" and the
-idea is that assembly libraries will be used to enhance the language in such ways.
+load it into a ``bytes`` variable. This is not possible with "plain Solidity" and the
+idea is that assembly libraries will be used to enhance the Solidity language.
.. code::
@@ -70,10 +87,8 @@ idea is that assembly libraries will be used to enhance the language in such way
}
}
-Inline assembly could also be beneficial in cases where the optimizer fails to produce
-efficient code. Please be aware that assembly is much more difficult to write because
-the compiler does not perform checks, so you should use it for complex things only if
-you really know what you are doing.
+Inline assembly is also beneficial in cases where the optimizer fails to produce
+efficient code, for example:
.. code::
@@ -125,22 +140,6 @@ you really know what you are doing.
}
-Syntax
-------
-
-Assembly parses comments, literals and identifiers exactly as Solidity, so you can use the
-usual ``//`` and ``/* */`` comments. Inline assembly is marked by ``assembly { ... }`` and inside
-these curly braces, the following can be used (see the later sections for more details)
-
- - literals, i.e. ``0x123``, ``42`` or ``"abc"`` (strings up to 32 characters)
- - opcodes in functional style, e.g. ``add(1, mlod(0))``
- - labels, e.g. ``name:``
- - variable declarations, e.g. ``let x := 7``, ``let x := add(y, 3)`` or ``let x`` (initial value of empty (0) is assigned)
- - identifiers (labels or assembly-local variables and externals if used as inline assembly), e.g. ``jump(name)``, ``3 x add``
- - assignments (in "instruction style"), e.g. ``3 =: x``
- - assignments in functional style, e.g. ``x := add(y, 3)``
- - blocks where local variables are scoped inside, e.g. ``{ let x := 3 { let y := add(x, 1) } }``
-
.. _opcodes:
Opcodes
@@ -368,17 +367,17 @@ Note that the order of arguments is reversed in functional-style as opposed to t
way. If you use functional-style, the first argument will end up on the stack top.
-Access to External Variables and Functions
-------------------------------------------
+Access to External Variables, Functions and Libraries
+-----------------------------------------------------
-Solidity variables and other identifiers can be accessed by simply using their name.
-For memory variables, this will push the address and not the value onto the
-stack. Storage variables are different: Values in storage might not occupy a
-full storage slot, so their "address" is composed of a slot and a byte-offset
+You can access Solidity variables and other identifiers by using their name.
+For variables stored in the memory data location, this pushes the address, and not the value
+onto the stack. Variables stored in the storage data location are different, as they might not
+occupy a full storage slot, so their "address" is composed of a slot and a byte-offset
inside that slot. To retrieve the slot pointed to by the variable ``x``, you
-used ``x_slot`` and to retrieve the byte-offset you used ``x_offset``.
+use ``x_slot``, and to retrieve the byte-offset you use ``x_offset``.
-In assignments (see below), we can even use local Solidity variables to assign to.
+Local Solidity variables are available for assignments, for example:
.. code::
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index 0b183ca5..d01886f8 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -220,7 +220,7 @@ bid. If the highest bid is raised, the previously
highest bidder gets her money back.
After the end of the bidding period, the
contract has to be called manually for the
-beneficiary to receive his money - contracts cannot
+beneficiary to receive their money - contracts cannot
activate themselves.
::
@@ -241,10 +241,11 @@ activate themselves.
// Allowed withdrawals of previous bids
mapping(address => uint) pendingReturns;
- // Set to true at the end, disallows any change
+ // Set to true at the end, disallows any change.
+ // By defaul initialized to `false`.
bool ended;
- // Events that will be fired on changes.
+ // Events that will be emitted on changes.
event HighestBidIncreased(address bidder, uint amount);
event AuctionEnded(address winner, uint amount);
@@ -372,7 +373,7 @@ is the same as the one provided during the bidding period.
Another challenge is how to make the auction
**binding and blind** at the same time: The only way to
prevent the bidder from just not sending the money
-after he won the auction is to make her send it
+after they won the auction is to make her send it
together with the bid. Since value transfers cannot
be blinded in Ethereum, anyone can see the value.
diff --git a/docs/solidity-in-depth.rst b/docs/solidity-in-depth.rst
index b6217b47..4a10a5a7 100644
--- a/docs/solidity-in-depth.rst
+++ b/docs/solidity-in-depth.rst
@@ -4,7 +4,7 @@ Solidity in Depth
This section should provide you with all you need to know about Solidity.
If something is missing here, please contact us on
-`Gitter <https://gitter.im/ethereum/solidity>`_ or make a pull request on
+`Gitter <https://gitter.im/ethereum/solidity>`_ or create a pull request on
`Github <https://github.com/ethereum/solidity/pulls>`_.
.. toctree::
diff --git a/docs/types.rst b/docs/types.rst
index 91f0c0ff..de384e2f 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -50,14 +50,25 @@ Operators:
* Comparisons: ``<=``, ``<``, ``==``, ``!=``, ``>=``, ``>`` (evaluate to ``bool``)
* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation)
-* Arithmetic operators: ``+``, ``-``, unary ``-``, unary ``+``, ``*``, ``/``, ``%`` (remainder), ``**`` (exponentiation), ``<<`` (left shift), ``>>`` (right shift)
+* Shift operators: ``<<`` (left shift), ``>>`` (right shift)
+* Arithmetic operators: ``+``, ``-``, unary ``-``, ``*``, ``/``, ``%`` (remainder), ``**`` (exponentiation)
-Division always truncates (it is just compiled to the ``DIV`` opcode of the EVM), but it does not truncate if both
-operators are :ref:`literals<rational_literals>` (or literal expressions).
-Division by zero and modulus with zero throws a runtime exception.
+Comparisons
+^^^^^^^^^^^
+
+The value of a comparison is the one obtained by comparing the integer value.
+
+Bit operations
+^^^^^^^^^^^^^^
+
+Bit operations are performed on the two's complement representation of the number.
+This means that, for example ``~int256(0) == int256(-1)``.
-The result of a shift operation is the type of the left operand. The
+Shifts
+^^^^^^
+
+The result of a shift operation has the type of the left operand. The
expression ``x << y`` is equivalent to ``x * 2**y``, and, for positive integers,
``x >> y`` is equivalent to ``x / 2**y``. For negative ``x``, ``x >> y``
is equivalent to dividing by a power of ``2`` while rounding down (towards negative infinity).
@@ -67,6 +78,34 @@ Shifting by a negative amount throws a runtime exception.
Before version ``0.5.0`` a right shift ``x >> y`` for negative ``x`` was equivalent to ``x / 2**y``,
i.e. right shifts used rounding towards zero instead of rounding towards negative infinity.
+Addition, Subtraction and Multiplication
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Addition, subtraction and multiplication have the usual semantics.
+They wrap in two's complement notation, meaning that
+for example ``uint256(0) - uint256(1) == 2**256 - 1``. You have to take these overflows
+into account when designing safe smart contracts.
+
+Division and Modulus
+^^^^^^^^^^^^^^^^^^^^
+
+Since the type of the result of an operation is always the type of one of
+the operands, division on integers always results in an integer.
+In Solidity, division rounds towards zero. This mean that ``int256(-5) / int256(2) == int256(-2)``.
+
+Note that in contrast, division on :ref:`literals<rational_literals>` results in fractional values
+of arbitrary precision.
+
+Division by zero and modulus with zero throws a runtime exception.
+
+Exponentiation
+^^^^^^^^^^^^^^
+
+Exponentiation is only available for unsigned types. Please take care that the types
+you are using are large enough to hold the result and prepare for potential wrapping behaviour.
+
+Note that ``0**0`` is defined by the EVM as ``1``.
+
.. index:: ! ufixed, ! fixed, ! fixed point number
Fixed Point Numbers
diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst
index 2e1b90a0..d6ef393e 100644
--- a/docs/units-and-global-variables.rst
+++ b/docs/units-and-global-variables.rst
@@ -151,6 +151,11 @@ Mathematical and Cryptographic Functions
recover the address associated with the public key from elliptic curve signature or return zero on error
(`example usage <https://ethereum.stackexchange.com/q/1777/222>`_)
+.. note::
+ Function ``ecrecover`` returns an ``address``, and not an ``address
+ payable``. See :ref:`address payable<address>` for conversion, in case you need
+ to transfer funds to the recovered address.
+
It might be that you run into Out-of-Gas for ``sha256``, ``ripemd160`` or ``ecrecover`` on a *private blockchain*. The reason for this is that those are implemented as so-called precompiled contracts and these contracts only really exist after they received the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution runs into an Out-of-Gas error. A workaround for this problem is to first send e.g. 1 Wei to each of the contracts before you use them in your actual contracts. This is not an issue on the official or test net.
.. index:: balance, send, transfer, call, callcode, delegatecall, staticcall