aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-07-03 20:52:29 +0800
committerGitHub <noreply@github.com>2017-07-03 20:52:29 +0800
commit76d3b7c5a160e1f550c710e6850ee6f116142ca1 (patch)
tree93c96f7073617b4f56c8c355cdc30701aec4818b /docs
parent78969364608ba60d1654f4d1738886d13112b6cd (diff)
parent2222ddecf49b5b901f63b9e7449ee76c9f51c47a (diff)
downloaddexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.tar.gz
dexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.tar.zst
dexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.zip
Merge pull request #2510 from ethereum/develop
Version 0.4.12
Diffstat (limited to 'docs')
-rw-r--r--docs/abi-spec.rst345
-rw-r--r--docs/assembly.rst68
-rw-r--r--docs/bugs.json7
-rw-r--r--docs/bugs_by_version.json37
-rw-r--r--docs/contracts.rst61
-rw-r--r--docs/contributing.rst21
-rw-r--r--docs/control-structures.rst65
-rw-r--r--docs/grammar.txt34
-rw-r--r--docs/index.rst9
-rw-r--r--docs/installing-solidity.rst8
-rw-r--r--docs/introduction-to-smart-contracts.rst24
-rw-r--r--docs/layout-of-source-files.rst4
-rw-r--r--docs/logo.svg27
-rw-r--r--docs/miscellaneous.rst8
-rw-r--r--docs/solidity-by-example.rst24
-rw-r--r--docs/types.rst25
-rw-r--r--docs/units-and-global-variables.rst21
-rw-r--r--docs/using-the-compiler.rst2
-rw-r--r--docs/utils/SolidityLexer.py2
19 files changed, 643 insertions, 149 deletions
diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst
new file mode 100644
index 00000000..e39c8861
--- /dev/null
+++ b/docs/abi-spec.rst
@@ -0,0 +1,345 @@
+.. index:: abi, application binary interface
+
+.. _ABI:
+
+******************************************
+Application Binary Interface Specification
+******************************************
+
+Basic design
+============
+
+The Application Binary Interface is the standard way to interact with contracts in the Ethereum ecosystem, both
+from outside the blockchain and for contract-to-contract interaction. Data is encoded following its type,
+according to this specification.
+
+We assume the Application Binary Interface (ABI) is strongly typed, known at compilation time and static. No introspection mechanism will be provided. We assert that all contracts will have the interface definitions of any contracts they call available at compile-time.
+
+This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. Should these cases become important they can be adequately handled as facilities built within the Ethereum ecosystem.
+
+Function Selector
+=================
+
+The first four bytes of the call data for a function call specifies the function to be called. It is the
+first (left, high-order in big-endian) four bytes of the Keccak (SHA-3) hash of the signature of the function. The signature is defined as the canonical expression of the basic prototype, i.e.
+the function name with the parenthesised list of parameter types. Parameter types are split by a single comma - no spaces are used.
+
+Argument Encoding
+=================
+
+Starting from the fifth byte, the encoded arguments follow. This encoding is also used in other places, e.g. the return values and also event arguments are encoded in the same way, without the four bytes specifying the function.
+
+Types
+=====
+
+The following elementary types exist:
+
+- `uint<M>`: unsigned integer type of `M` bits, `0 < M <= 256`, `M % 8 == 0`. e.g. `uint32`, `uint8`, `uint256`.
+
+- `int<M>`: two's complement signed integer type of `M` bits, `0 < M <= 256`, `M % 8 == 0`.
+
+- `address`: equivalent to `uint160`, except for the assumed interpretation and language typing.
+
+- `uint`, `int`: synonyms for `uint256`, `int256` respectively (not to be used for computing the function selector).
+
+- `bool`: equivalent to `uint8` restricted to the values 0 and 1
+
+- `fixed<M>x<N>`: signed fixed-point decimal number of `M` bits, `0 < M <= 256`, `M % 8 ==0`, and `0 < N <= 80`, which denotes the value `v` as `v / (10 ** N)`.
+
+- `ufixed<M>x<N>`: unsigned variant of `fixed<M>x<N>`.
+
+- `fixed`, `ufixed`: synonyms for `fixed128x19`, `ufixed128x19` respectively (not to be used for computing the function selector).
+
+- `bytes<M>`: binary type of `M` bytes, `0 < M <= 32`.
+
+- `function`: equivalent to `bytes24`: an address, followed by a function selector
+
+The following (fixed-size) array type exists:
+
+- `<type>[M]`: a fixed-length array of the given fixed-length type.
+
+The following non-fixed-size types exist:
+
+- `bytes`: dynamic sized byte sequence.
+
+- `string`: dynamic sized unicode string assumed to be UTF-8 encoded.
+
+- `<type>[]`: a variable-length array of the given fixed-length type.
+
+Types can be combined to anonymous structs by enclosing a finite non-negative number
+of them inside parentheses, separated by commas:
+
+- `(T1,T2,...,Tn)`: anonymous struct (ordered tuple) consisting of the types `T1`, ..., `Tn`, `n >= 0`
+
+It is possible to form structs of structs, arrays of structs and so on.
+
+
+Formal Specification of the Encoding
+====================================
+
+We will now formally specify the encoding, such that it will have the following
+properties, which are especially useful if some arguments are nested arrays:
+
+Properties:
+
+ 1. The number of reads necessary to access a value is at most the depth of the value inside the argument array structure, i.e. four reads are needed to retrieve `a_i[k][l][r]`. In a previous version of the ABI, the number of reads scaled linearly with the total number of dynamic parameters in the worst case.
+
+ 2. The data of a variable or array element is not interleaved with other data and it is relocatable, i.e. it only uses relative "addresses"
+
+We distinguish static and dynamic types. Static types are encoded in-place and dynamic types are encoded at a separately allocated location after the current block.
+
+**Definition:** The following types are called "dynamic":
+* `bytes`
+* `string`
+* `T[]` for any `T`
+* `T[k]` for any dynamic `T` and any `k > 0`
+
+All other types are called "static".
+
+**Definition:** `len(a)` is the number of bytes in a binary string `a`.
+The type of `len(a)` is assumed to be `uint256`.
+
+We define `enc`, the actual encoding, as a mapping of values of the ABI types to binary strings such
+that `len(enc(X))` depends on the value of `X` if and only if the type of `X` is dynamic.
+
+**Definition:** For any ABI value `X`, we recursively define `enc(X)`, depending
+on the type of `X` being
+
+- `(T1,...,Tk)` for `k >= 0` and any types `T1`, ..., `Tk`
+
+ `enc(X) = head(X(1)) ... head(X(k-1)) tail(X(0)) ... tail(X(k-1))`
+
+ where `X(i)` is the `ith` component of the value, and
+ `head` and `tail` are defined for `Ti` being a static type as
+
+ `head(X(i)) = enc(X(i))` and `tail(X(i)) = ""` (the empty string)
+
+ and as
+
+ `head(X(i)) = enc(len(head(X(0)) ... head(X(k-1)) tail(X(0)) ... tail(X(i-1))))`
+ `tail(X(i)) = enc(X(i))`
+
+ otherwise, i.e. if `Ti` is a dynamic type.
+
+ Note that in the dynamic case, `head(X(i))` is well-defined since the lengths of
+ the head parts only depend on the types and not the values. Its value is the offset
+ of the beginning of `tail(X(i))` relative to the start of `enc(X)`.
+
+- `T[k]` for any `T` and `k`:
+
+ `enc(X) = enc((X[0], ..., X[k-1]))`
+
+ i.e. it is encoded as if it were an anonymous struct with `k` elements
+ of the same type.
+
+- `T[]` where `X` has `k` elements (`k` is assumed to be of type `uint256`):
+
+ `enc(X) = enc(k) enc([X[1], ..., X[k]])`
+
+ i.e. it is encoded as if it were an array of static size `k`, prefixed with
+ the number of elements.
+
+- `bytes`, of length `k` (which is assumed to be of type `uint256`):
+
+ `enc(X) = enc(k) pad_right(X)`, i.e. the number of bytes is encoded as a
+ `uint256` followed by the actual value of `X` as a byte sequence, followed by
+ the minimum number of zero-bytes such that `len(enc(X))` is a multiple of 32.
+
+- `string`:
+
+ `enc(X) = enc(enc_utf8(X))`, i.e. `X` is utf-8 encoded and this value is interpreted as of `bytes` type and encoded further. Note that the length used in this subsequent encoding is the number of bytes of the utf-8 encoded string, not its number of characters.
+
+- `uint<M>`: `enc(X)` is the big-endian encoding of `X`, padded on the higher-order (left) side with zero-bytes such that the length is a multiple of 32 bytes.
+- `address`: as in the `uint160` case
+- `int<M>`: `enc(X)` is the big-endian two's complement encoding of `X`, padded on the higher-oder (left) side with `0xff` for negative `X` and with zero bytes for positive `X` such that the length is a multiple of 32 bytes.
+- `bool`: as in the `uint8` case, where `1` is used for `true` and `0` for `false`
+- `fixed<M>x<N>`: `enc(X)` is `enc(X * 10**N)` where `X * 10**N` is interpreted as a `int256`.
+- `fixed`: as in the `fixed128x19` case
+- `ufixed<M>x<N>`: `enc(X)` is `enc(X * 10**N)` where `X * 10**N` is interpreted as a `uint256`.
+- `ufixed`: as in the `ufixed128x19` case
+- `bytes<M>`: `enc(X)` is the sequence of bytes in `X` padded with zero-bytes to a length of 32.
+
+Note that for any `X`, `len(enc(X))` is a multiple of 32.
+
+Function Selector and Argument Encoding
+=======================================
+
+All in all, a call to the function `f` with parameters `a_1, ..., a_n` is encoded as
+
+ `function_selector(f) enc((a_1, ..., a_n))`
+
+and the return values `v_1, ..., v_k` of `f` are encoded as
+
+ `enc((v_1, ..., v_k))`
+
+i.e. the values are combined into an anonymous struct and encoded.
+
+Examples
+========
+
+Given the contract:
+
+::
+
+ contract Foo {
+ function bar(bytes3[2] xy) {}
+ function baz(uint32 x, bool y) returns (bool r) { r = x > 32 || y; }
+ function sam(bytes name, bool z, uint[] data) {}
+ }
+
+
+Thus for our `Foo` example if we wanted to call `baz` with the parameters `69` and `true`, we would pass 68 bytes total, which can be broken down into:
+
+- `0xcdcd77c0`: the Method ID. This is derived as the first 4 bytes of the Keccak hash of the ASCII form of the signature `baz(uint32,bool)`.
+- `0x0000000000000000000000000000000000000000000000000000000000000045`: the first parameter, a uint32 value `69` padded to 32 bytes
+- `0x0000000000000000000000000000000000000000000000000000000000000001`: the second parameter - boolean `true`, padded to 32 bytes
+
+In total::
+
+ 0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001
+
+It returns a single `bool`. If, for example, it were to return `false`, its output would be the single byte array `0x0000000000000000000000000000000000000000000000000000000000000000`, a single bool.
+
+If we wanted to call `bar` with the argument `["abc", "def"]`, we would pass 68 bytes total, broken down into:
+
+- `0xfce353f6`: the Method ID. This is derived from the signature `bar(bytes3[2])`.
+- `0x6162630000000000000000000000000000000000000000000000000000000000`: the first part of the first parameter, a `bytes3` value `"abc"` (left-aligned).
+- `0x6465660000000000000000000000000000000000000000000000000000000000`: the second part of the first parameter, a `bytes3` value `"def"` (left-aligned).
+
+In total::
+
+ 0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000
+
+If we wanted to call `sam` with the arguments `"dave"`, `true` and `[1,2,3]`, we would pass 292 bytes total, broken down into:
+- `0xa5643bf2`: the Method ID. This is derived from the signature `sam(bytes,bool,uint256[])`. Note that `uint` is replaced with its canonical representation `uint256`.
+- `0x0000000000000000000000000000000000000000000000000000000000000060`: the location of the data part of the first parameter (dynamic type), measured in bytes from the start of the arguments block. In this case, `0x60`.
+- `0x0000000000000000000000000000000000000000000000000000000000000001`: the second parameter: boolean true.
+- `0x00000000000000000000000000000000000000000000000000000000000000a0`: the location of the data part of the third parameter (dynamic type), measured in bytes. In this case, `0xa0`.
+- `0x0000000000000000000000000000000000000000000000000000000000000004`: the data part of the first argument, it starts with the length of the byte array in elements, in this case, 4.
+- `0x6461766500000000000000000000000000000000000000000000000000000000`: the contents of the first argument: the UTF-8 (equal to ASCII in this case) encoding of `"dave"`, padded on the right to 32 bytes.
+- `0x0000000000000000000000000000000000000000000000000000000000000003`: the data part of the third argument, it starts with the length of the array in elements, in this case, 3.
+- `0x0000000000000000000000000000000000000000000000000000000000000001`: the first entry of the third parameter.
+- `0x0000000000000000000000000000000000000000000000000000000000000002`: the second entry of the third parameter.
+- `0x0000000000000000000000000000000000000000000000000000000000000003`: the third entry of the third parameter.
+
+In total::
+
+ 0xa5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003
+
+Use of Dynamic Types
+====================
+
+A call to a function with the signature `f(uint,uint32[],bytes10,bytes)` with values `(0x123, [0x456, 0x789], "1234567890", "Hello, world!")` is encoded in the following way:
+
+We take the first four bytes of `sha3("f(uint256,uint32[],bytes10,bytes)")`, i.e. `0x8be65246`.
+Then we encode the head parts of all four arguments. For the static types `uint256` and `bytes10`, these are directly the values we want to pass, whereas for the dynamic types `uint32[]` and `bytes`, we use the offset in bytes to the start of their data area, measured from the start of the value encoding (i.e. not counting the first four bytes containing the hash of the function signature). These are:
+
+ - `0x0000000000000000000000000000000000000000000000000000000000000123` (`0x123` padded to 32 bytes)
+ - `0x0000000000000000000000000000000000000000000000000000000000000080` (offset to start of data part of second parameter, 4*32 bytes, exactly the size of the head part)
+ - `0x3132333435363738393000000000000000000000000000000000000000000000` (`"1234567890"` padded to 32 bytes on the right)
+ - `0x00000000000000000000000000000000000000000000000000000000000000e0` (offset to start of data part of fourth parameter = offset to start of data part of first dynamic parameter + size of data part of first dynamic parameter = 4\*32 + 3\*32 (see below))
+
+After this, the data part of the first dynamic argument, `[0x456, 0x789]` follows:
+
+ - `0x0000000000000000000000000000000000000000000000000000000000000002` (number of elements of the array, 2)
+ - `0x0000000000000000000000000000000000000000000000000000000000000456` (first element)
+ - `0x0000000000000000000000000000000000000000000000000000000000000789` (second element)
+
+Finally, we encode the data part of the second dynamic argument, `"Hello, world!"`:
+
+ - `0x000000000000000000000000000000000000000000000000000000000000000d` (number of elements (bytes in this case): 13)
+ - `0x48656c6c6f2c20776f726c642100000000000000000000000000000000000000` (`"Hello, world!"` padded to 32 bytes on the right)
+
+All together, the encoding is (newline after function selector and each 32-bytes for clarity):
+
+::
+
+ 0x8be65246
+ 0000000000000000000000000000000000000000000000000000000000000123
+ 0000000000000000000000000000000000000000000000000000000000000080
+ 3132333435363738393000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000000000000000000000e0
+ 0000000000000000000000000000000000000000000000000000000000000002
+ 0000000000000000000000000000000000000000000000000000000000000456
+ 0000000000000000000000000000000000000000000000000000000000000789
+ 000000000000000000000000000000000000000000000000000000000000000d
+ 48656c6c6f2c20776f726c642100000000000000000000000000000000000000
+
+Events
+======
+
+Events are an abstraction of the Ethereum logging/event-watching protocol. Log entries provide the contract's address, a series of up to four topics and some arbitrary length binary data. Events leverage the existing function ABI in order to interpret this (together with an interface spec) as a properly typed structure.
+
+Given an event name and series of event parameters, we split them into two sub-series: those which are indexed and those which are not. Those which are indexed, which may number up to 3, are used alongside the Keccak hash of the event signature to form the topics of the log entry. Those which as not indexed form the byte array of the event.
+
+In effect, a log entry using this ABI is described as:
+
+- `address`: the address of the contract (intrinsically provided by Ethereum);
+- `topics[0]`: `keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")` (`canonical_type_of` is a function that simply returns the canonical type of a given argument, e.g. for `uint indexed foo`, it would return `uint256`). If the event is declared as `anonymous` the `topics[0]` is not generated;
+- `topics[n]`: `EVENT_INDEXED_ARGS[n - 1]` (`EVENT_INDEXED_ARGS` is the series of `EVENT_ARGS` that are indexed);
+- `data`: `abi_serialise(EVENT_NON_INDEXED_ARGS)` (`EVENT_NON_INDEXED_ARGS` is the series of `EVENT_ARGS` that are not indexed, `abi_serialise` is the ABI serialisation function used for returning a series of typed values from a function, as described above).
+
+JSON
+====
+
+The JSON format for a contract's interface is given by an array of function and/or event descriptions. A function description is a JSON object with the fields:
+
+- `type`: `"function"`, `"constructor"`, or `"fallback"` (the :ref:`unnamed "default" function <fallback-function>`);
+- `name`: the name of the function;
+- `inputs`: an array of objects, each of which contains:
+ * `name`: the name of the parameter;
+ * `type`: the canonical type of the parameter.
+- `outputs`: an array of objects similar to `inputs`, can be omitted if function doesn't return anything;
+- `constant`: `true` if function is :ref:`specified to not modify blockchain state <constant-functions>`);
+- `payable`: `true` if function accepts ether, defaults to `false`.
+
+`type` can be omitted, defaulting to `"function"`.
+
+Constructor and fallback function never have `name` or `outputs`. Fallback function doesn't have `inputs` either.
+
+Sending non-zero ether to non-payable function will throw. Don't do it.
+
+An event description is a JSON object with fairly similar fields:
+
+- `type`: always `"event"`
+- `name`: the name of the event;
+- `inputs`: an array of objects, each of which contains:
+ * `name`: the name of the parameter;
+ * `type`: the canonical type of the parameter.
+ * `indexed`: `true` if the field is part of the log's topics, `false` if it one of the log's data segment.
+- `anonymous`: `true` if the event was declared as `anonymous`.
+
+For example,
+
+::
+
+ contract Test {
+ function Test(){ b = 0x12345678901234567890123456789012; }
+ event Event(uint indexed a, bytes32 b)
+ event Event2(uint indexed a, bytes32 b)
+ function foo(uint a) { Event(a, b); }
+ bytes32 b;
+ }
+
+would result in the JSON:
+
+.. code:: json
+
+ [{
+ "type":"event",
+ "inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}],
+ "name":"Event"
+ }, {
+ "type":"event",
+ "inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}],
+ "name":"Event2"
+ }, {
+ "type":"event",
+ "inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}],
+ "name":"Event2"
+ }, {
+ "type":"function",
+ "inputs": [{"name":"a","type":"uint256"}],
+ "name":"foo",
+ "outputs": []
+ }]
diff --git a/docs/assembly.rst b/docs/assembly.rst
index 420cea17..83643634 100644
--- a/docs/assembly.rst
+++ b/docs/assembly.rst
@@ -13,6 +13,8 @@ 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.
+.. _inline-assembly:
+
Inline Assembly
===============
@@ -28,11 +30,8 @@ arising when writing manual assembly by the following features:
* access to external variables: ``function f(uint x) { assembly { x := sub(x, 1) } }``
* labels: ``let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0))``
* loops: ``for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) }``
-* 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))) } }``
-
-.. note::
- Of the above, loops, function calls and switch statements are not yet implemented.
+* 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.
@@ -182,6 +181,8 @@ In the grammar, opcodes are represented as pre-defined identifiers.
+-------------------------+------+-----------------------------------------------------------------+
| signextend(i, x) | | sign extend from (i*8+7)th bit counting from least significant |
+-------------------------+------+-----------------------------------------------------------------+
+| keccak256(p, n) | | keccak(mem[p...(p+n))) |
++-------------------------+------+-----------------------------------------------------------------+
| sha3(p, n) | | keccak(mem[p...(p+n))) |
+-------------------------+------+-----------------------------------------------------------------+
| jump(label) | `-` | jump to label / code position |
@@ -232,9 +233,17 @@ In the grammar, opcodes are represented as pre-defined identifiers.
+-------------------------+------+-----------------------------------------------------------------+
| extcodecopy(a, t, f, s) | `-` | like codecopy(t, f, s) but take code at address a |
+-------------------------+------+-----------------------------------------------------------------+
+| returndatasize | | size of the last returndata |
++-------------------------+------+-----------------------------------------------------------------+
+| returndatacopy(t, f, s) | `-` | copy s bytes from returndata at position f to mem at position t |
++-------------------------+------+-----------------------------------------------------------------+
| create(v, p, s) | | create new contract with code mem[p..(p+s)) and send v wei |
| | | and return the new address |
+-------------------------+------+-----------------------------------------------------------------+
+| create2(v, n, p, s) | | create new contract with code mem[p..(p+s)) at address |
+| | | keccak256(<address> . n . keccak256(mem[p..(p+s))) and send v |
+| | | wei and return the new address |
++-------------------------+------+-----------------------------------------------------------------+
| call(g, a, v, in, | | call contract at address a with input mem[in..(in+insize)) |
| insize, out, outsize) | | providing g gas and v wei and output area |
| | | mem[out..(out+outsize)) returning 0 on error (eg. out of gas) |
@@ -246,6 +255,9 @@ In the grammar, opcodes are represented as pre-defined identifiers.
| delegatecall(g, a, in, | | identical to `callcode` but also keep ``caller`` |
| insize, out, outsize) | | and ``callvalue`` |
+-------------------------+------+-----------------------------------------------------------------+
+| staticcall(g, a, in, | | identical to `call(g, a, 0, in, insize, out, outsize)` but do |
+| insize, out, outsize) | | not allow state modifications |
++-------------------------+------+-----------------------------------------------------------------+
| return(p, s) | `-` | end execution, return data mem[p..(p+s)) |
+-------------------------+------+-----------------------------------------------------------------+
| revert(p, s) | `-` | end execution, revert state changes, return data mem[p..(p+s)) |
@@ -312,8 +324,10 @@ would be written as follows
mstore(0x80, add(mload(0x80), 3))
-Functional style and instructional style can be mixed, but any opcode inside a
-functional style expression has to return exactly one stack slot (most of the opcodes do).
+Functional style expressions cannot use instructional style internally, i.e.
+``1 2 mstore(0x80, add)`` is not valid assembly, it has to be written as
+``mstore(0x80, add(2, 1))``. For opcodes that do not take arguments, the
+parentheses can be omitted.
Note that the order of arguments is reversed in functional-style as opposed to the instruction-style
way. If you use functional-style, the first argument will end up on the stack top.
@@ -431,11 +445,6 @@ As an example how this can be done in extreme cases, please see the following.
pop // We have to pop the manually pushed value here again.
}
-.. note::
-
- ``invalidJumpLabel`` is a pre-defined label. Jumping to this location will always
- result in an invalid jump, effectively aborting execution of the code.
-
Declaring Assembly-Local Variables
----------------------------------
@@ -491,9 +500,6 @@ is performed by replacing the variable's value on the stack by the new value.
Switch
------
-.. note::
- Switch is not yet implemented.
-
You can use a switch statement as a very basic version of "if/else".
It takes the value of an expression and compares it to several constants.
The branch corresponding to the matching constant is taken. Contrary to the
@@ -506,10 +512,10 @@ case called ``default``.
assembly {
let x := 0
switch calldataload(4)
- case 0: {
+ case 0 {
x := calldataload(0x24)
}
- default: {
+ default {
x := calldataload(0x44)
}
sstore(0, div(x, 2))
@@ -521,13 +527,10 @@ case does require them.
Loops
-----
-.. note::
- Loops are not yet implemented.
-
Assembly supports a simple for-style loop. For-style loops have
a header containing an initializing part, a condition and a post-iteration
part. The condition has to be a functional-style expression, while
-the other two can also be blocks. If the initializing part is a block that
+the other two are blocks. If the initializing part
declares any variables, the scope of these variables is extended into the
body (including the condition and the post-iteration part).
@@ -545,9 +548,6 @@ The following example computes the sum of an area in memory.
Functions
---------
-.. note::
- Functions are not yet implemented.
-
Assembly allows the definition of low-level functions. These take their
arguments (and a return PC) from the stack and also put the results onto the
stack. Calling a function looks the same way as executing a functional-style
@@ -559,7 +559,7 @@ defined outside of that function. There is no explicit ``return``
statement.
If you call a function that returns multiple values, you have to assign
-them to a tuple using ``(a, b) := f(x)`` or ``let (a, b) := f(x)``.
+them to a tuple using ``a, b := f(x)`` or ``let a, b := f(x)``.
The following example implements the power function by square-and-multiply.
@@ -568,12 +568,12 @@ The following example implements the power function by square-and-multiply.
assembly {
function power(base, exponent) -> result {
switch exponent
- 0: { result := 1 }
- 1: { result := base }
- default: {
+ case 0 { result := 1 }
+ case 1 { result := base }
+ default {
result := power(mul(base, base), div(exponent, 2))
switch mod(exponent, 2)
- 1: { result := mul(base, result) }
+ case 1 { result := mul(base, result) }
}
}
}
@@ -693,13 +693,13 @@ The following assembly will be generated::
mstore(0x40, 0x60) // store the "free memory pointer"
// function dispatcher
switch div(calldataload(0), exp(2, 226))
- case 0xb3de648b: {
+ case 0xb3de648b {
let (r) = f(calldataload(4))
let ret := $allocate(0x20)
mstore(ret, r)
return(ret, 0x20)
}
- default: { jump(invalidJumpLabel) }
+ default { revert(0, 0) }
// memory allocator
function $allocate(size) -> pos {
pos := mload(0x40)
@@ -744,7 +744,7 @@ After the desugaring phase it looks as follows::
}
$caseDefault:
{
- jump(invalidJumpLabel)
+ revert(0, 0)
jump($endswitch)
}
$endswitch:
@@ -850,8 +850,8 @@ Grammar::
AssemblyAssignment = '=:' Identifier
LabelDefinition = Identifier ':'
AssemblySwitch = 'switch' FunctionalAssemblyExpression AssemblyCase*
- ( 'default' ':' AssemblyBlock )?
- AssemblyCase = 'case' FunctionalAssemblyExpression ':' AssemblyBlock
+ ( 'default' AssemblyBlock )?
+ AssemblyCase = 'case' FunctionalAssemblyExpression AssemblyBlock
AssemblyFunctionDefinition = 'function' Identifier '(' IdentifierList? ')'
( '->' '(' IdentifierList ')' )? AssemblyBlock
AssemblyFor = 'for' ( AssemblyBlock | FunctionalAssemblyExpression)
diff --git a/docs/bugs.json b/docs/bugs.json
index 1a67d626..a0c0e7c4 100644
--- a/docs/bugs.json
+++ b/docs/bugs.json
@@ -1,5 +1,12 @@
[
{
+ "name": "SkipEmptyStringLiteral",
+ "summary": "If \"\" is used in a function call, the following function arguments will not be correctly passed to the function.",
+ "description": "If the empty string literal \"\" is used as an argument in a function call, it is skipped by the encoder. This has the effect that the encoding of all arguments following this is shifted left by 32 bytes and thus the function call data is corrupted.",
+ "fixed": "0.4.12",
+ "severity": "low"
+ },
+ {
"name": "ConstantOptimizerSubtraction",
"summary": "In some situations, the optimizer replaces certain numbers in the code with routines that compute different numbers.",
"description": "The optimizer tries to represent any number in the bytecode by routines that compute them with less gas. For some special numbers, an incorrect routine is generated. This could allow an attacker to e.g. trick victims about a specific amount of ether, or function calls to call different functions (or none at all).",
diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json
index 0f7346b4..cab79f05 100644
--- a/docs/bugs_by_version.json
+++ b/docs/bugs_by_version.json
@@ -1,6 +1,7 @@
{
"0.1.0": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"OptimizerStaleKnowledgeAboutSHA3",
@@ -15,6 +16,7 @@
},
"0.1.1": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"OptimizerStaleKnowledgeAboutSHA3",
@@ -29,6 +31,7 @@
},
"0.1.2": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"OptimizerStaleKnowledgeAboutSHA3",
@@ -43,6 +46,7 @@
},
"0.1.3": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"OptimizerStaleKnowledgeAboutSHA3",
@@ -57,6 +61,7 @@
},
"0.1.4": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"OptimizerStaleKnowledgeAboutSHA3",
@@ -71,6 +76,7 @@
},
"0.1.5": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"OptimizerStaleKnowledgeAboutSHA3",
@@ -85,6 +91,7 @@
},
"0.1.6": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -100,6 +107,7 @@
},
"0.1.7": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -115,6 +123,7 @@
},
"0.2.0": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -130,6 +139,7 @@
},
"0.2.1": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -145,6 +155,7 @@
},
"0.2.2": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -160,6 +171,7 @@
},
"0.3.0": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -174,6 +186,7 @@
},
"0.3.1": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -187,6 +200,7 @@
},
"0.3.2": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -200,6 +214,7 @@
},
"0.3.3": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -212,6 +227,7 @@
},
"0.3.4": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -224,6 +240,7 @@
},
"0.3.5": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -236,6 +253,7 @@
},
"0.3.6": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -246,6 +264,7 @@
},
"0.4.0": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -256,6 +275,7 @@
},
"0.4.1": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -266,16 +286,24 @@
},
"0.4.10": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction"
],
"released": "2017-03-15"
},
"0.4.11": {
- "bugs": [],
+ "bugs": [
+ "SkipEmptyStringLiteral"
+ ],
"released": "2017-05-03"
},
+ "0.4.12": {
+ "bugs": [],
+ "released": "2017-07-03"
+ },
"0.4.2": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage",
@@ -285,6 +313,7 @@
},
"0.4.3": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"HighOrderByteCleanStorage"
@@ -293,6 +322,7 @@
},
"0.4.4": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored"
],
@@ -300,6 +330,7 @@
},
"0.4.5": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored",
"OptimizerStateKnowledgeNotResetForJumpdest"
@@ -308,6 +339,7 @@
},
"0.4.6": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction",
"IdentityPrecompileReturnIgnored"
],
@@ -315,18 +347,21 @@
},
"0.4.7": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction"
],
"released": "2016-12-15"
},
"0.4.8": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction"
],
"released": "2017-01-13"
},
"0.4.9": {
"bugs": [
+ "SkipEmptyStringLiteral",
"ConstantOptimizerSubtraction"
],
"released": "2017-01-31"
diff --git a/docs/contracts.rst b/docs/contracts.rst
index 8d7af2c1..e9ea1b3b 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -20,7 +20,7 @@ Contracts can be created "from outside" or from Solidity contracts.
When a contract is created, its constructor (a function with the same
name as the contract) is executed once.
-A constructor is optional. Only one constructor is allowed and this means
+A constructor is optional. Only one constructor is allowed, and this means
overloading is not supported.
From ``web3.js``, i.e. the JavaScript
@@ -244,6 +244,7 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value
}
.. index:: ! getter;function, ! function;getter
+.. _getter_functions:
Getter Functions
================
@@ -273,7 +274,7 @@ be done at declaration.
The getter functions have external visibility. If the
symbol is accessed internally (i.e. without ``this.``),
-it is evaluated as a state variable and if it is accessed externally
+it is evaluated as a state variable. If it is accessed externally
(i.e. with ``this.``), it is evaluated as a function.
::
@@ -321,8 +322,8 @@ is no good way to provide the key for the mapping.
Function Modifiers
******************
-Modifiers can be used to easily change the behaviour of functions, for example
-to automatically check a condition prior to executing the function. They are
+Modifiers can be used to easily change the behaviour of functions. For example,
+they can automatically check a condition prior to executing the function. Modifiers are
inheritable properties of contracts and may be overridden by derived contracts.
::
@@ -405,8 +406,8 @@ inheritable properties of contracts and may be overridden by derived contracts.
}
}
-Multiple modifiers can be applied to a function by specifying them in a
-whitespace-separated list and will be evaluated in order.
+Multiple modifiers are applied to a function by specifying them in a
+whitespace-separated list and are evaluated in the order presented.
.. warning::
In an earlier version of Solidity, ``return`` statements in functions
@@ -441,7 +442,7 @@ The reason behind allowing side-effects on the memory allocator is that it
should be possible to construct complex objects like e.g. lookup-tables.
This feature is not yet fully usable.
-The compiler does not reserve a storage slot for these variables and every occurrence is
+The compiler does not reserve a storage slot for these variables, and every occurrence is
replaced by the respective constant expression (which might be computed to a single value by the optimizer).
Not all types for constants are implemented at this time. The only supported types are
@@ -458,11 +459,13 @@ value types and strings.
}
+.. _constant-functions:
+
******************
Constant Functions
******************
-Functions can be declared constant. These functions promise not to modify the state.
+Functions can be declared constant in which case they promise not to modify the state.
::
@@ -491,7 +494,7 @@ Fallback Function
A contract can have exactly one unnamed function. This function cannot have
arguments and cannot return anything.
It is executed on a call to the contract if none of the other
-functions matches the given function identifier (or if no data was supplied at
+functions match the given function identifier (or if no data was supplied at
all).
Furthermore, this function is executed whenever the contract receives plain
@@ -509,7 +512,8 @@ In particular, the following operations will consume more gas than the stipend p
Please ensure you test your fallback function thoroughly to ensure the execution cost is less than 2300 gas before deploying a contract.
.. warning::
- Contracts that receive Ether but do not define a fallback function
+ Contracts that receive Ether directly (without a function call, i.e. using ``send`` or ``transfer``)
+ but do not define a fallback function
throw an exception, sending back the Ether (this was different
before Solidity v0.4.0). So if you want your contract to receive Ether,
you have to implement a fallback function.
@@ -567,13 +571,12 @@ the contract and will be incorporated into the blockchain
and stay there as long as a block is accessible (forever as of
Frontier and Homestead, but this might change with Serenity). Log and
event data is not accessible from within contracts (not even from
-the contract that created a log).
+the contract that created them).
SPV proofs for logs are possible, so if an external entity supplies
a contract with such a proof, it can check that the log actually
-exists inside the blockchain (but be aware of the fact that
-ultimately, also the block headers have to be supplied because
-the contract can only see the last 256 block hashes).
+exists inside the blockchain. But be aware that block headers have to be supplied because
+the contract can only see the last 256 block hashes.
Up to three parameters can
receive the attribute ``indexed`` which will cause the respective arguments
@@ -590,7 +593,7 @@ not possible to filter for specific anonymous events by name.
All non-indexed arguments will be stored in the data part of the log.
.. note::
- Indexed arguments will not be stored themselves, you can only
+ Indexed arguments will not be stored themselves. You can only
search for the values, but it is impossible to retrieve the
values themselves.
@@ -605,7 +608,7 @@ All non-indexed arguments will be stored in the data part of the log.
uint _value
);
- function deposit(bytes32 _id) {
+ function deposit(bytes32 _id) payable {
// Any call to this function (even deeply nested) can
// be detected from the JavaScript API by filtering
// for `Deposit` to be called.
@@ -679,9 +682,9 @@ Solidity supports multiple inheritance by copying code including polymorphism.
All function calls are virtual, which means that the most derived function
is called, except when the contract name is explicitly given.
-Even if a contract inherits from multiple other contracts, only a single
-contract is created on the blockchain, the code from the base contracts
-is always copied into the final contract.
+When a contract inherits from multiple contracts, only a single
+contract is created on the blockchain, and the code from all the base contracts
+is copied into the created contract.
The general inheritance system is very similar to
`Python's <https://docs.python.org/3/tutorial/classes.html#inheritance>`_,
@@ -818,7 +821,7 @@ derived override, but this function will bypass
}
If ``Base1`` calls a function of ``super``, it does not simply
-call this function on one of its base contracts, it rather
+call this function on one of its base contracts. Rather, it
calls this function on the next base contract in the final
inheritance graph, so it will call ``Base2.kill()`` (note that
the final inheritance sequence is -- starting with the most
@@ -834,7 +837,7 @@ Arguments for Base Constructors
===============================
Derived contracts need to provide all arguments needed for
-the base constructors. This can be done at two places::
+the base constructors. This can be done in two ways::
pragma solidity ^0.4.0;
@@ -849,7 +852,7 @@ the base constructors. This can be done at two places::
}
}
-Either directly in the inheritance list (``is Base(7)``) or in
+One way is directly in the inheritance list (``is Base(7)``). The other is in
the way a modifier would be invoked as part of the header of
the derived constructor (``Base(_y * _y)``). The first way to
do it is more convenient if the constructor argument is a
@@ -865,7 +868,7 @@ Multiple Inheritance and Linearization
======================================
Languages that allow multiple inheritance have to deal with
-several problems, one of them being the `Diamond Problem <https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem>`_.
+several problems. One is the `Diamond Problem <https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem>`_.
Solidity follows the path of Python and uses "`C3 Linearization <https://en.wikipedia.org/wiki/C3_linearization>`_"
to force a specific order in the DAG of base classes. This
results in the desirable property of monotonicity but
@@ -937,7 +940,7 @@ Interfaces are similar to abstract contracts, but they cannot have any functions
Some of these restrictions might be lifted in the future.
-Interfaces are basically limited to what the Contract ABI can represent and the conversion between the ABI and
+Interfaces are basically limited to what the Contract ABI can represent, and the conversion between the ABI and
an Interface should be possible without any information loss.
Interfaces are denoted by their own keyword:
@@ -976,9 +979,9 @@ contracts (``L.f()`` if ``L`` is the name of the library). Furthermore,
if the library were a base contract. Of course, calls to internal functions
use the internal calling convention, which means that all internal types
can be passed and memory types will be passed by reference and not copied.
-In order to realise this in the EVM, code of internal library functions
-(and all functions called from therein) will be pulled into the calling
-contract and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL``.
+To realize this in the EVM, code of internal library functions
+and all functions called from therein will be pulled into the calling
+contract, and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL``.
.. index:: using for, set
@@ -1041,8 +1044,8 @@ more advanced example to implement a set).
Of course, you do not have to follow this way to use
libraries - they can also be used without defining struct
-data types, functions also work without any storage
-reference parameters, can have multiple storage reference
+data types. Functions also work without any storage
+reference parameters, and they can have multiple storage reference
parameters and in any position.
The calls to ``Set.contains``, ``Set.insert`` and ``Set.remove``
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 42204d5c..559f9f6a 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -12,7 +12,7 @@ In particular, we need help in the following areas:
* Improving the documentation
* Responding to questions from other users on `StackExchange
- <http://ethereum.stackexchange.com/>`_ and the `Solidity Gitter
+ <https://ethereum.stackexchange.com>`_ and the `Solidity Gitter
<https://gitter.im/ethereum/solidity>`_
* Fixing and responding to `Solidity's GitHub issues
<https://github.com/ethereum/solidity/issues>`_, especially those tagged as
@@ -74,3 +74,22 @@ To run a subset of tests, filters can be used:
``soltest -t TestSuite/TestName -- --ipcpath /tmp/testeth/geth.ipc``, where ``TestName`` can be a wildcard ``*``.
Alternatively, there is a testing script at ``scripts/test.sh`` which executes all tests.
+
+Whiskers
+========
+
+*Whiskers* is a templating system similar to `Moustache <https://mustache.github.io>`_. It is used by the
+compiler in various places to aid readability, and thus maintainability and verifiability, of the code.
+
+The syntax comes with a substantial difference to Moustache: the template markers ``{{`` and ``}}`` are
+replaced by ``<`` and ``>`` in order to aid parsing and avoid conflicts with :ref:`inline-assembly`
+(The symbols ``<`` and ``>`` are invalid in inline assembly, while ``{`` and ``}`` are used to delimit blocks).
+Another limitation is that lists are only resolved one depth and they will not recurse. This may change in the future.
+
+A rough specification is the following:
+
+Any occurrence of ``<name>`` is replaced by the string-value of the supplied variable ``name`` without any
+escaping and without iterated replacements. An area can be delimited by ``<#name>...</name>``. It is replaced
+by as many concatenations of its contents as there were sets of variables supplied to the template system,
+each time replacing any ``<inner>`` items by their respective value. Top-level variales can also be used
+inside such areas. \ No newline at end of file
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index a2d34274..03787c20 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -361,55 +361,72 @@ As a result, the following code is legal, despite being poorly written::
return bar;// returns 5
}
-.. index:: ! exception, ! throw
+.. index:: ! exception, ! throw, ! assert, ! require, ! revert
-Exceptions
-==========
+Error handling: Assert, Require, Revert and Exceptions
+======================================================
+
+Solidity uses state-reverting exceptions to handle errors. Such an exception will undo all changes made to the
+state in the current call (and all its sub-calls) and also flag an error to the caller.
+The convenience functions ``assert`` and ``require`` can be used to check for conditions and throw an exception
+if the condition is not met. The difference between the two is that ``assert`` should only be used for internal errors
+and ``require`` should be used to check external conditions (invalid inputs or errors in external components).
+The idea behind that is that analysis tools can check your contract and try to come up with situations and
+series of function calls that will reach a failing assertion. If this is possible, this means there is a bug
+in your contract you should fix.
-There are some cases where exceptions are thrown automatically (see below). You can use the ``throw`` instruction to throw an exception manually. The effect of an exception is that the currently executing call is stopped and reverted (i.e. all changes to the state and balances are undone) and the exception is also "bubbled up" through Solidity function calls (exceptions are ``send`` and the low-level functions ``call``, ``delegatecall`` and ``callcode``, those return ``false`` in case of an exception).
+There are two other ways to trigger execptions: The ``revert`` function can be used to flag an error and
+revert the current call. In the future it might be possible to also include details about the error
+in a call to ``revert``. The ``throw`` keyword can also be used as an alternative to ``revert()``.
+
+When exceptions happen in a sub-call, they "bubble up" (i.e. exceptions are rethrown) automatically. Exceptions to this rule are ``send``
+and the low-level functions ``call``, ``delegatecall`` and ``callcode`` -- those return ``false`` in case
+of an exception instead of "bubbling up".
Catching exceptions is not yet possible.
-In the following example, we show how ``throw`` can be used to easily revert an Ether transfer and also how to check the return value of ``send``::
+In the following example, you can see how ``require`` can be used to easily check conditions on inputs
+and how ``assert`` can be used for internal error checking::
pragma solidity ^0.4.0;
contract Sharer {
function sendHalf(address addr) payable returns (uint balance) {
- if (!addr.send(msg.value / 2))
- throw; // also reverts the transfer to Sharer
+ require(msg.value % 2 == 0); // Only allow even numbers
+ uint balanceBeforeTransfer = this.balance;
+ addr.transfer(msg.value / 2);
+ // Since transfer throws an exception on failure and
+ // cannot call back here, there should be no way for us to
+ // still have half of the money.
+ assert(this.balance == balanceBeforeTransfer - msg.value / 2);
return this.balance;
}
}
-Currently, Solidity automatically generates a runtime exception in the following situations:
+An ``assert``-style exception is generated in the following situations:
#. If you access an array at a too large or negative index (i.e. ``x[i]`` where ``i >= x.length`` or ``i < 0``).
#. If you access a fixed-length ``bytesN`` at a too large or negative index.
-#. If you call a function via a message call but it does not finish properly (i.e. it runs out of gas, has no matching function, or throws an exception itself), except when a low level operation ``call``, ``send``, ``delegatecall`` or ``callcode`` is used. The low level operations never throw exceptions but indicate failures by returning ``false``.
-#. If you create a contract using the ``new`` keyword but the contract creation does not finish properly (see above for the definition of "not finish properly").
#. If you divide or modulo by zero (e.g. ``5 / 0`` or ``23 % 0``).
#. If you shift by a negative amount.
#. If you convert a value too big or negative into an enum type.
-#. If you perform an external function call targeting a contract that contains no code.
-#. If your contract receives Ether via a public function without ``payable`` modifier (including the constructor and the fallback function).
-#. If your contract receives Ether via a public getter function.
#. If you call a zero-initialized variable of internal function type.
-#. If a ``.transfer()`` fails.
#. If you call ``assert`` with an argument that evaluates to false.
-While a user-provided exception is generated in the following situations:
+A ``require``-style exception is generated in the following situations:
#. Calling ``throw``.
#. Calling ``require`` with an argument that evaluates to ``false``.
+#. If you call a function via a message call but it does not finish properly (i.e. it runs out of gas, has no matching function, or throws an exception itself), except when a low level operation ``call``, ``send``, ``delegatecall`` or ``callcode`` is used. The low level operations never throw exceptions but indicate failures by returning ``false``.
+#. If you create a contract using the ``new`` keyword but the contract creation does not finish properly (see above for the definition of "not finish properly").
+#. If you perform an external function call targeting a contract that contains no code.
+#. If your contract receives Ether via a public function without ``payable`` modifier (including the constructor and the fallback function).
+#. If your contract receives Ether via a public getter function.
+#. If a ``.transfer()`` fails.
-Internally, Solidity performs a revert operation (instruction ``0xfd``) when a user-provided exception is thrown or the condition of
-a ``require`` call is not met. In contrast, it performs an invalid operation
-(instruction ``0xfe``) if a runtime exception is encountered or the condition of an ``assert`` call is not met. In both cases, this causes
-the EVM to revert all changes made to the state. The reason for this is that there is no safe way to continue execution, because an expected effect
+Internally, Solidity performs a revert operation (instruction ``0xfd``) for a ``require``-style exception and executes an invalid operation
+(instruction ``0xfe``) to throw an ``assert``-style exception. In both cases, this causes
+the EVM to revert all changes made to the state. The reason for reverting is that there is no safe way to continue execution, because an expected effect
did not occur. Because we want to retain the atomicity of transactions, the safest thing to do is to revert all changes and make the whole transaction
-(or at least call) without effect.
-
-If contracts are written so that ``assert`` is only used to test internal conditions and ``require``
-is used in case of malformed input, a formal analysis tool that verifies that the invalid
-opcode can never be reached can be used to check for the absence of errors assuming valid inputs.
+(or at least call) without effect. Note that ``assert``-style exceptions consume all gas available to the call, while
+``revert``-style exceptions will not consume any gas starting from the Metropolis release. \ No newline at end of file
diff --git a/docs/grammar.txt b/docs/grammar.txt
index dc188572..6c041460 100644
--- a/docs/grammar.txt
+++ b/docs/grammar.txt
@@ -7,7 +7,7 @@ ImportDirective = 'import' StringLiteral ('as' Identifier)? ';'
| 'import' ('*' | Identifier) ('as' Identifier)? 'from' StringLiteral ';'
| 'import' '{' Identifier ('as' Identifier)? ( ',' Identifier ('as' Identifier)? )* '}' 'from' StringLiteral ';'
-ContractDefinition = ( 'contract' | 'library' ) Identifier
+ContractDefinition = ( 'contract' | 'library' | 'interface' ) Identifier
( 'is' InheritanceSpecifier (',' InheritanceSpecifier )* )?
'{' ContractPart* '}'
@@ -20,9 +20,12 @@ StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' )? Ident
UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';'
StructDefinition = 'struct' Identifier '{'
( VariableDeclaration ';' (VariableDeclaration ';')* )? '}'
+
ModifierDefinition = 'modifier' Identifier ParameterList? Block
+ModifierInvocation = Identifier ( '(' ExpressionList? ')' )?
+
FunctionDefinition = 'function' Identifier? ParameterList
- ( FunctionCall | Identifier | 'constant' | 'payable' | 'external' | 'public' | 'internal' | 'private' )*
+ ( ModifierInvocation | 'constant' | 'payable' | 'external' | 'public' | 'internal' | 'private' )*
( 'returns' ParameterList )? ( ';' | Block )
EventDefinition = 'event' Identifier IndexedParameterList 'anonymous'? ';'
@@ -62,7 +65,7 @@ WhileStatement = 'while' '(' Expression ')' Statement
PlaceholderStatement = '_'
SimpleStatement = VariableDefinition | ExpressionStatement
ForStatement = 'for' '(' (SimpleStatement)? ';' (Expression)? ';' (ExpressionStatement)? ')' Statement
-InlineAssemblyStatement = 'assembly' InlineAssemblyBlock
+InlineAssemblyStatement = 'assembly' StringLiteral? InlineAssemblyBlock
DoWhileStatement = 'do' Statement 'while' '(' Expression ')'
Continue = 'continue'
Break = 'break'
@@ -72,8 +75,13 @@ VariableDefinition = ('var' IdentifierList | VariableDeclaration) ( '=' Expressi
IdentifierList = '(' ( Identifier? ',' )* Identifier? ')'
// Precedence by order (see github.com/ethereum/solidity/pull/732)
-Expression =
- ( Expression ('++' | '--') | FunctionCall | IndexAccess | MemberAccess | '(' Expression ')' )
+Expression
+ = Expression ('++' | '--')
+ | NewExpression
+ | IndexAccess
+ | MemberAccess
+ | FunctionCall
+ | '(' Expression ')'
| ('!' | '~' | 'delete' | '++' | '--' | '+' | '-') Expression
| Expression '**' Expression
| Expression ('*' | '/' | '%') Expression
@@ -88,20 +96,20 @@ Expression =
| Expression '||' Expression
| Expression '?' Expression ':' Expression
| Expression ('=' | '|=' | '^=' | '&=' | '<<=' | '>>=' | '+=' | '-=' | '*=' | '/=' | '%=') Expression
- | Expression? (',' Expression)
| PrimaryExpression
-PrimaryExpression = Identifier
- | BooleanLiteral
+PrimaryExpression = BooleanLiteral
| NumberLiteral
| HexLiteral
| StringLiteral
+ | TupleExpression
+ | Identifier
| ElementaryTypeNameExpression
ExpressionList = Expression ( ',' Expression )*
NameValueList = Identifier ':' Expression ( ',' Identifier ':' Expression )*
-FunctionCall = ( PrimaryExpression | NewExpression | TypeName ) ( ( '.' Identifier ) | ( '[' Expression ']' ) )* '(' FunctionCallArguments ')'
+FunctionCall = Expression '(' FunctionCallArguments ')'
FunctionCallArguments = '{' NameValueList? '}'
| ExpressionList?
@@ -120,6 +128,9 @@ Identifier = [a-zA-Z_$] [a-zA-Z_$0-9]*
HexNumber = '0x' [0-9a-fA-F]+
DecimalNumber = [0-9]+
+TupleExpression = '(' ( Expression ( ',' Expression )* )? ')'
+ | '[' ( Expression ( ',' Expression )* )? ']'
+
ElementaryTypeNameExpression = ElementaryTypeName
ElementaryTypeName = 'address' | 'bool' | 'string' | 'var'
@@ -137,7 +148,8 @@ Ufixed = 'ufixed' | 'ufixed0x8' | 'ufixed0x16' | 'ufixed0x24' | 'ufixed0x32' | '
InlineAssemblyBlock = '{' AssemblyItem* '}'
-AssemblyItem = Identifier | FunctionalAssemblyExpression | InlineAssemblyBlock | AssemblyLocalBinding | AssemblyAssignment | NumberLiteral | StringLiteral | HexLiteral
+AssemblyItem = Identifier | FunctionalAssemblyExpression | InlineAssemblyBlock | AssemblyLocalBinding | AssemblyAssignment | AssemblyLabel | NumberLiteral | StringLiteral | HexLiteral
AssemblyLocalBinding = 'let' Identifier ':=' FunctionalAssemblyExpression
-AssemblyAssignment = Identifier ':=' FunctionalAssemblyExpression | '=:' Identifier
+AssemblyAssignment = ( Identifier ':=' FunctionalAssemblyExpression ) | ( '=:' Identifier )
+AssemblyLabel = Identifier ':'
FunctionalAssemblyExpression = Identifier '(' AssemblyItem? ( ',' AssemblyItem )* ')'
diff --git a/docs/index.rst b/docs/index.rst
index 1312864a..3cdda62d 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,6 +1,11 @@
Solidity
========
+.. image:: logo.svg
+ :width: 120px
+ :alt: Solidity logo
+ :align: center
+
Solidity is a contract-oriented, high-level language whose syntax is similar to that of JavaScript
and it is designed to target the Ethereum Virtual Machine (EVM).
@@ -54,6 +59,9 @@ Available Solidity Integrations
* `Atom Solidity Linter <https://atom.io/packages/linter-solidity>`_
Plugin for the Atom editor that provides Solidity linting.
+* `Atom Solium Linter <https://atom.io/packages/linter-solium>`_
+ Configurable Solidty linter for Atom using Solium as a base.
+
* `Solium <https://github.com/duaraghav8/Solium/>`_
A commandline linter for Solidity which strictly follows the rules prescribed by the `Solidity Style Guide <http://solidity.readthedocs.io/en/latest/style-guide.html>`_.
@@ -137,6 +145,7 @@ Contents
solidity-in-depth.rst
security-considerations.rst
using-the-compiler.rst
+ abi-spec.rst
style-guide.rst
common-patterns.rst
bugs.rst
diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst
index a2a3c3da..9b5ba9f2 100644
--- a/docs/installing-solidity.rst
+++ b/docs/installing-solidity.rst
@@ -119,6 +119,12 @@ Install it using ``brew``:
# Install 0.4.8
brew install https://raw.githubusercontent.com/ethereum/homebrew-ethereum/77cce03da9f289e5a3ffe579840d3c5dc0a62717/solidity.rb
+Gentoo Linux also provides a solidity package that can be installed using ``emerge``:
+
+.. code:: bash
+
+ demerge ev-lang/solidity
+
.. _building-from-source:
Building from Source
@@ -261,7 +267,7 @@ If there are local modifications, the commit will be postfixed with ``.mod``.
These parts are combined as required by Semver, where the Solidity pre-release tag equals to the Semver pre-release
and the Solidity commit and platform combined make up the Semver build metadata.
-A relase example: ``0.4.8+commit.60cc1668.Emscripten.clang``.
+A release example: ``0.4.8+commit.60cc1668.Emscripten.clang``.
A pre-release example: ``0.4.9-nightly.2017.1.17+commit.6ecb4aa3.Emscripten.clang``
diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst
index 9001a08c..dc7c6cc9 100644
--- a/docs/introduction-to-smart-contracts.rst
+++ b/docs/introduction-to-smart-contracts.rst
@@ -33,9 +33,11 @@ Storage
The first line simply tells that the source code is written for
Solidity version 0.4.0 or anything newer that does not break functionality
(up to, but not including, version 0.5.0). This is to ensure that the
-contract does not suddenly behave differently with a new compiler version.
+contract does not suddenly behave differently with a new compiler version. The keyword ``pragma`` is called that way because, in general,
+pragmas are instructions for the compiler about how to treat the
+source code (e.g. `pragma once <https://en.wikipedia.org/wiki/Pragma_once>`_). .
-A contract in the sense of Solidity is a collection of code (its functions) and
+A contract in the sense of Solidity is a collection of code (its *functions*) and
data (its *state*) that resides at a specific address on the Ethereum
blockchain. The line ``uint storedData;`` declares a state variable called ``storedData`` of
type ``uint`` (unsigned integer of 256 bits). You can think of it as a single slot
@@ -47,9 +49,9 @@ or retrieve the value of the variable.
To access a state variable, you do not need the prefix ``this.`` as is common in
other languages.
-This contract does not yet do much apart from (due to the infrastructure
-built by Ethereum) allowing anyone to store a single number that is accessible by
-anyone in the world without (feasible) a way to prevent you from publishing
+This contract does not do much yet (due to the infrastructure
+built by Ethereum) apart from allowing anyone to store a single number that is accessible by
+anyone in the world without a (feasible) way to prevent you from publishing
this number. Of course, anyone could just call ``set`` again with a different value
and overwrite your number, but the number will still be stored in the history
of the blockchain. Later, we will see how you can impose access restrictions
@@ -124,7 +126,7 @@ get the idea - the compiler figures that out for you.
The next line, ``mapping (address => uint) public balances;`` also
creates a public state variable, but it is a more complex datatype.
The type maps addresses to unsigned integers.
-Mappings can be seen as hashtables which are
+Mappings can be seen as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_ which are
virtually initialized such that every possible key exists and is mapped to a
value whose byte-representation is all zeros. This analogy does not go
too far, though, as it is neither possible to obtain a list of all keys of
@@ -193,7 +195,7 @@ Blockchain Basics
*****************
Blockchains as a concept are not too hard to understand for programmers. The reason is that
-most of the complications (mining, hashing, elliptic-curve cryptography, peer-to-peer networks, ...)
+most of the complications (mining, `hashing <https://en.wikipedia.org/wiki/Cryptographic_hash_function>`_, `elliptic-curve cryptography <https://en.wikipedia.org/wiki/Elliptic_curve_cryptography>`_, `peer-to-peer networks <https://en.wikipedia.org/wiki/Peer-to-peer>`_, etc.)
are just there to provide a certain set of features and promises. Once you accept these
features as given, you do not have to worry about the underlying technology - or do you have
to know how Amazon's AWS works internally in order to use it?
@@ -402,7 +404,7 @@ such situations, so that exceptions "bubble up" the call stack.
As already said, the called contract (which can be the same as the caller)
will receive a freshly cleared instance of memory and has access to the
call payload - which will be provided in a separate area called the **calldata**.
-After it finished execution, it can return data which will be stored at
+After it has finished execution, it can return data which will be stored at
a location in the caller's memory preallocated by the caller.
Calls are **limited** to a depth of 1024, which means that for more complex
@@ -423,8 +425,8 @@ address at runtime. Storage, current address and balance still
refer to the calling contract, only the code is taken from the called address.
This makes it possible to implement the "library" feature in Solidity:
-Reusable library code that can be applied to a contract's storage in
-order to e.g. implement a complex data structure.
+Reusable library code that can be applied to a contract's storage, e.g. in
+order to implement a complex data structure.
.. index:: log
@@ -436,7 +438,7 @@ that maps all the way up to the block level. This feature called **logs**
is used by Solidity in order to implement **events**.
Contracts cannot access log data after it has been created, but they
can be efficiently accessed from outside the blockchain.
-Since some part of the log data is stored in bloom filters, it is
+Since some part of the log data is stored in `bloom filters <https://en.wikipedia.org/wiki/Bloom_filter>`_, it is
possible to search for this data in an efficient and cryptographically
secure way, so network peers that do not download the whole blockchain
("light clients") can still find these logs.
diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst
index 715b29ae..e4b403f6 100644
--- a/docs/layout-of-source-files.rst
+++ b/docs/layout-of-source-files.rst
@@ -33,7 +33,7 @@ be sure that our code will compile the way we intended it to. We do not fix
the exact version of the compiler, so that bugfix releases are still possible.
It is possible to specify much more complex rules for the compiler version,
-the expression follows those used by npm.
+the expression follows those used by `npm <https://docs.npmjs.com/misc/semver>`_.
.. index:: source file, ! import
@@ -185,7 +185,7 @@ Additionally, there is another type of comment called a natspec comment,
for which the documentation is not yet written. They are written with a
triple slash (``///``) or a double asterisk block(``/** ... */``) and
they should be used directly above function declarations or statements.
-You can use Doxygen-style tags inside these comments to document
+You can use `Doxygen <https://en.wikipedia.org/wiki/Doxygen>`_-style tags inside these comments to document
functions, annotate conditions for formal verification, and provide a
**confirmation text** which is shown to users when they attempt to invoke a
function.
diff --git a/docs/logo.svg b/docs/logo.svg
new file mode 100644
index 00000000..86b9f499
--- /dev/null
+++ b/docs/logo.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1300px" height="1300px"
+ viewBox="0 0 1300 1300" enable-background="new 0 0 1300 1300" xml:space="preserve">
+<title>Vector 1</title>
+<desc>Created with Sketch.</desc>
+<g id="Page-1" sketch:type="MSPage">
+ <g id="solidity" transform="translate(402.000000, 118.000000)" sketch:type="MSLayerGroup">
+ <g id="Group" sketch:type="MSShapeGroup">
+ <path id="Shape" opacity="0.45" enable-background="new " d="M371.772,135.308L241.068,367.61H-20.158l130.614-232.302
+ H371.772"/>
+ <path id="Shape_1_" opacity="0.6" enable-background="new " d="M241.068,367.61h261.318L371.772,135.308H110.456
+ L241.068,367.61z"/>
+ <path id="Shape_2_" opacity="0.8" enable-background="new " d="M110.456,599.822L241.068,367.61L110.456,135.308
+ L-20.158,367.61L110.456,599.822z"/>
+ <path id="Shape_3_" opacity="0.45" enable-background="new " d="M111.721,948.275l130.704-232.303h261.318L373.038,948.275
+ H111.721"/>
+ <path id="Shape_4_" opacity="0.6" enable-background="new " d="M242.424,715.973H-18.893l130.613,232.303h261.317
+ L242.424,715.973z"/>
+ <path id="Shape_5_" opacity="0.8" enable-background="new " d="M373.038,483.761L242.424,715.973l130.614,232.303
+ l130.704-232.303L373.038,483.761z"/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index 914dfacd..182de33a 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -371,7 +371,7 @@ Tips and Tricks
* Use ``delete`` on arrays to delete all its elements.
* Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple SSTORE operations might be combined into a single (SSTORE costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check!
-* Make your state variables public - the compiler will create :ref:`getters <visibility-and-getters>` for you for free.
+* Make your state variables public - the compiler will create :ref:`getters <visibility-and-getters>` for you automatically.
* If you end up checking conditions on input or state a lot at the beginning of your functions, try using :ref:`modifiers`.
* If your contract has a function called ``send`` but you want to use the built-in send-function, use ``address(contractVariable).send(amount)``.
* Initialise storage structs with a single assignment: ``x = MyStruct({a: 1, b: 2});``
@@ -394,12 +394,14 @@ The following is the order of precedence for operators, listed in order of evalu
+============+=====================================+============================================+
| *1* | Postfix increment and decrement | ``++``, ``--`` |
+ +-------------------------------------+--------------------------------------------+
-| | Function-like call | ``<func>(<args...>)`` |
+| | New expression | ``new <typename>`` |
+ +-------------------------------------+--------------------------------------------+
| | Array subscripting | ``<array>[<index>]`` |
+ +-------------------------------------+--------------------------------------------+
| | Member access | ``<object>.<member>`` |
+ +-------------------------------------+--------------------------------------------+
+| | Function-like call | ``<func>(<args...>)`` |
++ +-------------------------------------+--------------------------------------------+
| | Parentheses | ``(<statement>)`` |
+------------+-------------------------------------+--------------------------------------------+
| *2* | Prefix increment and decrement | ``++``, ``--`` |
@@ -462,7 +464,7 @@ Global Variables
- ``tx.gasprice`` (``uint``): gas price of the transaction
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error)
-- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for malformed input)
+- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component)
- ``revert()``: abort execution and revert state changes
- ``keccak256(...) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the (tightly packed) arguments
- ``sha3(...) returns (bytes32)``: an alias to `keccak256()`
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index 4ed474df..450b0286 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -94,7 +94,7 @@ of votes.
// called incorrectly. But watch out, this
// will currently also consume all provided gas
// (this is planned to change in the future).
- require((msg.sender == chairperson) && !voters[voter].voted);
+ require((msg.sender == chairperson) && !voters[voter].voted && (voters[voter].weight == 0));
voters[voter].weight = 1;
}
@@ -165,7 +165,7 @@ of votes.
}
}
}
-
+
// Calls winningProposal() function to get the index
// of the winner contained in the proposals array and then
// returns the name of the winner
@@ -273,7 +273,7 @@ activate themselves.
// If the bid is not higher, send the
// money back.
require(msg.value > highestBid);
-
+
if (highestBidder != 0) {
// Sending back the money by simply using
// highestBidder.send(highestBid) is a security risk
@@ -296,7 +296,7 @@ activate themselves.
// before `send` returns.
pendingReturns[msg.sender] = 0;
- if (!msg.sender.send(amount)) {
+ if (!msg.sender.send(amount)) {
// No need to call throw here, just reset the amount owing
pendingReturns[msg.sender] = amount;
return false;
@@ -316,7 +316,7 @@ activate themselves.
// 3. interacting with other contracts
// If these phases are mixed up, the other contract could call
// back into the current contract and modify the state or cause
- // effects (ether payout) to be perfromed multiple times.
+ // effects (ether payout) to be performed multiple times.
// If functions called internally include interaction with external
// contracts, they also have to be considered interaction with
// external contracts.
@@ -566,9 +566,9 @@ Safe Remote Purchase
_;
}
- event aborted();
- event purchaseConfirmed();
- event itemReceived();
+ event Aborted();
+ event PurchaseConfirmed();
+ event ItemReceived();
/// Abort the purchase and reclaim the ether.
/// Can only be called by the seller before
@@ -577,7 +577,7 @@ Safe Remote Purchase
onlySeller
inState(State.Created)
{
- aborted();
+ Aborted();
state = State.Inactive;
seller.transfer(this.balance);
}
@@ -591,7 +591,7 @@ Safe Remote Purchase
condition(msg.value == (2 * value))
payable
{
- purchaseConfirmed();
+ PurchaseConfirmed();
buyer = msg.sender;
state = State.Locked;
}
@@ -602,7 +602,7 @@ Safe Remote Purchase
onlyBuyer
inState(State.Locked)
{
- itemReceived();
+ ItemReceived();
// It is important to change the state first because
// otherwise, the contracts called using `send` below
// can call in again here.
@@ -612,7 +612,7 @@ Safe Remote Purchase
// block the refund - the withdraw pattern should be used.
buyer.transfer(value);
- seller.transfer(this.balance));
+ seller.transfer(this.balance);
}
}
diff --git a/docs/types.rst b/docs/types.rst
index c400aecb..319701c7 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -54,13 +54,13 @@ Operators:
* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation)
* Arithmetic operators: ``+``, ``-``, unary ``-``, unary ``+``, ``*``, ``/``, ``%`` (remainder), ``**`` (exponentiation), ``<<`` (left shift), ``>>`` (right shift)
-Division always truncates (it just maps to the DIV opcode of the EVM), but it does not truncate if both
+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.
The result of a shift operation is the type of the left operand. The
-expression ``x << y`` is equivalent to ``x * 2**y`` and ``x >> y`` is
+expression ``x << y`` is equivalent to ``x * 2**y``, and ``x >> y`` is
equivalent to ``x / 2**y``. This means that shifting negative numbers
sign extends. Shifting by a negative amount throws a runtime exception.
@@ -77,7 +77,7 @@ sign extends. Shifting by a negative amount throws a runtime exception.
Address
-------
-``address``: Holds a 20 byte value (size of an Ethereum address). Address types also have members and serve as base for all contracts.
+``address``: Holds a 20 byte value (size of an Ethereum address). Address types also have members and serve as a base for all contracts.
Operators:
@@ -125,7 +125,7 @@ the function ``call`` is provided which takes an arbitrary number of arguments o
``call`` returns a boolean indicating whether the invoked function terminated (``true``) or caused an EVM exception (``false``). It is not possible to access the actual data returned (for this we would need to know the encoding and size in advance).
-In a similar way, the function ``delegatecall`` can be used: The difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of ``delegatecall`` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for delegatecall to be used. Prior to homestead, only a limited variant called ``callcode`` was available that did not provide access to the original ``msg.sender`` and ``msg.value`` values.
+In a similar way, the function ``delegatecall`` can be used: the difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of ``delegatecall`` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for delegatecall to be used. Prior to homestead, only a limited variant called ``callcode`` was available that did not provide access to the original ``msg.sender`` and ``msg.value`` values.
All three functions ``call``, ``delegatecall`` and ``callcode`` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity.
@@ -387,10 +387,10 @@ Example that shows how to use internal function types::
}
function reduce(
uint[] memory self,
- function (uint x, uint y) returns (uint) f
+ function (uint, uint) returns (uint) f
)
internal
- returns (uint r)
+ returns (uint)
{
r = self[0];
for (uint i = 1; i < self.length; i++) {
@@ -472,19 +472,19 @@ context, there is always a default, but it can be overridden by appending
either ``storage`` or ``memory`` to the type. The default for function parameters (including return parameters) is ``memory``, the default for local variables is ``storage`` and the location is forced
to ``storage`` for state variables (obviously).
-There is also a third data location, "calldata", which is a non-modifyable
+There is also a third data location, "calldata", which is a non-modifiable,
non-persistent area where function arguments are stored. Function parameters
(not return parameters) of external functions are forced to "calldata" and
-it behaves mostly like memory.
+behave mostly like memory.
Data locations are important because they change how assignments behave:
-Assignments between storage and memory and also to a state variable (even from other state variables)
+assignments between storage and memory and also to a state variable (even from other state variables)
always create an independent copy.
Assignments to local storage variables only assign a reference though, and
this reference always points to the state variable even if the latter is changed
in the meantime.
On the other hand, assignments from a memory stored reference type to another
-memory-stored reference type does not create a copy.
+memory-stored reference type do not create a copy.
::
@@ -655,7 +655,8 @@ Members
contract ArrayContract {
uint[2**20] m_aLotOfIntegers;
- // Note that the following is not a pair of arrays but an array of pairs.
+ // Note that the following is not a pair of dynamic arrays but a
+ // dynamic array of pairs (i.e. of fixed size arrays of length two).
bool[2][] m_pairsOfFlags;
// newPairs is stored in memory - the default for function arguments
@@ -795,7 +796,7 @@ Mapping types are declared as ``mapping(_KeyType => _ValueType)``.
Here ``_KeyType`` can be almost any type except for a mapping, a dynamically sized array, a contract, an enum and a struct.
``_ValueType`` can actually be any type, including mappings.
-Mappings can be seen as hashtables which are virtually initialized such that
+Mappings can be seen as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_ which are virtually initialized such that
every possible key exists and is mapped to a value whose byte-representation is
all zeros: a type's :ref:`default value <default-value>`. The similarity ends here, though: The key data is not actually stored
in a mapping, only its ``keccak256`` hash used to look up the value.
diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst
index 246cc564..7d21f065 100644
--- a/docs/units-and-global-variables.rst
+++ b/docs/units-and-global-variables.rst
@@ -55,7 +55,7 @@ Block and Transaction Properties
- ``block.difficulty`` (``uint``): current block difficulty
- ``block.gaslimit`` (``uint``): current block gaslimit
- ``block.number`` (``uint``): current block number
-- ``block.timestamp`` (``uint``): current block timestamp
+- ``block.timestamp`` (``uint``): current block timestamp as seconds since unix epoch
- ``msg.data`` (``bytes``): complete calldata
- ``msg.gas`` (``uint``): remaining gas
- ``msg.sender`` (``address``): sender of the message (current call)
@@ -79,13 +79,23 @@ Block and Transaction Properties
You can only access the hashes of the most recent 256 blocks, all other
values will be zero.
-.. index:: assert, revert, keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, send
+.. index:: assert, revert, require
+
+Error Handling
+--------------
+
+``assert(bool condition)``:
+ throws if the condition is not met - to be used for internal errors.
+``require(bool condition)``:
+ throws if the condition is not met - to be used for errors in inputs or external components.
+``revert()``:
+ abort execution and revert state changes
+
+.. index:: keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography,
Mathematical and Cryptographic Functions
----------------------------------------
-``assert(bool condition)``:
- throws if the condition is not met.
``addmod(uint x, uint y, uint k) returns (uint)``:
compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``.
``mulmod(uint x, uint y, uint k) returns (uint)``:
@@ -101,8 +111,6 @@ Mathematical and Cryptographic Functions
``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``:
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>`_)
-``revert()``:
- abort execution and revert state changes
In the above, "tightly packed" means that the arguments are concatenated without padding.
This means that the following are all identical::
@@ -122,6 +130,7 @@ This means that, for example, ``keccak256(0) == keccak256(uint8(0))`` and
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
.. _address_related:
Address Related
diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst
index 7aa997f8..7f82df70 100644
--- a/docs/using-the-compiler.rst
+++ b/docs/using-the-compiler.rst
@@ -119,7 +119,7 @@ Input Description
//
// The available output types are as follows:
// abi - ABI
- // ast - AST of all source files (not supported atm)
+ // ast - AST of all source files
// legacyAST - legacy AST of all source files
// devdoc - Developer documentation (natspec)
// userdoc - User documentation (natspec)
diff --git a/docs/utils/SolidityLexer.py b/docs/utils/SolidityLexer.py
index 1dc99159..ef55c6a2 100644
--- a/docs/utils/SolidityLexer.py
+++ b/docs/utils/SolidityLexer.py
@@ -26,7 +26,7 @@ class SolidityLexer(RegexLexer):
(r'/\*.*?\*/', Comment.Multiline)
],
'natspec': [
- (r'@author|@dev|@notice|@return|@param|@why3|@title', Keyword),
+ (r'@author|@dev|@notice|@return|@param|@title', Keyword),
(r'.[^@*\n]*?', Comment.Special)
],
'docstringsingle': [