aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/abi-spec.rst12
-rw-r--r--docs/assembly.rst367
-rw-r--r--docs/bugs_by_version.json4
-rw-r--r--docs/contracts.rst89
-rw-r--r--docs/control-structures.rst63
-rw-r--r--docs/frequently-asked-questions.rst63
-rw-r--r--docs/grammar.txt3
-rw-r--r--docs/index.rst5
-rw-r--r--docs/installing-solidity.rst10
-rw-r--r--docs/introduction-to-smart-contracts.rst16
-rw-r--r--docs/julia.rst153
-rw-r--r--docs/miscellaneous.rst19
-rw-r--r--docs/solidity-by-example.rst43
-rw-r--r--docs/structure-of-a-contract.rst4
-rw-r--r--docs/style-guide.rst169
-rw-r--r--docs/types.rst4
-rw-r--r--docs/units-and-global-variables.rst17
-rw-r--r--docs/using-the-compiler.rst4
18 files changed, 677 insertions, 368 deletions
diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst
index 8095a3b7..4a61d91f 100644
--- a/docs/abi-spec.rst
+++ b/docs/abi-spec.rst
@@ -26,6 +26,10 @@ The first four bytes of the call data for a function call specifies the function
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.
+.. note::
+ The return type of a function is not part of this signature. In :ref:`Solidity's function overloading <overload-function>` return types are not considered. The reason is to keep function call resolution context-independent.
+ The JSON description of the ABI however contains both inputs and outputs. See (the :ref:`JSON ABI <abi_json>`)
+
Argument Encoding
=================
@@ -155,15 +159,15 @@ on the type of ``X`` being
``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.
+- ``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 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.
+- ``int<M>``: ``enc(X)`` is the big-endian two's complement encoding of ``X``, padded on the higher-order (left) side with ``0xff`` for negative ``X`` and with zero bytes for positive ``X`` such that the length is 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.
+- ``bytes<M>``: ``enc(X)`` is the sequence of bytes in ``X`` padded with trailing zero-bytes to a length of 32 bytes.
Note that for any ``X``, ``len(enc(X))`` is a multiple of 32.
@@ -290,6 +294,8 @@ In effect, a log entry using this ABI is described as:
For all fixed-length Solidity types, the ``EVENT_INDEXED_ARGS`` array contains the 32-byte encoded value directly. However, for *types of dynamic length*, which include ``string``, ``bytes``, and arrays, ``EVENT_INDEXED_ARGS`` will contain the *Keccak hash* of the encoded value, rather than the encoded value directly. This allows applications to efficiently query for values of dynamic-length types (by setting the hash of the encoded value as the topic), but leaves applications unable to decode indexed values they have not queried for. For dynamic-length types, application developers face a trade-off between fast search for predetermined values (if the argument is indexed) and legibility of arbitrary values (which requires that the arguments not be indexed). Developers may overcome this tradeoff and achieve both efficient search and arbitrary legibility by defining events with two arguments — one indexed, one not — intended to hold the same value.
+.. _abi_json:
+
JSON
====
diff --git a/docs/assembly.rst b/docs/assembly.rst
index afc44d66..cf9bf840 100644
--- a/docs/assembly.rst
+++ b/docs/assembly.rst
@@ -153,6 +153,8 @@ If an opcode takes arguments (always from the top of the stack), they are given
Note that the order of arguments can be seen to be reversed in non-functional style (explained below).
Opcodes marked with ``-`` do not push an item onto the stack, those marked with ``*`` are
special and all others push exactly one item onto the stack.
+Opcodes marked with ``F``, ``H``, ``B`` or ``C`` are present since Frontier, Homestead, Byzantium or Constantinople, respectively.
+Constantinople is still in planning and all instructions marked as such will result in an invalid instruction exception.
In the following, ``mem[a...b)`` signifies the bytes of memory starting at position ``a`` up to
(excluding) position ``b`` and ``storage[p]`` signifies the storage contents at position ``p``.
@@ -161,165 +163,173 @@ The opcodes ``pushi`` and ``jumpdest`` cannot be used directly.
In the grammar, opcodes are represented as pre-defined identifiers.
-+-------------------------+------+-----------------------------------------------------------------+
-| stop + `-` | stop execution, identical to return(0,0) |
-+-------------------------+------+-----------------------------------------------------------------+
-| add(x, y) | | x + y |
-+-------------------------+------+-----------------------------------------------------------------+
-| sub(x, y) | | x - y |
-+-------------------------+------+-----------------------------------------------------------------+
-| mul(x, y) | | x * y |
-+-------------------------+------+-----------------------------------------------------------------+
-| div(x, y) | | x / y |
-+-------------------------+------+-----------------------------------------------------------------+
-| sdiv(x, y) | | x / y, for signed numbers in two's complement |
-+-------------------------+------+-----------------------------------------------------------------+
-| mod(x, y) | | x % y |
-+-------------------------+------+-----------------------------------------------------------------+
-| smod(x, y) | | x % y, for signed numbers in two's complement |
-+-------------------------+------+-----------------------------------------------------------------+
-| exp(x, y) | | x to the power of y |
-+-------------------------+------+-----------------------------------------------------------------+
-| not(x) | | ~x, every bit of x is negated |
-+-------------------------+------+-----------------------------------------------------------------+
-| lt(x, y) | | 1 if x < y, 0 otherwise |
-+-------------------------+------+-----------------------------------------------------------------+
-| gt(x, y) | | 1 if x > y, 0 otherwise |
-+-------------------------+------+-----------------------------------------------------------------+
-| slt(x, y) | | 1 if x < y, 0 otherwise, for signed numbers in two's complement |
-+-------------------------+------+-----------------------------------------------------------------+
-| sgt(x, y) | | 1 if x > y, 0 otherwise, for signed numbers in two's complement |
-+-------------------------+------+-----------------------------------------------------------------+
-| eq(x, y) | | 1 if x == y, 0 otherwise |
-+-------------------------+------+-----------------------------------------------------------------+
-| iszero(x) | | 1 if x == 0, 0 otherwise |
-+-------------------------+------+-----------------------------------------------------------------+
-| and(x, y) | | bitwise and of x and y |
-+-------------------------+------+-----------------------------------------------------------------+
-| or(x, y) | | bitwise or of x and y |
-+-------------------------+------+-----------------------------------------------------------------+
-| xor(x, y) | | bitwise xor of x and y |
-+-------------------------+------+-----------------------------------------------------------------+
-| byte(n, x) | | nth byte of x, where the most significant byte is the 0th byte |
-+-------------------------+------+-----------------------------------------------------------------+
-| addmod(x, y, m) | | (x + y) % m with arbitrary precision arithmetics |
-+-------------------------+------+-----------------------------------------------------------------+
-| mulmod(x, y, m) | | (x * y) % m with arbitrary precision arithmetics |
-+-------------------------+------+-----------------------------------------------------------------+
-| 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 |
-+-------------------------+------+-----------------------------------------------------------------+
-| jumpi(label, cond) | `-` | jump to label if cond is nonzero |
-+-------------------------+------+-----------------------------------------------------------------+
-| pc | | current position in code |
-+-------------------------+------+-----------------------------------------------------------------+
-| pop(x) | `-` | remove the element pushed by x |
-+-------------------------+------+-----------------------------------------------------------------+
-| dup1 ... dup16 | | copy ith stack slot to the top (counting from top) |
-+-------------------------+------+-----------------------------------------------------------------+
-| swap1 ... swap16 | `*` | swap topmost and ith stack slot below it |
-+-------------------------+------+-----------------------------------------------------------------+
-| mload(p) | | mem[p..(p+32)) |
-+-------------------------+------+-----------------------------------------------------------------+
-| mstore(p, v) | `-` | mem[p..(p+32)) := v |
-+-------------------------+------+-----------------------------------------------------------------+
-| mstore8(p, v) | `-` | mem[p] := v & 0xff - only modifies a single byte |
-+-------------------------+------+-----------------------------------------------------------------+
-| sload(p) | | storage[p] |
-+-------------------------+------+-----------------------------------------------------------------+
-| sstore(p, v) | `-` | storage[p] := v |
-+-------------------------+------+-----------------------------------------------------------------+
-| msize | | size of memory, i.e. largest accessed memory index |
-+-------------------------+------+-----------------------------------------------------------------+
-| gas | | gas still available to execution |
-+-------------------------+------+-----------------------------------------------------------------+
-| address | | address of the current contract / execution context |
-+-------------------------+------+-----------------------------------------------------------------+
-| balance(a) | | wei balance at address a |
-+-------------------------+------+-----------------------------------------------------------------+
-| caller | | call sender (excluding delegatecall) |
-+-------------------------+------+-----------------------------------------------------------------+
-| callvalue | | wei sent together with the current call |
-+-------------------------+------+-----------------------------------------------------------------+
-| calldataload(p) | | call data starting from position p (32 bytes) |
-+-------------------------+------+-----------------------------------------------------------------+
-| calldatasize | | size of call data in bytes |
-+-------------------------+------+-----------------------------------------------------------------+
-| calldatacopy(t, f, s) | `-` | copy s bytes from calldata at position f to mem at position t |
-+-------------------------+------+-----------------------------------------------------------------+
-| codesize | | size of the code of the current contract / execution context |
-+-------------------------+------+-----------------------------------------------------------------+
-| codecopy(t, f, s) | `-` | copy s bytes from code at position f to mem at position t |
-+-------------------------+------+-----------------------------------------------------------------+
-| extcodesize(a) | | size of the code at address a |
-+-------------------------+------+-----------------------------------------------------------------+
-| 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) |
-| | | and 1 on success |
-+-------------------------+------+-----------------------------------------------------------------+
-| callcode(g, a, v, in, | | identical to `call` but only use the code from a and stay |
-| insize, out, outsize) | | in the context of the current contract otherwise |
-+-------------------------+------+-----------------------------------------------------------------+
-| 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)) |
-+-------------------------+------+-----------------------------------------------------------------+
-| selfdestruct(a) | `-` | end execution, destroy current contract and send funds to a |
-+-------------------------+------+-----------------------------------------------------------------+
-| invalid | `-` | end execution with invalid instruction |
-+-------------------------+------+-----------------------------------------------------------------+
-| log0(p, s) | `-` | log without topics and data mem[p..(p+s)) |
-+-------------------------+------+-----------------------------------------------------------------+
-| log1(p, s, t1) | `-` | log with topic t1 and data mem[p..(p+s)) |
-+-------------------------+------+-----------------------------------------------------------------+
-| log2(p, s, t1, t2) | `-` | log with topics t1, t2 and data mem[p..(p+s)) |
-+-------------------------+------+-----------------------------------------------------------------+
-| log3(p, s, t1, t2, t3) | `-` | log with topics t1, t2, t3 and data mem[p..(p+s)) |
-+-------------------------+------+-----------------------------------------------------------------+
-| log4(p, s, t1, t2, t3, | `-` | log with topics t1, t2, t3, t4 and data mem[p..(p+s)) |
-| t4) | | |
-+-------------------------+------+-----------------------------------------------------------------+
-| origin | | transaction sender |
-+-------------------------+------+-----------------------------------------------------------------+
-| gasprice | | gas price of the transaction |
-+-------------------------+------+-----------------------------------------------------------------+
-| blockhash(b) | | hash of block nr b - only for last 256 blocks excluding current |
-+-------------------------+------+-----------------------------------------------------------------+
-| coinbase | | current mining beneficiary |
-+-------------------------+------+-----------------------------------------------------------------+
-| timestamp | | timestamp of the current block in seconds since the epoch |
-+-------------------------+------+-----------------------------------------------------------------+
-| number | | current block number |
-+-------------------------+------+-----------------------------------------------------------------+
-| difficulty | | difficulty of the current block |
-+-------------------------+------+-----------------------------------------------------------------+
-| gaslimit | | block gas limit of the current block |
-+-------------------------+------+-----------------------------------------------------------------+
++-------------------------+-----+---+-----------------------------------------------------------------+
+| Instruction | | | Explanation |
++=========================+=====+===+=================================================================+
+| stop + `-` | F | stop execution, identical to return(0,0) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| add(x, y) | | F | x + y |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| sub(x, y) | | F | x - y |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| mul(x, y) | | F | x * y |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| div(x, y) | | F | x / y |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| sdiv(x, y) | | F | x / y, for signed numbers in two's complement |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| mod(x, y) | | F | x % y |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| smod(x, y) | | F | x % y, for signed numbers in two's complement |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| exp(x, y) | | F | x to the power of y |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| not(x) | | F | ~x, every bit of x is negated |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| lt(x, y) | | F | 1 if x < y, 0 otherwise |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| gt(x, y) | | F | 1 if x > y, 0 otherwise |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| slt(x, y) | | F | 1 if x < y, 0 otherwise, for signed numbers in two's complement |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| sgt(x, y) | | F | 1 if x > y, 0 otherwise, for signed numbers in two's complement |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| eq(x, y) | | F | 1 if x == y, 0 otherwise |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| iszero(x) | | F | 1 if x == 0, 0 otherwise |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| and(x, y) | | F | bitwise and of x and y |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| or(x, y) | | F | bitwise or of x and y |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| xor(x, y) | | F | bitwise xor of x and y |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| byte(n, x) | | F | nth byte of x, where the most significant byte is the 0th byte |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| shl(x, y) | | C | logical shift left y by x bits |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| shr(x, y) | | C | logical shift right y by x bits |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| sar(x, y) | | C | arithmetic shift right y by x bits |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetics |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| mulmod(x, y, m) | | F | (x * y) % m with arbitrary precision arithmetics |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| signextend(i, x) | | F | sign extend from (i*8+7)th bit counting from least significant |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| keccak256(p, n) | | F | keccak(mem[p...(p+n))) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| sha3(p, n) | | F | keccak(mem[p...(p+n))) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| jump(label) | `-` | F | jump to label / code position |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| jumpi(label, cond) | `-` | F | jump to label if cond is nonzero |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| pc | | F | current position in code |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| pop(x) | `-` | F | remove the element pushed by x |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| dup1 ... dup16 | | F | copy ith stack slot to the top (counting from top) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| swap1 ... swap16 | `*` | F | swap topmost and ith stack slot below it |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| mload(p) | | F | mem[p..(p+32)) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| mstore(p, v) | `-` | F | mem[p..(p+32)) := v |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| mstore8(p, v) | `-` | F | mem[p] := v & 0xff (only modifies a single byte) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| sload(p) | | F | storage[p] |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| sstore(p, v) | `-` | F | storage[p] := v |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| msize | | F | size of memory, i.e. largest accessed memory index |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| gas | | F | gas still available to execution |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| address | | F | address of the current contract / execution context |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| balance(a) | | F | wei balance at address a |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| caller | | F | call sender (excluding ``delegatecall``) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| callvalue | | F | wei sent together with the current call |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| calldataload(p) | | F | call data starting from position p (32 bytes) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| calldatasize | | F | size of call data in bytes |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| calldatacopy(t, f, s) | `-` | F | copy s bytes from calldata at position f to mem at position t |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| codesize | | F | size of the code of the current contract / execution context |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| codecopy(t, f, s) | `-` | F | copy s bytes from code at position f to mem at position t |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| extcodesize(a) | | F | size of the code at address a |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| extcodecopy(a, t, f, s) | `-` | F | like codecopy(t, f, s) but take code at address a |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| returndatasize | | B | size of the last returndata |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| returndatacopy(t, f, s) | `-` | B | copy s bytes from returndata at position f to mem at position t |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| create(v, p, s) | | F | create new contract with code mem[p..(p+s)) and send v wei |
+| | | | and return the new address |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| create2(v, n, p, s) | | C | 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, | | F | 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) |
+| | | | and 1 on success |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| callcode(g, a, v, in, | | F | identical to ``call`` but only use the code from a and stay |
+| insize, out, outsize) | | | in the context of the current contract otherwise |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| delegatecall(g, a, in, | | H | identical to ``callcode`` but also keep ``caller`` |
+| insize, out, outsize) | | | and ``callvalue`` |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| staticcall(g, a, in, | | B | identical to ``call(g, a, 0, in, insize, out, outsize)`` but do |
+| insize, out, outsize) | | | not allow state modifications |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| return(p, s) | `-` | F | end execution, return data mem[p..(p+s)) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| revert(p, s) | `-` | B | end execution, revert state changes, return data mem[p..(p+s)) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| selfdestruct(a) | `-` | F | end execution, destroy current contract and send funds to a |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| invalid | `-` | F | end execution with invalid instruction |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| log0(p, s) | `-` | F | log without topics and data mem[p..(p+s)) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| log1(p, s, t1) | `-` | F | log with topic t1 and data mem[p..(p+s)) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| log2(p, s, t1, t2) | `-` | F | log with topics t1, t2 and data mem[p..(p+s)) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| log3(p, s, t1, t2, t3) | `-` | F | log with topics t1, t2, t3 and data mem[p..(p+s)) |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| log4(p, s, t1, t2, t3, | `-` | F | log with topics t1, t2, t3, t4 and data mem[p..(p+s)) |
+| t4) | | | |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| origin | | F | transaction sender |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| gasprice | | F | gas price of the transaction |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| blockhash(b) | | F | hash of block nr b - only for last 256 blocks excluding current |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| coinbase | | F | current mining beneficiary |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| timestamp | | F | timestamp of the current block in seconds since the epoch |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| number | | F | current block number |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| difficulty | | F | difficulty of the current block |
++-------------------------+-----+---+-----------------------------------------------------------------+
+| gaslimit | | F | block gas limit of the current block |
++-------------------------+-----+---+-----------------------------------------------------------------+
Literals
--------
@@ -376,8 +386,8 @@ Functions external to inline assembly can also be accessed: The assembly will
push their entry label (with virtual function resolution applied). The calling semantics
in solidity are:
- - the caller pushes return label, arg1, arg2, ..., argn
- - the call returns with ret1, ret2, ..., retm
+ - the caller pushes ``return label``, ``arg1``, ``arg2``, ..., ``argn``
+ - the call returns with ``ret1``, ``ret2``, ..., ``retm``
This feature is still a bit cumbersome to use, because the stack offset essentially
changes during the call, and thus references to local variables will be wrong.
@@ -727,7 +737,7 @@ The following assembly will be generated::
// function dispatcher
switch div(calldataload(0), exp(2, 226))
case 0xb3de648b {
- let (r) = f(calldataload(4))
+ let r := f(calldataload(4))
let ret := $allocate(0x20)
mstore(ret, r)
return(ret, 0x20)
@@ -861,38 +871,37 @@ Grammar::
AssemblyItem =
Identifier |
AssemblyBlock |
- FunctionalAssemblyExpression |
+ AssemblyExpression |
AssemblyLocalDefinition |
- FunctionalAssemblyAssignment |
AssemblyAssignment |
+ AssemblyStackAssignment |
LabelDefinition |
AssemblyIf |
AssemblySwitch |
AssemblyFunctionDefinition |
AssemblyFor |
- 'break' | 'continue' |
- SubAssembly | 'dataSize' '(' Identifier ')' |
- LinkerSymbol |
- 'errorLabel' | 'bytecodeSize' |
- NumberLiteral | StringLiteral | HexLiteral
+ 'break' |
+ 'continue' |
+ SubAssembly
+ AssemblyExpression = AssemblyCall | Identifier | AssemblyLiteral
+ AssemblyLiteral = NumberLiteral | StringLiteral | HexLiteral
Identifier = [a-zA-Z_$] [a-zA-Z_0-9]*
- FunctionalAssemblyExpression = Identifier '(' ( AssemblyItem ( ',' AssemblyItem )* )? ')'
- AssemblyLocalDefinition = 'let' IdentifierOrList ':=' FunctionalAssemblyExpression
- FunctionalAssemblyAssignment = IdentifierOrList ':=' FunctionalAssemblyExpression
+ AssemblyCall = Identifier '(' ( AssemblyExpression ( ',' AssemblyExpression )* )? ')'
+ AssemblyLocalDefinition = 'let' IdentifierOrList ( ':=' AssemblyExpression )?
+ AssemblyAssignment = IdentifierOrList ':=' AssemblyExpression
IdentifierOrList = Identifier | '(' IdentifierList ')'
IdentifierList = Identifier ( ',' Identifier)*
- AssemblyAssignment = '=:' Identifier
+ AssemblyStackAssignment = '=:' Identifier
LabelDefinition = Identifier ':'
- AssemblyIf = 'if' FunctionalAssemblyExpression AssemblyBlock
- AssemblySwitch = 'switch' FunctionalAssemblyExpression AssemblyCase*
+ AssemblyIf = 'if' AssemblyExpression AssemblyBlock
+ AssemblySwitch = 'switch' AssemblyExpression AssemblyCase*
( 'default' AssemblyBlock )?
- AssemblyCase = 'case' FunctionalAssemblyExpression AssemblyBlock
+ AssemblyCase = 'case' AssemblyExpression AssemblyBlock
AssemblyFunctionDefinition = 'function' Identifier '(' IdentifierList? ')'
( '->' '(' IdentifierList ')' )? AssemblyBlock
- AssemblyFor = 'for' ( AssemblyBlock | FunctionalAssemblyExpression)
- FunctionalAssemblyExpression ( AssemblyBlock | FunctionalAssemblyExpression) AssemblyBlock
+ AssemblyFor = 'for' ( AssemblyBlock | AssemblyExpression )
+ AssemblyExpression ( AssemblyBlock | AssemblyExpression ) AssemblyBlock
SubAssembly = 'assembly' Identifier AssemblyBlock
- LinkerSymbol = 'linkerSymbol' '(' StringLiteral ')'
NumberLiteral = HexNumber | DecimalNumber
HexLiteral = 'hex' ('"' ([0-9a-fA-F]{2})* '"' | '\'' ([0-9a-fA-F]{2})* '\'')
StringLiteral = '"' ([^"\r\n\\] | '\\' .)* '"'
diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json
index 5a4c9e29..4c976a32 100644
--- a/docs/bugs_by_version.json
+++ b/docs/bugs_by_version.json
@@ -418,6 +418,10 @@
"bugs": [],
"released": "2018-02-14"
},
+ "0.4.21": {
+ "bugs": [],
+ "released": "2018-03-07"
+ },
"0.4.3": {
"bugs": [
"ZeroFunctionSelector",
diff --git a/docs/contracts.rst b/docs/contracts.rst
index afc32b16..121c4de0 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -402,7 +402,7 @@ State variables can be declared as ``constant``. In this case, they have to be
assigned from an expression which is a constant at compile time. Any expression
that accesses storage, blockchain data (e.g. ``now``, ``this.balance`` or
``block.number``) or
-execution data (``msg.gas``) or make calls to external contracts are disallowed. Expressions
+execution data (``msg.value`` or ``gasleft()``) or make calls to external contracts are disallowed. Expressions
that might have a side-effect on memory allocation are allowed, but those that
might have a side-effect on other memory objects are not. The built-in functions
``keccak256``, ``sha256``, ``ripemd160``, ``ecrecover``, ``addmod`` and ``mulmod``
@@ -467,13 +467,20 @@ The following statements are considered modifying the state:
}
.. note::
- ``constant`` is an alias to ``view``.
+ ``constant`` on functions is an alias to ``view``, but this is deprecated and is planned to be dropped in version 0.5.0.
.. note::
Getter methods are marked ``view``.
+.. note::
+ If invalid explicit type conversions are used, state modifications are possible
+ even though a ``view`` function was called.
+ You can switch the compiler to use ``STATICCALL`` when calling such functions and thus
+ prevent modifications to the state on the level of the EVM by adding
+ ``pragma experimental "v0.5.0";``
+
.. warning::
- The compiler does not enforce yet that a ``view`` method is not modifying state.
+ The compiler does not enforce yet that a ``view`` method is not modifying state. It raises a warning though.
.. index:: ! pure function, function;pure
@@ -502,8 +509,20 @@ In addition to the list of state modifying statements explained above, the follo
}
}
+.. note::
+ If invalid explicit type conversions are used, state modifications are possible
+ even though a ``pure`` function was called.
+ You can switch the compiler to use ``STATICCALL`` when calling such functions and thus
+ prevent modifications to the state on the level of the EVM by adding
+ ``pragma experimental "v0.5.0";``
+
.. warning::
- The compiler does not enforce yet that a ``pure`` method is not reading from the state.
+ It is not possible to prevent functions from reading the state at the level
+ of the EVM, it is only possible to prevent them from writing to the state
+ (i.e. only ``view`` can be enforced at the EVM level, ``pure`` can not).
+
+.. warning::
+ Before version 0.4.17 the compiler didn't enforce that ``pure`` is not reading the state.
.. index:: ! fallback function, function;fallback
@@ -523,16 +542,14 @@ Ether (without data). Additionally, in order to receive Ether, the fallback func
must be marked ``payable``. If no such function exists, the contract cannot receive
Ether through regular transactions.
-In such a context, there is usually very little gas available to the function call (to be precise, 2300 gas), so it is important to make fallback functions as cheap as possible. Note that the gas required by a transaction (as opposed to an internal call) that invokes the fallback function is much higher, because each transaction charges an additional amount of 21000 gas or more for things like signature checking.
-
-In particular, the following operations will consume more gas than the stipend provided to a fallback function:
+In the worst case, the fallback function can only rely on 2300 gas being available (for example when send or transfer is used), leaving not much room to perform other operations except basic logging. The following operations will consume more gas than the 2300 gas stipend:
- Writing to storage
- Creating a contract
- Calling an external function which consumes a large amount of gas
- Sending Ether
-Please ensure you test your fallback function thoroughly to ensure the execution cost is less than 2300 gas before deploying a contract.
+Like any function, the fallback function can execute complex operations as long as there is enough gas passed on to it.
.. note::
Even though the fallback function cannot have arguments, one can still use ``msg.data`` to retrieve
@@ -724,10 +741,12 @@ All non-indexed arguments will be stored in the data part of the log.
);
function deposit(bytes32 _id) public payable {
- // Any call to this function (even deeply nested) can
- // be detected from the JavaScript API by filtering
- // for `Deposit` to be called.
- Deposit(msg.sender, _id, msg.value);
+ // Events are emitted using `emit`, followed by
+ // the name of the event and the arguments
+ // (if any) in parentheses. Any such invocation
+ // (even deeply nested) can be detected from
+ // the JavaScript API by filtering for `Deposit`.
+ emit Deposit(msg.sender, _id, msg.value);
}
}
@@ -953,6 +972,31 @@ not known in the context of the class where it is used,
although its type is known. This is similar for ordinary
virtual method lookup.
+.. index:: ! constructor
+
+Constructors
+============
+A constructor is an optional function with the same name as the contract which is executed upon contract creation.
+Constructor functions can be either ``public`` or ``internal``.
+
+::
+
+ pragma solidity ^0.4.11;
+
+ contract A {
+ uint public a;
+
+ function A(uint _a) internal {
+ a = _a;
+ }
+ }
+
+ contract B is A(1) {
+ function B() public {}
+ }
+
+A constructor set as ``internal`` causes the contract to be marked as :ref:`abstract <abstract-contract>`.
+
.. index:: ! base;constructor
Arguments for Base Constructors
@@ -1025,11 +1069,13 @@ As an exception, a state variable getter can override a public function.
.. index:: ! contract;abstract, ! abstract contract
+.. _abstract-contract:
+
******************
Abstract Contracts
******************
-Contract functions can lack an implementation as in the following example (note that the function declaration header is terminated by ``;``)::
+Contracts are marked as abstract when at least one of their functions lacks an implementation as in the following example (note that the function declaration header is terminated by ``;``)::
pragma solidity ^0.4.0;
@@ -1037,9 +1083,7 @@ Contract functions can lack an implementation as in the following example (note
function utterance() public returns (bytes32);
}
-Such contracts cannot be compiled (even if they contain
-implemented functions alongside non-implemented functions),
-but they can be used as base contracts::
+Such contracts cannot be compiled (even if they contain implemented functions alongside non-implemented functions), but they can be used as base contracts::
pragma solidity ^0.4.0;
@@ -1053,6 +1097,19 @@ but they can be used as base contracts::
If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it will itself be abstract.
+Note that a function without implementation is different from a :ref:`Function Type <function_types>` even though their syntax looks very similar.
+
+Example of function without implementation (a function declaration)::
+
+ function foo(address) external returns (address);
+
+Example of a Function Type (a variable declaration, where the variable is of type ``function``)::
+
+ function(address) external returns (address) foo;
+
+Abstract contracts decouple the definition of a contract from its implementation providing better extensibility and self-documentation and
+facilitating patterns like the `Template method <https://en.wikipedia.org/wiki/Template_method_pattern>`_ and removing code duplication.
+
.. index:: ! contract;interface, ! interface contract
**********
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index 1a8ee25b..46e076e5 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -324,7 +324,8 @@ is ``false``. The default value for the ``uint`` or ``int`` types is ``0``. For
element will be initialized to the default value corresponding to its type. Finally, for dynamically-sized arrays, ``bytes``
and ``string``, the default value is an empty array or string.
-A variable declared anywhere within a function will be in scope for the *entire function*, regardless of where it is declared.
+A variable declared anywhere within a function will be in scope for the *entire function*, regardless of where it is declared
+(this will change soon, see below).
This happens because Solidity inherits its scoping rules from JavaScript.
This is in contrast to many languages where variables are only scoped where they are declared until the end of the semantic block.
As a result, the following code is illegal and cause the compiler to throw an error, ``Identifier already declared``::
@@ -366,7 +367,9 @@ As a result, the following code is illegal and cause the compiler to throw an er
}
In addition to this, if a variable is declared, it will be initialized at the beginning of the function to its default value.
-As a result, the following code is legal, despite being poorly written::
+As a result, the following code is legal, despite being poorly written:
+
+::
pragma solidity ^0.4.0;
@@ -383,6 +386,60 @@ As a result, the following code is legal, despite being poorly written::
}
}
+Scoping starting from Version 0.5.0
+-----------------------------------
+
+Starting from version 0.5.0, Solidity will change to the more widespread scoping rules of C99
+(and many other languages): Variables are visible from the point right after their declaration
+until the end of a ``{ }``-block. As an exception to this rule, variables declared in the
+initialization part of a for-loop are only visible until the end of the for-loop.
+
+Variables and other items declared outside of a code block, for example functions, contracts,
+user-defined types, etc., do not change their scoping behaviour. This means you can
+use state variables before they are declared and call functions recursively.
+
+These rules are already introduced now as an experimental feature.
+
+As a consequence, the following examples will compile without warnings, since
+the two variables have the same name but disjoint scopes. In non-0.5.0-mode,
+they have the same scope (the function ``minimalScoping``) and thus it does
+not compile there.
+
+::
+
+ pragma solidity ^0.4.0;
+ pragma experimental "v0.5.0";
+ contract C {
+ function minimalScoping() pure public {
+ {
+ uint same2 = 0;
+ }
+
+ {
+ uint same2 = 0;
+ }
+ }
+ }
+
+As a special example of the C99 scoping rules, note that in the following,
+the first assignment to ``x`` will actually assign the outer and not the inner variable.
+In any case, you will get a warning about the outer variable being shadowed.
+
+::
+
+ pragma solidity ^0.4.0;
+ pragma experimental "v0.5.0";
+ contract C {
+ function f() pure public returns (uint) {
+ uint x = 1;
+ {
+ x = 2; // this will assign to the outer variable
+ uint x;
+ }
+ return x; // x has value 2
+ }
+ }
+
.. index:: ! exception, ! throw, ! assert, ! require, ! revert
Error handling: Assert, Require, Revert and Exceptions
@@ -407,7 +464,7 @@ and the low-level functions ``call``, ``delegatecall`` and ``callcode`` -- those
of an exception instead of "bubbling up".
.. warning::
- The low-level ``call``, ``delegatecall`` and ``callcode`` will return success if the calling account is non-existent, as part of the design of EVM. Existence must be checked prior to calling if desired.
+ The low-level ``call``, ``delegatecall`` and ``callcode`` will return success if the called account is non-existent, as part of the design of EVM. Existence must be checked prior to calling if desired.
Catching exceptions is not yet possible.
diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst
index a6bead29..6a2fe685 100644
--- a/docs/frequently-asked-questions.rst
+++ b/docs/frequently-asked-questions.rst
@@ -9,17 +9,6 @@ This list was originally compiled by `fivedogit <mailto:fivedogit@gmail.com>`_.
Basic Questions
***************
-Example contracts
-=================
-
-There are some `contract examples <https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts/>`_ by fivedogit and
-there should be a `test contract <https://github.com/ethereum/solidity/blob/develop/test/libsolidity/SolidityEndToEndTest.cpp>`_ for every single feature of Solidity.
-
-Create and publish the most basic contract possible
-===================================================
-
-A quite simple contract is the `greeter <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/05_greeter.sol>`_
-
Is it possible to do something on a specific block number? (e.g. publish a contract or execute a transaction)
=============================================================================================================
@@ -40,9 +29,9 @@ Is there a decompiler available?
================================
There is no exact decompiler to Solidity, but
-`Porosity <https://github.com/comaeio/porosity>`_ is close.
-Because some information like variable names, comments, and
-source code formatting is lost in the compilation process,
+`Porosity <https://github.com/comaeio/porosity>`_ is close.
+Because some information like variable names, comments, and
+source code formatting is lost in the compilation process,
it is not possible to completely recover the original source code.
Bytecode can be disassembled to opcodes, a service that is provided by
@@ -74,25 +63,6 @@ has it (which includes `Remix <https://remix.ethereum.org/>`_), then
``contractname.kill.sendTransaction({from:eth.coinbase})``, just the same as my
examples.
-Store Ether in a contract
-=========================
-
-The trick is to create the contract with ``{from:someaddress, value: web3.toWei(3,"ether")...}``
-
-See `endowment_retriever.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/30_endowment_retriever.sol>`_.
-
-Use a non-constant function (req ``sendTransaction``) to increment a variable in a contract
-===========================================================================================
-
-See `value_incrementer.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/20_value_incrementer.sol>`_.
-
-Get a contract to return its funds to you (not using ``selfdestruct(...)``).
-============================================================================
-
-This example demonstrates how to send funds from a contract to an address.
-
-See `endowment_retriever <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/30_endowment_retriever.sol>`_.
-
Can you return an array or a ``string`` from a solidity function call?
======================================================================
@@ -542,12 +512,27 @@ contract level) with ``arrayname.length = <some new length>;``. If you get the
::
- int8[] memory memArr; // Case 1
- memArr.length++; // illegal
- int8[5] storageArr; // Case 2
- somearray.length++; // legal
- int8[5] storage storageArr2; // Explicit case 2
- somearray2.length++; // legal
+ // This will not compile
+
+ pragma solidity ^0.4.18;
+
+ contract C {
+ int8[] dynamicStorageArray;
+ int8[5] fixedStorageArray;
+
+ function f() {
+ int8[] memory memArr; // Case 1
+ memArr.length++; // illegal
+
+ int8[5] storage storageArr = fixedStorageArray; // Case 2
+ storageArr.length++; // illegal
+
+ int8[] storage storageArr2 = dynamicStorageArray;
+ storageArr2.length++; // legal
+
+
+ }
+ }
**Important note:** In Solidity, array dimensions are declared backwards from the way you
might be used to declaring them in C or Java, but they are access as in
diff --git a/docs/grammar.txt b/docs/grammar.txt
index e700c946..a5c2acf3 100644
--- a/docs/grammar.txt
+++ b/docs/grammar.txt
@@ -63,7 +63,7 @@ StateMutability = 'pure' | 'constant' | 'view' | 'payable'
Block = '{' Statement* '}'
Statement = IfStatement | WhileStatement | ForStatement | Block | InlineAssemblyStatement |
( DoWhileStatement | PlaceholderStatement | Continue | Break | Return |
- Throw | SimpleStatement ) ';'
+ Throw | EmitStatement | SimpleStatement ) ';'
ExpressionStatement = Expression
IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?
@@ -77,6 +77,7 @@ Continue = 'continue'
Break = 'break'
Return = 'return' Expression?
Throw = 'throw'
+EmitStatement = 'emit' FunctionCall
VariableDefinition = ('var' IdentifierList | VariableDeclaration) ( '=' Expression )?
IdentifierList = '(' ( Identifier? ',' )* Identifier? ')'
diff --git a/docs/index.rst b/docs/index.rst
index 3df0af3c..f53b0fc4 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -19,7 +19,9 @@ crowdfunding, blind auctions, multi-signature wallets and more.
.. note::
The best way to try out Solidity right now is using
`Remix <https://remix.ethereum.org/>`_
- (it can take a while to load, please be patient).
+ (it can take a while to load, please be patient). Remix is a web browser
+ based IDE that allows you to write Solidity smart contracts, then deploy
+ and run the smart contracts.
.. warning::
Since software is written by humans, it can have bugs. Thus, also
@@ -34,6 +36,7 @@ Translations
This documentation is translated into several languages by community volunteers, but the English version stands as a reference.
+* `Simplified Chinese <http://solidity-cn.readthedocs.io>`_ (in progress)
* `Spanish <https://solidity-es.readthedocs.io>`_
* `Russian <https://github.com/ethereum/wiki/wiki/%5BRussian%5D-%D0%A0%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D0%BF%D0%BE-Solidity>`_ (rather outdated)
diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst
index 8f30f199..e26870f0 100644
--- a/docs/installing-solidity.rst
+++ b/docs/installing-solidity.rst
@@ -29,18 +29,20 @@ Further options on this page detail installing commandline Solidity compiler sof
on your computer. Choose a commandline compiler if you are working on a larger contract
or if you require more compilation options.
+.. _solcjs:
+
npm / Node.js
=============
Use `npm` for a convenient and portable way to install `solcjs`, a Solidity compiler. The
`solcjs` program has less features than all options further down this page. Our
-`Using the compiler <using-the-compiler.html>` documentation assumes you are using
+:ref:`commandline-compiler` documentation assumes you are using
the full-featured compiler, `solc`. So if you install `solcjs` from `npm` then you will
-stop reading the documentation here and then continue to <https://github.com/ethereum/solc-js>,
+stop reading the documentation here and then continue to `solc-js <https://github.com/ethereum/solc-js>`_.
-Note: The `solc-js <https://github.com/ethereum/solc-js>` project is derived from the C++
+Note: The solc-js project is derived from the C++
`solc` by using Emscripten. `solc-js` can be used in JavaScript projects directly (such as Remix).
-Please refer to the `solc-js <https://github.com/ethereum/solc-js>`_ repository for instructions.
+Please refer to the solc-js repository for instructions.
.. code:: bash
diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst
index 6425dcaa..56f0fe3e 100644
--- a/docs/introduction-to-smart-contracts.rst
+++ b/docs/introduction-to-smart-contracts.rst
@@ -80,7 +80,7 @@ registering with username and password - all you need is an Ethereum keypair.
::
- pragma solidity ^0.4.0;
+ pragma solidity ^0.4.21;
contract Coin {
// The keyword "public" makes those variables
@@ -107,7 +107,7 @@ registering with username and password - all you need is an Ethereum keypair.
if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver] += amount;
- Sent(msg.sender, receiver, amount);
+ emit Sent(msg.sender, receiver, amount);
}
}
@@ -118,9 +118,11 @@ that is publicly accessible. The ``address`` type is a 160-bit value
that does not allow any arithmetic operations. It is suitable for
storing addresses of contracts or keypairs belonging to external
persons. The keyword ``public`` automatically generates a function that
-allows you to access the current value of the state variable.
+allows you to access the current value of the state variable
+from outside of the contract.
Without this keyword, other contracts have no way to access the variable.
-The function will look something like this::
+The code of the function generated by the compiler is roughly equivalent
+to the following::
function minter() returns (address) { return minter; }
@@ -155,10 +157,10 @@ single account.
.. index:: event
The line ``event Sent(address from, address to, uint amount);`` declares
-a so-called "event" which is fired in the last line of the function
+a so-called "event" which is emitted in the last line of the function
``send``. User interfaces (as well as server applications of course) can
-listen for those events being fired on the blockchain without much
-cost. As soon as it is fired, the listener will also receive the
+listen for those events being emitted on the blockchain without much
+cost. As soon as it is emitted, the listener will also receive the
arguments ``from``, ``to`` and ``amount``, which makes it easy to track
transactions. In order to listen for this event, you would use ::
diff --git a/docs/julia.rst b/docs/julia.rst
index 9e961a9d..078bc55b 100644
--- a/docs/julia.rst
+++ b/docs/julia.rst
@@ -320,168 +320,169 @@ The following functions must be available:
+---------------------------------------------------------------------------------------------------------------+
| *Arithmetics* |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| addu256(x:u256, y:u256) -> z:u256 | x + y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| subu256(x:u256, y:u256) -> z:u256 | x - y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| mulu256(x:u256, y:u256) -> z:u256 | x * y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| divu256(x:u256, y:u256) -> z:u256 | x / y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| divs256(x:s256, y:s256) -> z:s256 | x / y, for signed numbers in two's complement |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| modu256(x:u256, y:u256) -> z:u256 | x % y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| mods256(x:s256, y:s256) -> z:s256 | x % y, for signed numbers in two's complement |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| signextendu256(i:u256, x:u256) -> z:u256 | sign extend from (i*8+7)th bit counting from least significant |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| expu256(x:u256, y:u256) -> z:u256 | x to the power of y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| addmodu256(x:u256, y:u256, m:u256) -> z:u256| (x + y) % m with arbitrary precision arithmetics |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| mulmodu256(x:u256, y:u256, m:u256) -> z:u256| (x * y) % m with arbitrary precision arithmetics |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| ltu256(x:u256, y:u256) -> z:bool | 1 if x < y, 0 otherwise |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| gtu256(x:u256, y:u256) -> z:bool | 1 if x > y, 0 otherwise |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| sltu256(x:s256, y:s256) -> z:bool | 1 if x < y, 0 otherwise, for signed numbers in two's complement |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| sgtu256(x:s256, y:s256) -> z:bool | 1 if x > y, 0 otherwise, for signed numbers in two's complement |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| equ256(x:u256, y:u256) -> z:bool | 1 if x == y, 0 otherwise |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| notu256(x:u256) -> z:u256 | ~x, every bit of x is negated |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| andu256(x:u256, y:u256) -> z:u256 | bitwise and of x and y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| oru256(x:u256, y:u256) -> z:u256 | bitwise or of x and y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| xoru256(x:u256, y:u256) -> z:u256 | bitwise xor of x and y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| shlu256(x:u256, y:u256) -> z:u256 | logical left shift of x by y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| shru256(x:u256, y:u256) -> z:u256 | logical right shift of x by y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| saru256(x:u256, y:u256) -> z:u256 | arithmetic right shift of x by y |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| byte(n:u256, x:u256) -> v:u256 | nth byte of x, where the most significant byte is the 0th byte |
-| Cannot this be just replaced by and256(shr256(n, x), 0xff) and let it be optimised out by the EVM backend? |
-+---------------------------------------------------------------------------------------------------------------+
+| | Cannot this be just replaced by and256(shr256(n, x), 0xff) and |
+| | let it be optimised out by the EVM backend? |
++---------------------------------------------+-----------------------------------------------------------------+
| *Memory and storage* |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| mload(p:u256) -> v:u256 | mem[p..(p+32)) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| mstore(p:u256, v:u256) | mem[p..(p+32)) := v |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| mstore8(p:u256, v:u256) | mem[p] := v & 0xff - only modifies a single byte |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| sload(p:u256) -> v:u256 | storage[p] |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| sstore(p:u256, v:u256) | storage[p] := v |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| msize() -> size:u256 | size of memory, i.e. largest accessed memory index, albeit due |
| | due to the memory extension function, which extends by words, |
| | this will always be a multiple of 32 bytes |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| *Execution control* |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| create(v:u256, p:u256, s:u256) | create new contract with code mem[p..(p+s)) and send v wei |
| | and return the new address |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| call(g:u256, a:u256, v:u256, in:u256, | call contract at address a with input mem[in..(in+insize)) |
| insize:u256, out:u256, | providing g gas and v wei and output area |
| outsize:u256) | mem[out..(out+outsize)) returning 0 on error (eg. out of gas) |
| -> r:u256 | and 1 on success |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| callcode(g:u256, a:u256, v:u256, in:u256, | identical to ``call`` but only use the code from a |
| insize:u256, out:u256, | and stay in the context of the |
| outsize:u256) -> r:u256 | current contract otherwise |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| delegatecall(g:u256, a:u256, in:u256, | identical to ``callcode``, |
| insize:u256, out:u256, | but also keep ``caller`` |
| outsize:u256) -> r:u256 | and ``callvalue`` |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| stop() | stop execution, identical to return(0,0) |
-| Perhaps it would make sense retiring this as it equals to return(0,0). It can be an optimisation by the EVM |
-| backend. |
-+---------------------------------------------------------------------------------------------------------------+
+| | Perhaps it would make sense retiring this as it equals to |
+| | return(0,0). It can be an optimisation by the EVM backend. |
++---------------------------------------------+-----------------------------------------------------------------+
| abort() | abort (equals to invalid instruction on EVM) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| return(p:u256, s:u256) | end execution, return data mem[p..(p+s)) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| revert(p:u256, s:u256) | end execution, revert state changes, return data mem[p..(p+s)) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| selfdestruct(a:u256) | end execution, destroy current contract and send funds to a |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| log0(p:u256, s:u256) | log without topics and data mem[p..(p+s)) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| log1(p:u256, s:u256, t1:u256) | log with topic t1 and data mem[p..(p+s)) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| log2(p:u256, s:u256, t1:u256, t2:u256) | log with topics t1, t2 and data mem[p..(p+s)) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| log3(p:u256, s:u256, t1:u256, t2:u256, | log with topics t, t2, t3 and data mem[p..(p+s)) |
| t3:u256) | |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| log4(p:u256, s:u256, t1:u256, t2:u256, | log with topics t1, t2, t3, t4 and data mem[p..(p+s)) |
| t3:u256, t4:u256) | |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| *State queries* |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| blockcoinbase() -> address:u256 | current mining beneficiary |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| blockdifficulty() -> difficulty:u256 | difficulty of the current block |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| blockgaslimit() -> limit:u256 | block gas limit of the current block |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| blockhash(b:u256) -> hash:u256 | hash of block nr b - only for last 256 blocks excluding current |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| blocknumber() -> block:u256 | current block number |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| blocktimestamp() -> timestamp:u256 | timestamp of the current block in seconds since the epoch |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| txorigin() -> address:u256 | transaction sender |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| txgasprice() -> price:u256 | gas price of the transaction |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| gasleft() -> gas:u256 | gas still available to execution |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| balance(a:u256) -> v:u256 | wei balance at address a |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| this() -> address:u256 | address of the current contract / execution context |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| caller() -> address:u256 | call sender (excluding delegatecall) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| callvalue() -> v:u256 | wei sent together with the current call |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| calldataload(p:u256) -> v:u256 | call data starting from position p (32 bytes) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| calldatasize() -> v:u256 | size of call data in bytes |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| calldatacopy(t:u256, f:u256, s:u256) | copy s bytes from calldata at position f to mem at position t |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| codesize() -> size:u256 | size of the code of the current contract / execution context |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| codecopy(t:u256, f:u256, s:u256) | copy s bytes from code at position f to mem at position t |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| extcodesize(a:u256) -> size:u256 | size of the code at address a |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| extcodecopy(a:u256, t:u256, f:u256, s:u256) | like codecopy(t, f, s) but take code at address a |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| *Others* |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| discardu256(unused:u256) | discard value |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| splitu256tou64(x:u256) -> (x1:u64, x2:u64, | split u256 to four u64's |
| x3:u64, x4:u64) | |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| combineu64tou256(x1:u64, x2:u64, x3:u64, | combine four u64's into a single u256 |
| x4:u64) -> (x:u256) | |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
| sha3(p:u256, s:u256) -> v:u256 | keccak(mem[p...(p+s))) |
-+---------------------------------------------------------------------------------------------------------------+
++---------------------------------------------+-----------------------------------------------------------------+
Backends
--------
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index 1c4f918c..075b6be0 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -192,6 +192,11 @@ These are regular array indices into a list of source files usually called
``"sourceList"``, which is part of the combined-json and the output of
the json / npm compiler.
+.. note ::
+ In the case of instructions that are not associated with any particular source file,
+ the source mapping assigns an integer identifier of ``-1``. This may happen for
+ bytecode sections stemming from compiler-generated inline assembly statements.
+
The source mappings inside the AST use the following
notation:
@@ -219,7 +224,7 @@ This means the following source mappings represent the same information:
``1:2:1;1:9:1;2:1:2;2:1:2;2:1:2``
-``1:2:1;:9;2::2;;``
+``1:2:1;:9;2:1:2;;``
***************
Tips and Tricks
@@ -230,7 +235,10 @@ Tips and Tricks
* 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});``
+* Initialize storage structs with a single assignment: ``x = MyStruct({a: 1, b: 2});``
+
+.. note::
+ If the storage struct has tightly packed properties, initialize it with separate assignments: ``x.a = 1; x.b = 2;``. In this way it will be easier for the optimizer to update storage in one go, thus making assignment cheaper.
**********
Cheatsheet
@@ -312,8 +320,9 @@ Global Variables
- ``block.gaslimit`` (``uint``): current block gaslimit
- ``block.number`` (``uint``): current block number
- ``block.timestamp`` (``uint``): current block timestamp
+- ``gasleft() returns (uint256)``: remaining gas
- ``msg.data`` (``bytes``): complete calldata
-- ``msg.gas`` (``uint``): remaining gas
+- ``msg.gas`` (``uint``): remaining gas - deprecated in version 0.4.21 and to be replaced by ``gasleft()``
- ``msg.sender`` (``address``): sender of the message (current call)
- ``msg.value`` (``uint``): number of wei sent with the message
- ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``)
@@ -327,8 +336,8 @@ Global Variables
- ``sha256(...) returns (bytes32)``: compute the SHA-256 hash of the :ref:`(tightly packed) arguments <abi_packed_mode>`
- ``ripemd160(...) returns (bytes20)``: compute the RIPEMD-160 hash of the :ref:`(tightly packed) arguments <abi_packed_mode>`
- ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: recover address associated with the public key from elliptic curve signature, return zero on error
-- ``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)``: compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``
+- ``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``. Assert that ``k != 0`` starting from version 0.5.0.
+- ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
- ``this`` (current contract's type): the current contract, explicitly convertible to ``address``
- ``super``: the contract one level higher in the inheritance hierarchy
- ``selfdestruct(address recipient)``: destroy the current contract, sending its funds to the given address
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index b663083c..27fefd49 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -94,7 +94,11 @@ 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 && (voters[voter].weight == 0));
+ require(
+ (msg.sender == chairperson) &&
+ !voters[voter].voted &&
+ (voters[voter].weight == 0)
+ );
voters[voter].weight = 1;
}
@@ -126,15 +130,15 @@ of votes.
// modifies `voters[msg.sender].voted`
sender.voted = true;
sender.delegate = to;
- Voter storage delegate = voters[to];
- if (delegate.voted) {
+ Voter storage delegate_ = voters[to];
+ if (delegate_.voted) {
// If the delegate already voted,
// directly add to the number of votes
- proposals[delegate.vote].voteCount += sender.weight;
+ proposals[delegate_.vote].voteCount += sender.weight;
} else {
// If the delegate did not vote yet,
// add to her weight.
- delegate.weight += sender.weight;
+ delegate_.weight += sender.weight;
}
}
@@ -155,13 +159,13 @@ of votes.
/// @dev Computes the winning proposal taking all
/// previous votes into account.
function winningProposal() public view
- returns (uint winningProposal)
+ returns (uint winningProposal_)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
- winningProposal = p;
+ winningProposal_ = p;
}
}
}
@@ -170,12 +174,13 @@ of votes.
// of the winner contained in the proposals array and then
// returns the name of the winner
function winnerName() public view
- returns (bytes32 winnerName)
+ returns (bytes32 winnerName_)
{
- winnerName = proposals[winningProposal()].name;
+ winnerName_ = proposals[winningProposal()].name;
}
}
+
Possible Improvements
=====================
@@ -214,7 +219,7 @@ activate themselves.
::
- pragma solidity ^0.4.11;
+ pragma solidity ^0.4.21;
contract SimpleAuction {
// Parameters of the auction. Times are either
@@ -272,7 +277,7 @@ activate themselves.
// money back.
require(msg.value > highestBid);
- if (highestBidder != 0) {
+ if (highestBid != 0) {
// Sending back the money by simply using
// highestBidder.send(highestBid) is a security risk
// because it could execute an untrusted contract.
@@ -282,7 +287,7 @@ activate themselves.
}
highestBidder = msg.sender;
highestBid = msg.value;
- HighestBidIncreased(msg.sender, msg.value);
+ emit HighestBidIncreased(msg.sender, msg.value);
}
/// Withdraw a bid that was overbid.
@@ -325,7 +330,7 @@ activate themselves.
// 2. Effects
ended = true;
- AuctionEnded(highestBidder, highestBid);
+ emit AuctionEnded(highestBidder, highestBid);
// 3. Interaction
beneficiary.transfer(highestBid);
@@ -371,7 +376,7 @@ high or low invalid bids.
::
- pragma solidity ^0.4.11;
+ pragma solidity ^0.4.21;
contract BlindAuction {
struct Bid {
@@ -509,7 +514,7 @@ high or low invalid bids.
onlyAfter(revealEnd)
{
require(!ended);
- AuctionEnded(highestBidder, highestBid);
+ emit AuctionEnded(highestBidder, highestBid);
ended = true;
beneficiary.transfer(highestBid);
}
@@ -524,7 +529,7 @@ Safe Remote Purchase
::
- pragma solidity ^0.4.11;
+ pragma solidity ^0.4.21;
contract Purchase {
uint public value;
@@ -574,7 +579,7 @@ Safe Remote Purchase
onlySeller
inState(State.Created)
{
- Aborted();
+ emit Aborted();
state = State.Inactive;
seller.transfer(this.balance);
}
@@ -589,7 +594,7 @@ Safe Remote Purchase
condition(msg.value == (2 * value))
payable
{
- PurchaseConfirmed();
+ emit PurchaseConfirmed();
buyer = msg.sender;
state = State.Locked;
}
@@ -601,7 +606,7 @@ Safe Remote Purchase
onlyBuyer
inState(State.Locked)
{
- ItemReceived();
+ emit ItemReceived();
// It is important to change the state first because
// otherwise, the contracts called using `send` below
// can call in again here.
diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst
index a9a7ed52..df40b1d0 100644
--- a/docs/structure-of-a-contract.rst
+++ b/docs/structure-of-a-contract.rst
@@ -86,14 +86,14 @@ Events are convenience interfaces with the EVM logging facilities.
::
- pragma solidity ^0.4.0;
+ pragma solidity ^0.4.21;
contract SimpleAuction {
event HighestBidIncreased(address bidder, uint amount); // Event
function bid() public payable {
// ...
- HighestBidIncreased(msg.sender, msg.value); // Triggering event
+ emit HighestBidIncreased(msg.sender, msg.value); // Triggering event
}
}
diff --git a/docs/style-guide.rst b/docs/style-guide.rst
index 4c0d44f0..2261746f 100644
--- a/docs/style-guide.rst
+++ b/docs/style-guide.rst
@@ -112,6 +112,111 @@ No::
}
}
+.. _maximum_line_length:
+
+Maximum Line Length
+===================
+
+Keeping lines under the `PEP 8 recommendation <https://www.python.org/dev/peps/pep-0008/#maximum-line-length>`_ of 79 (or 99)
+characters helps readers easily parse the code.
+
+Wrapped lines should conform to the following guidelines.
+
+1. The first argument should not be attached to the opening parenthesis.
+2. One, and only one, indent should be used.
+3. Each argument should fall on its own line.
+4. The terminating element, :code:`);`, should be placed on the final line by itself.
+
+Function Calls
+
+Yes::
+
+ thisFunctionCallIsReallyLong(
+ longArgument1,
+ longArgument2,
+ longArgument3
+ );
+
+No::
+
+ thisFunctionCallIsReallyLong(longArgument1,
+ longArgument2,
+ longArgument3
+ );
+
+ thisFunctionCallIsReallyLong(longArgument1,
+ longArgument2,
+ longArgument3
+ );
+
+ thisFunctionCallIsReallyLong(
+ longArgument1, longArgument2,
+ longArgument3
+ );
+
+ thisFunctionCallIsReallyLong(
+ longArgument1,
+ longArgument2,
+ longArgument3
+ );
+
+ thisFunctionCallIsReallyLong(
+ longArgument1,
+ longArgument2,
+ longArgument3);
+
+Assignment Statements
+
+Yes::
+
+ thisIsALongNestedMapping[being][set][to_some_value] = someFunction(
+ argument1,
+ argument2,
+ argument3,
+ argument4
+ );
+
+No::
+
+ thisIsALongNestedMapping[being][set][to_some_value] = someFunction(argument1,
+ argument2,
+ argument3,
+ argument4);
+
+Event Definitions and Event Emitters
+
+Yes::
+
+ event LongAndLotsOfArgs(
+ adress sender,
+ adress recipient,
+ uint256 publicKey,
+ uint256 amount,
+ bytes32[] options
+ );
+
+ LongAndLotsOfArgs(
+ sender,
+ recipient,
+ publicKey,
+ amount,
+ options
+ );
+
+No::
+
+ event LongAndLotsOfArgs(adress sender,
+ adress recipient,
+ uint256 publicKey,
+ uint256 amount,
+ bytes32[] options);
+
+ LongAndLotsOfArgs(sender,
+ recipient,
+ publicKey,
+ amount,
+ options);
+
Source File Encoding
====================
@@ -391,7 +496,7 @@ function body to be kept on the same line as the function declaration.
The closing brace should be at the same indentation level as the function
declaration.
-The opening brace should be preceeded by a single space.
+The opening brace should be preceded by a single space.
Yes::
@@ -421,7 +526,21 @@ No::
function increment(uint x) public pure returns (uint) {
return x + 1;}
-The visibility modifiers for a function should come before any custom
+You should explicitly label the visibility of all functions, including constructors.
+
+Yes::
+
+ function explicitlyPublic(uint val) public {
+ doSomething();
+ }
+
+No::
+
+ function implicitlyPublic(uint val) {
+ doSomething();
+ }
+
+The visibility modifier for a function should come before any custom
modifiers.
Yes::
@@ -533,6 +652,50 @@ No::
doSomething();
}
+Multiline output parameters and return statements should follow the same style recommended for wrapping long lines found in the :ref:`Maximum Line Length <maximum_line_length>` section.
+
+Yes::
+
+ function thisFunctionNameIsReallyLong(
+ address a,
+ address b,
+ address c
+ )
+ public
+ returns (
+ address someAddressName,
+ uint256 LongArgument,
+ uint256 Argument
+ )
+ {
+ doSomething()
+
+ return (
+ veryLongReturnArg1,
+ veryLongReturnArg2,
+ veryLongReturnArg3
+ );
+ }
+
+No::
+
+ function thisFunctionNameIsReallyLong(
+ address a,
+ address b,
+ address c
+ )
+ public
+ returns (address someAddressName,
+ uint256 LongArgument,
+ uint256 Argument)
+ {
+ doSomething()
+
+ return (veryLongReturnArg1,
+ veryLongReturnArg1,
+ veryLongReturnArg1);
+ }
+
For constructor functions on inherited contracts whose bases require arguments,
it is recommended to drop the base constructors onto new lines in the same
manner as modifiers if the function declaration is long or hard to read.
@@ -684,7 +847,7 @@ naming styles.
* ``mixedCase`` (differs from CapitalizedWords by initial lowercase character!)
* ``Capitalized_Words_With_Underscores``
-.. note:: When using abbreviations in CapWords, capitalize all the letters of the abbreviation. Thus HTTPServerError is better than HttpServerError.
+.. note:: When using initialisms in CapWords, capitalize all the letters of the initialisms. Thus HTTPServerError is better than HttpServerError. When using initialisms is mixedCase, capitalize all the letters of the initialisms, except keep the first one lower case if it is the beginning of the name. Thus xmlHTTPRequest is better than XMLHTTPRequest.
Names to Avoid
diff --git a/docs/types.rst b/docs/types.rst
index 55eaa69a..e704687e 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -470,7 +470,7 @@ Example that shows how to use internal function types::
Another example that uses external function types::
- pragma solidity ^0.4.11;
+ pragma solidity ^0.4.21;
contract Oracle {
struct Request {
@@ -481,7 +481,7 @@ Another example that uses external function types::
event NewRequest(uint);
function query(bytes data, function(bytes memory) external callback) public {
requests.push(Request(data, callback));
- NewRequest(requests.length - 1);
+ emit NewRequest(requests.length - 1);
}
function reply(uint requestID, bytes response) public {
// Here goes the check that the reply comes from a trusted source
diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst
index ce58cf56..1b58b1e8 100644
--- a/docs/units-and-global-variables.rst
+++ b/docs/units-and-global-variables.rst
@@ -58,8 +58,9 @@ Block and Transaction Properties
- ``block.gaslimit`` (``uint``): current block gaslimit
- ``block.number`` (``uint``): current block number
- ``block.timestamp`` (``uint``): current block timestamp as seconds since unix epoch
+- ``gasleft() returns (uint256)``: remaining gas
- ``msg.data`` (``bytes``): complete calldata
-- ``msg.gas`` (``uint``): remaining gas
+- ``msg.gas`` (``uint``): remaining gas - deprecated in version 0.4.21 and to be replaced by ``gasleft()``
- ``msg.sender`` (``address``): sender of the message (current call)
- ``msg.sig`` (``bytes4``): first four bytes of the calldata (i.e. function identifier)
- ``msg.value`` (``uint``): number of wei sent with the message
@@ -107,9 +108,9 @@ Mathematical and Cryptographic Functions
----------------------------------------
``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``.
+ compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
``mulmod(uint x, uint y, uint k) returns (uint)``:
- compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``.
+ compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
``keccak256(...) returns (bytes32)``:
compute the Ethereum-SHA-3 (Keccak-256) hash of the :ref:`(tightly packed) arguments <abi_packed_mode>`
``sha256(...) returns (bytes32)``:
@@ -149,15 +150,15 @@ Address Related
``<address>.balance`` (``uint256``):
balance of the :ref:`address` in Wei
``<address>.transfer(uint256 amount)``:
- send given amount of Wei to :ref:`address`, throws on failure
+ send given amount of Wei to :ref:`address`, throws on failure, forwards 2300 gas stipend, not adjustable
``<address>.send(uint256 amount) returns (bool)``:
- send given amount of Wei to :ref:`address`, returns ``false`` on failure
+ send given amount of Wei to :ref:`address`, returns ``false`` on failure, forwards 2300 gas stipend, not adjustable
``<address>.call(...) returns (bool)``:
- issue low-level ``CALL``, returns ``false`` on failure
+ issue low-level ``CALL``, returns ``false`` on failure, forwards all available gas, adjustable
``<address>.callcode(...) returns (bool)``:
- issue low-level ``CALLCODE``, returns ``false`` on failure
+ issue low-level ``CALLCODE``, returns ``false`` on failure, forwards all available gas, adjustable
``<address>.delegatecall(...) returns (bool)``:
- issue low-level ``DELEGATECALL``, returns ``false`` on failure
+ issue low-level ``DELEGATECALL``, returns ``false`` on failure, forwards all available gas, adjustable
For more information, see the section on :ref:`address`.
diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst
index 42cc807a..df30b6b4 100644
--- a/docs/using-the-compiler.rst
+++ b/docs/using-the-compiler.rst
@@ -9,6 +9,9 @@ Using the compiler
Using the Commandline Compiler
******************************
+.. note::
+ This section doesn't apply to :ref:`solcjs <solcjs>`.
+
One of the build targets of the Solidity repository is ``solc``, the solidity commandline compiler.
Using ``solc --help`` provides you with an explanation of all options. The compiler can produce various outputs, ranging from simple binaries and assembly over an abstract syntax tree (parse tree) to estimations of gas usage.
If you only want to compile a single file, you run it as ``solc --bin sourceFile.sol`` and it will print the binary. Before you deploy your contract, activate the optimizer while compiling using ``solc --optimize --bin sourceFile.sol``. If you want to get some of the more advanced output variants of ``solc``, it is probably better to tell it to output everything to separate files using ``solc -o outputDirectory --bin --ast --asm sourceFile.sol``.
@@ -98,6 +101,7 @@ Input Description
enabled: true,
runs: 500
},
+ evmVersion: "byzantium", // Version of the EVM to compile for. Affects type checking and code generation. Can be homestead, tangerineWhistle, spuriousDragon, byzantium or constantinople
// Metadata settings (optional)
metadata: {
// Use only literal content and not URLs (false by default)