aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/abi-spec.rst6
-rw-r--r--docs/assembly.rst367
-rw-r--r--docs/contracts.rst27
-rw-r--r--docs/control-structures.rst61
-rw-r--r--docs/frequently-asked-questions.rst63
-rw-r--r--docs/grammar.txt3
-rw-r--r--docs/index.rst1
-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.rst6
-rw-r--r--docs/solidity-by-example.rst43
-rw-r--r--docs/structure-of-a-contract.rst4
-rw-r--r--docs/style-guide.rst2
-rw-r--r--docs/types.rst4
-rw-r--r--docs/units-and-global-variables.rst14
-rw-r--r--docs/using-the-compiler.rst3
17 files changed, 431 insertions, 352 deletions
diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst
index 8095a3b7..07c8e0ce 100644
--- a/docs/abi-spec.rst
+++ b/docs/abi-spec.rst
@@ -155,15 +155,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.
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/contracts.rst b/docs/contracts.rst
index afc32b16..416dc649 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -467,13 +467,13 @@ 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``.
.. warning::
- The compiler does not enforce yet that a ``view`` method is not modifying state.
+ Before version 0.4.17 the compiler didn't enforce that ``view`` is not modifying the state.
.. index:: ! pure function, function;pure
@@ -503,7 +503,7 @@ In addition to the list of state modifying statements explained above, the follo
}
.. warning::
- The compiler does not enforce yet that a ``pure`` method is not reading from the state.
+ Before version 0.4.17 the compiler didn't enforce that ``view`` is not reading the state.
.. index:: ! fallback function, function;fallback
@@ -724,10 +724,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);
}
}
@@ -1053,6 +1055,17 @@ 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;
+
+
.. index:: ! contract;interface, ! interface contract
**********
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index 7be92cfa..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
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..184d0e69 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -34,6 +34,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..11e07292 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.20; // should actually be 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..b5d605ac 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -219,7 +219,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
@@ -327,8 +327,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..57556fa5 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.20; // should actually be 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.20; // should actually be 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.20; // should actually be 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..4a0873df 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.20; // should actually be 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 533c4be5..2261746f 100644
--- a/docs/style-guide.rst
+++ b/docs/style-guide.rst
@@ -847,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..3611bc3e 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.20; // should actually be 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..cc4d4446 100644
--- a/docs/units-and-global-variables.rst
+++ b/docs/units-and-global-variables.rst
@@ -107,9 +107,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 +149,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..66e3ac35 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``.