aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/abi-spec.rst8
-rw-r--r--docs/assembly.rst15
-rw-r--r--docs/bugs_by_version.json4
-rw-r--r--docs/common-patterns.rst25
-rw-r--r--docs/contracts.rst66
-rw-r--r--docs/contributing.rst149
-rw-r--r--docs/control-structures.rst54
-rw-r--r--docs/grammar.txt2
-rw-r--r--docs/index.rst1
-rw-r--r--docs/installing-solidity.rst1
-rw-r--r--docs/introduction-to-smart-contracts.rst8
-rw-r--r--docs/miscellaneous.rst40
-rw-r--r--docs/solidity-by-example.rst75
-rw-r--r--docs/structure-of-a-contract.rst7
-rw-r--r--docs/style-guide.rst2
-rw-r--r--docs/types.rst13
-rw-r--r--docs/units-and-global-variables.rst42
17 files changed, 421 insertions, 91 deletions
diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst
index 4a61d91f..98301fdc 100644
--- a/docs/abi-spec.rst
+++ b/docs/abi-spec.rst
@@ -54,11 +54,11 @@ The following elementary types exist:
- ``ufixed<M>x<N>``: unsigned variant of ``fixed<M>x<N>``.
-- ``fixed``, ``ufixed``: synonyms for ``fixed128x19``, ``ufixed128x19`` respectively. For computing the function selector, ``fixed128x19`` and ``ufixed128x19`` have to be used.
+- ``fixed``, ``ufixed``: synonyms for ``fixed128x18``, ``ufixed128x18`` respectively. For computing the function selector, ``fixed128x18`` and ``ufixed128x18`` have to be used.
- ``bytes<M>``: binary type of ``M`` bytes, ``0 < M <= 32``.
-- ``function``: an address (20 bytes) folled by a function selector (4 bytes). Encoded identical to ``bytes24``.
+- ``function``: an address (20 bytes) followed by a function selector (4 bytes). Encoded identical to ``bytes24``.
The following (fixed-size) array type exists:
@@ -164,9 +164,9 @@ on the type of ``X`` being
- ``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
+- ``fixed``: as in the ``fixed128x18`` 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
+- ``ufixed``: as in the ``ufixed128x18`` case
- ``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 cf9bf840..978e71e3 100644
--- a/docs/assembly.rst
+++ b/docs/assembly.rst
@@ -405,6 +405,16 @@ changes during the call, and thus references to local variables will be wrong.
}
}
+.. note::
+ If you access variables of a type that spans less than 256 bits
+ (for example ``uint64``, ``address``, ``bytes16`` or ``byte``),
+ you cannot make any assumptions about bits not part of the
+ encoding of the type. Especially, do not assume them to be zero.
+ To be safe, always clear the data properly before you use it
+ in a context where this is important:
+ ``uint32 x = f(); assembly { x := and(x, 0xffffffff) /* now use x */ }``
+ To clean signed types, you can use the ``signextend`` opcode.
+
Labels
------
@@ -647,6 +657,11 @@ Solidity manages memory in a very simple way: There is a "free memory pointer"
at position ``0x40`` in memory. If you want to allocate memory, just use the memory
from that point on and update the pointer accordingly.
+The first 64 bytes of memory can be used as "scratch space" for short-term
+allocation. The 32 bytes after the free memory pointer (i.e. starting at ``0x60``)
+is meant to be zero permanently and is used as the initial value for
+empty dynamic memory arrays.
+
Elements in memory arrays in Solidity always occupy multiples of 32 bytes (yes, this is
even true for ``byte[]``, but not for ``bytes`` and ``string``). Multi-dimensional memory
arrays are pointers to memory arrays. The length of a dynamic array is stored at the
diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json
index 4c976a32..32f305c8 100644
--- a/docs/bugs_by_version.json
+++ b/docs/bugs_by_version.json
@@ -422,6 +422,10 @@
"bugs": [],
"released": "2018-03-07"
},
+ "0.4.22": {
+ "bugs": [],
+ "released": "2018-04-16"
+ },
"0.4.3": {
"bugs": [
"ZeroFunctionSelector",
diff --git a/docs/common-patterns.rst b/docs/common-patterns.rst
index 7e09f534..739e136f 100644
--- a/docs/common-patterns.rst
+++ b/docs/common-patterns.rst
@@ -130,7 +130,7 @@ restrictions highly readable.
::
- pragma solidity ^0.4.11;
+ pragma solidity ^0.4.22;
contract AccessRestriction {
// These will be assigned at the construction
@@ -147,7 +147,10 @@ restrictions highly readable.
// a certain address.
modifier onlyBy(address _account)
{
- require(msg.sender == _account);
+ require(
+ msg.sender == _account,
+ "Sender not authorized."
+ );
// Do not forget the "_;"! It will
// be replaced by the actual function
// body when the modifier is used.
@@ -164,7 +167,10 @@ restrictions highly readable.
}
modifier onlyAfter(uint _time) {
- require(now >= _time);
+ require(
+ now >= _time,
+ "Function called too early."
+ );
_;
}
@@ -186,7 +192,10 @@ restrictions highly readable.
// This was dangerous before Solidity version 0.4.0,
// where it was possible to skip the part after `_;`.
modifier costs(uint _amount) {
- require(msg.value >= _amount);
+ require(
+ msg.value >= _amount,
+ "Not enough Ether provided."
+ );
_;
if (msg.value > _amount)
msg.sender.send(msg.value - _amount);
@@ -194,6 +203,7 @@ restrictions highly readable.
function forceOwnerChange(address _newOwner)
public
+ payable
costs(200 ether)
{
owner = _newOwner;
@@ -272,7 +282,7 @@ function finishes.
::
- pragma solidity ^0.4.11;
+ pragma solidity ^0.4.22;
contract StateMachine {
enum Stages {
@@ -289,7 +299,10 @@ function finishes.
uint public creationTime = now;
modifier atStage(Stages _stage) {
- require(stage == _stage);
+ require(
+ stage == _stage,
+ "Function cannot be called at this time."
+ );
_;
}
diff --git a/docs/contracts.rst b/docs/contracts.rst
index 121c4de0..a1f2895c 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -40,7 +40,7 @@ This means that cyclic creation dependencies are impossible.
::
- pragma solidity ^0.4.16;
+ pragma solidity ^0.4.22;
contract OwnedToken {
// TokenCreator is a contract type that is defined below.
@@ -52,7 +52,7 @@ This means that cyclic creation dependencies are impossible.
// This is the constructor which registers the
// creator and the assigned name.
- function OwnedToken(bytes32 _name) public {
+ constructor(bytes32 _name) public {
// State variables are accessed via their name
// and not via e.g. this.owner. This also applies
// to functions and especially in the constructors,
@@ -301,7 +301,7 @@ inheritable properties of contracts and may be overridden by derived contracts.
::
- pragma solidity ^0.4.11;
+ pragma solidity ^0.4.22;
contract owned {
function owned() public { owner = msg.sender; }
@@ -315,7 +315,10 @@ inheritable properties of contracts and may be overridden by derived contracts.
// function is executed and otherwise, an exception is
// thrown.
modifier onlyOwner {
- require(msg.sender == owner);
+ require(
+ msg.sender == owner,
+ "Only owner can call this function."
+ );
_;
}
}
@@ -360,7 +363,10 @@ inheritable properties of contracts and may be overridden by derived contracts.
contract Mutex {
bool locked;
modifier noReentrancy() {
- require(!locked);
+ require(
+ !locked,
+ "Reentrant call."
+ );
locked = true;
_;
locked = false;
@@ -679,7 +685,7 @@ candidate, resolution fails.
}
}
-Calling ``f(50)`` would create a type error since ``250`` can be implicitly converted both to ``uint8``
+Calling ``f(50)`` would create a type error since ``50`` can be implicitly converted both to ``uint8``
and ``uint256`` types. On another hand ``f(256)`` would resolve to ``f(uint256)`` overload as ``256`` cannot be implicitly
converted to ``uint8``.
@@ -803,7 +809,7 @@ as topics. The event call above can be performed in the same way as
}
where the long hexadecimal number is equal to
-``keccak256("Deposit(address,hash256,uint256)")``, the signature of the event.
+``keccak256("Deposit(address,bytes32,uint256)")``, the signature of the event.
Additional Resources for Understanding Events
==============================================
@@ -976,8 +982,31 @@ virtual method lookup.
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``.
+A constructor is an optional function declared with the ``constructor`` keyword which is executed upon contract creation.
+Constructor functions can be either ``public`` or ``internal``. If there is no constructor, the contract will assume the
+default constructor: ``contructor() public {}``.
+
+
+::
+
+ pragma solidity ^0.4.22;
+
+ contract A {
+ uint public a;
+
+ constructor(uint _a) internal {
+ a = _a;
+ }
+ }
+
+ contract B is A(1) {
+ constructor() public {}
+ }
+
+A constructor set as ``internal`` causes the contract to be marked as :ref:`abstract <abstract-contract>`.
+
+.. note ::
+ Prior to version 0.4.22, constructors were defined as functions with the same name as the contract. This syntax is now deprecated.
::
@@ -995,7 +1024,6 @@ Constructor functions can be either ``public`` or ``internal``.
function B() public {}
}
-A constructor set as ``internal`` causes the contract to be marked as :ref:`abstract <abstract-contract>`.
.. index:: ! base;constructor
@@ -1009,12 +1037,15 @@ the base constructors. This can be done in two ways::
contract Base {
uint x;
- function Base(uint _x) public { x = _x; }
+ constructor(uint _x) public { x = _x; }
}
- contract Derived is Base(7) {
- function Derived(uint _y) Base(_y * _y) public {
- }
+ contract Derived1 is Base(7) {
+ constructor(uint _y) public {}
+ }
+
+ contract Derived2 is Base {
+ constructor(uint _y) Base(_y * _y) public {}
}
One way is directly in the inheritance list (``is Base(7)``). The other is in
@@ -1024,8 +1055,9 @@ do it is more convenient if the constructor argument is a
constant and defines the behaviour of the contract or
describes it. The second way has to be used if the
constructor arguments of the base depend on those of the
-derived contract. If, as in this silly example, both places
-are used, the modifier-style argument takes precedence.
+derived contract. Arguments have to be given either in the
+inheritance list or in modifier-style in the derived constuctor.
+Specifying arguments in both places is an error.
.. index:: ! inheritance;multiple, ! linearization, ! C3 linearization
@@ -1183,7 +1215,7 @@ more advanced example to implement a set).
::
- pragma solidity ^0.4.16;
+ pragma solidity ^0.4.22;
library Set {
// We define a new struct datatype that will be used to
diff --git a/docs/contributing.rst b/docs/contributing.rst
index a5efba8b..6717a8b9 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -55,8 +55,8 @@ However, if you are making a larger change, please consult with the `Solidity De
focused on compiler and language development instead of language use) first.
-Finally, please make sure you respect the `coding standards
-<https://raw.githubusercontent.com/ethereum/cpp-ethereum/develop/CodingStandards.txt>`_
+Finally, please make sure you respect the `coding style
+<https://raw.githubusercontent.com/ethereum/solidity/develop/CODING_STYLE.md>`_
for this project. Also, even though we do CI testing, please test your code and
ensure that it builds locally before submitting a pull request.
@@ -69,21 +69,158 @@ Solidity includes different types of tests. They are included in the application
called ``soltest``. Some of them require the ``cpp-ethereum`` client in testing mode,
some others require ``libz3`` to be installed.
-To disable the z3 tests, use ``./build/test/soltest -- --no-smt`` and
-to run a subset of the tests that do not require ``cpp-ethereum``, use ``./build/test/soltest -- --no-ipc``.
+``soltest`` reads test contracts that are annotated with expected results
+stored in ``./test/libsolidity/syntaxTests``. In order for soltest to find these
+tests the root test directory has to be specified using the ``--testpath`` command
+line option, e.g. ``./build/test/soltest -- --testpath ./test``.
+
+To disable the z3 tests, use ``./build/test/soltest -- --no-smt --testpath ./test`` and
+to run a subset of the tests that do not require ``cpp-ethereum``, use
+``./build/test/soltest -- --no-ipc --testpath ./test``.
For all other tests, you need to install `cpp-ethereum <https://github.com/ethereum/cpp-ethereum/releases/download/solidityTester/eth>`_ and run it in testing mode: ``eth --test -d /tmp/testeth``.
-Then you run the actual tests: ``./build/test/soltest -- --ipcpath /tmp/testeth/geth.ipc``.
+Then you run the actual tests: ``./build/test/soltest -- --ipcpath /tmp/testeth/geth.ipc --testpath ./test``.
To run a subset of tests, filters can be used:
-``soltest -t TestSuite/TestName -- --ipcpath /tmp/testeth/geth.ipc``, where ``TestName`` can be a wildcard ``*``.
+``soltest -t TestSuite/TestName -- --ipcpath /tmp/testeth/geth.ipc --testpath ./test``,
+where ``TestName`` can be a wildcard ``*``.
Alternatively, there is a testing script at ``scripts/test.sh`` which executes all tests and runs
``cpp-ethereum`` automatically if it is in the path (but does not download it).
Travis CI even runs some additional tests (including ``solc-js`` and testing third party Solidity frameworks) that require compiling the Emscripten target.
+Writing and running syntax tests
+--------------------------------
+
+As mentioned above, syntax tests are stored in individual contracts. These files must contain annotations, stating the expected result(s) of the respective test.
+The test suite will compile and check them against the given expectations.
+
+Example: ``./test/libsolidity/syntaxTests/double_stateVariable_declaration.sol``
+
+::
+
+ contract test {
+ uint256 variable;
+ uint128 variable;
+ }
+ // ----
+ // DeclarationError: Identifier already declared.
+
+A syntax test must contain at least the contract under test itself, followed by the seperator ``----``. The additional comments above are used to describe the
+expected compiler errors or warnings. This section can be empty in case that the contract should compile without any errors or warnings.
+
+In the above example, the state variable ``variable`` was declared twice, which is not allowed. This will result in a ``DeclarationError`` stating that the identifer was already declared.
+
+The tool that is being used for those tests is called ``isoltest`` and can be found under ``./test/tools/``. It is an interactive tool which allows
+editing of failing contracts using your prefered text editor. Let's try to break this test by removing the second declaration of ``variable``:
+
+::
+
+ contract test {
+ uint256 variable;
+ }
+ // ----
+ // DeclarationError: Identifier already declared.
+
+Running ``./test/isoltest`` again will result in a test failure:
+
+::
+
+ syntaxTests/double_stateVariable_declaration.sol: FAIL
+ Contract:
+ contract test {
+ uint256 variable;
+ }
+
+ Expected result:
+ DeclarationError: Identifier already declared.
+ Obtained result:
+ Success
+
+
+which prints the expected result next to the obtained result, but also provides a way to change edit / update / skip the current contract or to even quit.
+``isoltest`` offers several options for failing tests:
+
+- edit: ``isoltest`` will try to open the editor that was specified before using ``isoltest --editor /path/to/editor``. If no path was set, this will result in a runtime error. In case an editor was specified, this will open it such that the contract can be adjusted.
+- update: Updates the contract under test. This will either remove the annotation which contains the exception not met or will add missing expectations. The test will then be run again.
+- skip: Skips the execution of this particular test.
+- quit: Quits ``isoltest``.
+
+Automatically updating the test above will change it to
+
+::
+
+ contract test {
+ uint256 variable;
+ }
+ // ----
+
+and re-run the test. It will now pass again:
+
+::
+
+ Re-running test case...
+ syntaxTests/double_stateVariable_declaration.sol: OK
+
+
+.. note::
+
+ Please choose a name for the contract file, that is self-explainatory in the sense of what is been tested, e.g. ``double_variable_declaration.sol``.
+ Do not put more than one contract into a single file. ``isoltest`` is currently not able to recognize them individually.
+
+
+Running the Fuzzer via AFL
+==========================
+
+Fuzzing is a technique that runs programs on more or less random inputs to find exceptional execution
+states (segmentation faults, exceptions, etc). Modern fuzzers are clever and do a directed search
+inside the input. We have a specialized binary called ``solfuzzer`` which takes source code as input
+and fails whenever it encounters an internal compiler error, segmentation fault or similar, but
+does not fail if e.g. the code contains an error. This way, internal problems in the compiler
+can be found by fuzzing tools.
+
+We mainly use `AFL <http://lcamtuf.coredump.cx/afl/>`_ for fuzzing. You need to download and
+build AFL manually. Next, build Solidity (or just the ``solfuzzer`` binary) with AFL as your compiler:
+
+::
+
+ cd build
+ # if needed
+ make clean
+ cmake .. -DCMAKE_C_COMPILER=path/to/afl-gcc -DCMAKE_CXX_COMPILER=path/to/afl-g++
+ make solfuzzer
+
+Next, you need some example source files. This will make it much easer for the fuzzer
+to find errors. You can either copy some files from the syntax tests or extract test files
+from the documentation or the other tests:
+
+::
+
+ mkdir /tmp/test_cases
+ cd /tmp/test_cases
+ # extract from tests:
+ path/to/solidity/scripts/isolate_tests.py path/to/solidity/test/libsolidity/SolidityEndToEndTest.cpp
+ # extract from documentation:
+ path/to/solidity/scripts/isolate_tests.py path/to/solidity/docs docs
+
+The AFL documentation states that the corpus (the initial input files) should not be
+too large. The files themselves should not be larger than 1 kB and there should be
+at most one input file per functionality, so better start with a small number of
+input files. There is also a tool called ``afl-cmin`` that can trim input files
+that result in similar behaviour of the binary.
+
+Now run the fuzzer (the ``-m`` extends the size of memory to 60 MB):
+
+::
+
+ afl-fuzz -m 60 -i /tmp/test_cases -o /tmp/fuzzer_reports -- /path/to/solfuzzer
+
+The fuzzer will create source files that lead to failures in ``/tmp/fuzzer_reports``.
+Often it finds many similar source files that produce the same error. You can
+use the tool ``scripts/uniqueErrors.sh`` to filter out the unique errors.
+
Whiskers
========
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index 46e076e5..f3c351dd 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -284,10 +284,12 @@ Solidity internally allows tuple types, i.e. a list of objects of potentially di
}
function g() public {
- // Declares and assigns the variables. Specifying the type explicitly is not possible.
- var (x, b, y) = f();
- // Assigns to a pre-existing variable.
- (x, y) = (2, 7);
+ // Variables declared with type
+ uint x;
+ bool b;
+ uint y;
+ // Tuple values can be assigned to these pre-existing variables
+ (x, b, y) = f();
// Common trick to swap values -- does not work for non-value storage types.
(x, y) = (y, x);
// Components can be left out (also for variable declarations).
@@ -453,8 +455,9 @@ The ``require`` function should be used to ensure valid conditions, such as inpu
If used properly, analysis tools can evaluate your contract to identify the conditions and function calls which will reach a failing ``assert``. Properly functioning code should never reach a failing assert statement; if this happens there is a bug in your contract which you should fix.
There are two other ways to trigger exceptions: The ``revert`` function can be used to flag an error and
-revert the current call. In the future it might be possible to also include details about the error
-in a call to ``revert``. The ``throw`` keyword can also be used as an alternative to ``revert()``.
+revert the current call. It is possible to provide a string message containing details about the error
+that will be passed back to the caller.
+The deprecated keyword ``throw`` can also be used as an alternative to ``revert()`` (but only without error message).
.. note::
From version 0.4.13 the ``throw`` keyword is deprecated and will be phased out in the future.
@@ -469,13 +472,16 @@ of an exception instead of "bubbling up".
Catching exceptions is not yet possible.
In the following example, you can see how ``require`` can be used to easily check conditions on inputs
-and how ``assert`` can be used for internal error checking::
+and how ``assert`` can be used for internal error checking. Note that you can optionally provide
+a message string for ``require``, but not for ``assert``.
- pragma solidity ^0.4.0;
+::
+
+ pragma solidity ^0.4.22;
contract Sharer {
function sendHalf(address addr) public payable returns (uint balance) {
- require(msg.value % 2 == 0); // Only allow even numbers
+ require(msg.value % 2 == 0, "Even value required.");
uint balanceBeforeTransfer = this.balance;
addr.transfer(msg.value / 2);
// Since transfer throws an exception on failure and
@@ -513,3 +519,33 @@ the EVM to revert all changes made to the state. The reason for reverting is tha
did not occur. Because we want to retain the atomicity of transactions, the safest thing to do is to revert all changes and make the whole transaction
(or at least call) without effect. Note that ``assert``-style exceptions consume all gas available to the call, while
``require``-style exceptions will not consume any gas starting from the Metropolis release.
+
+The following example shows how an error string can be used together with revert and require:
+
+::
+
+ pragma solidity ^0.4.22;
+
+ contract VendingMachine {
+ function buy(uint amount) payable {
+ if (amount > msg.value / 2 ether)
+ revert("Not enough Ether provided.");
+ // Alternative way to do it:
+ require(
+ amount <= msg.value / 2 ether,
+ "Not enough Ether provided."
+ );
+ // Perform the purchase.
+ }
+ }
+
+The provided string will be :ref:`abi-encoded <ABI>` as if it were a call to a function ``Error(string)``.
+In the above example, ``revert("Not enough Ether provided.");`` will cause the following hexadecimal data be
+set as error return data:
+
+.. code::
+
+ 0x08c379a0 // Function selector for Error(string)
+ 0x0000000000000000000000000000000000000000000000000000000000000020 // Data offset
+ 0x000000000000000000000000000000000000000000000000000000000000001a // String length
+ 0x4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 // String data
diff --git a/docs/grammar.txt b/docs/grammar.txt
index a5c2acf3..b4ca5ca9 100644
--- a/docs/grammar.txt
+++ b/docs/grammar.txt
@@ -19,7 +19,7 @@ InheritanceSpecifier = UserDefinedTypeName ( '(' Expression ( ',' Expression )*
StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' | 'constant' )? Identifier ('=' Expression)? ';'
UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';'
StructDefinition = 'struct' Identifier '{'
- ( VariableDeclaration ';' (VariableDeclaration ';')* )? '}'
+ ( VariableDeclaration ';' (VariableDeclaration ';')* ) '}'
ModifierDefinition = 'modifier' Identifier ParameterList? Block
ModifierInvocation = Identifier ( '(' ExpressionList? ')' )?
diff --git a/docs/index.rst b/docs/index.rst
index f53b0fc4..80b0d6e7 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -39,6 +39,7 @@ This documentation is translated into several languages by community volunteers,
* `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)
+* `Korean <http://solidity-kr.readthedocs.io>`_ (in progress)
Useful links
diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst
index e26870f0..6726ded9 100644
--- a/docs/installing-solidity.rst
+++ b/docs/installing-solidity.rst
@@ -122,7 +122,6 @@ We will re-add the pre-built bottles soon.
brew upgrade
brew tap ethereum/ethereum
brew install solidity
- brew linkapps solidity
If you need a specific version of Solidity you can install a
Homebrew formula directly from Github.
diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst
index 56f0fe3e..84b1fff8 100644
--- a/docs/introduction-to-smart-contracts.rst
+++ b/docs/introduction-to-smart-contracts.rst
@@ -326,7 +326,13 @@ EVM bytecode and executed. The output of this execution is
permanently stored as the code of the contract.
This means that in order to create a contract, you do not
send the actual code of the contract, but in fact code that
-returns that code.
+returns that code when executed.
+
+.. note::
+ While a contract is being created, its code is still empty.
+ Because of that, you should not call back into the
+ contract under construction until its constructor has
+ finished executing.
.. index:: ! gas, ! gas price
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index 075b6be0..c7c32528 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -64,12 +64,15 @@ The position of ``data[4][9].b`` is at ``keccak256(uint256(9) . keccak256(uint25
Layout in Memory
****************
-Solidity reserves three 256-bit slots:
+Solidity reserves four 32 byte slots:
-- 0 - 64: scratch space for hashing methods
-- 64 - 96: currently allocated memory size (aka. free memory pointer)
+- ``0x00`` - ``0x3f``: scratch space for hashing methods
+- ``0x40`` - ``0x5f``: currently allocated memory size (aka. free memory pointer)
+- ``0x60`` - ``0x7f``: zero slot
-Scratch space can be used between statements (ie. within inline assembly).
+Scratch space can be used between statements (ie. within inline assembly). The zero slot
+is used as initial value for dynamic memory arrays and should never be written to
+(the free memory pointer points to ``0x80`` initially).
Solidity always places new objects at the free memory pointer and memory is never freed (this might change in the future).
@@ -314,7 +317,12 @@ The following is the order of precedence for operators, listed in order of evalu
Global Variables
================
-- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks
+- ``abi.encode(...) returns (bytes)``: :ref:`ABI <ABI>`-encodes the given arguments
+- ``abi.encodePacked(...) returns (bytes)``: Performes :ref:`packed encoding <abi_packed_mode>` of the given arguments
+- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: :ref:`ABI <ABI>`-encodes the given arguments
+ starting from the second and prepends the given four-byte selector
+- ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(signature), ...)```
+- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by ``blockhash(uint blockNumber)``.
- ``block.coinbase`` (``address``): current block miner's address
- ``block.difficulty`` (``uint``): current block difficulty
- ``block.gaslimit`` (``uint``): current block gaslimit
@@ -330,7 +338,10 @@ Global Variables
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error)
- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component)
+- ``require(bool condition, string message)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component). Also provide error message.
- ``revert()``: abort execution and revert state changes
+- ``revert(string message)``: abort execution and revert state changes providing an explanatory string
+- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks
- ``keccak256(...) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the :ref:`(tightly packed) arguments <abi_packed_mode>`
- ``sha3(...) returns (bytes32)``: an alias to ``keccak256``
- ``sha256(...) returns (bytes32)``: compute the SHA-256 hash of the :ref:`(tightly packed) arguments <abi_packed_mode>`
@@ -341,11 +352,28 @@ Global Variables
- ``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
-- ``suicide(address recipient)``: an alias to ``selfdestruct``
+- ``suicide(address recipient)``: a deprecated alias to ``selfdestruct``
- ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei
- ``<address>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`, returns ``false`` on failure
- ``<address>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure
+.. note::
+ Do not rely on ``block.timestamp``, ``now`` and ``blockhash`` as a source of randomness,
+ unless you know what you are doing.
+
+ Both the timestamp and the block hash can be influenced by miners to some degree.
+ Bad actors in the mining community can for example run a casino payout function on a chosen hash
+ and just retry a different hash if they did not receive any money.
+
+ The current block timestamp must be strictly larger than the timestamp of the last block,
+ but the only guarantee is that it will be somewhere between the timestamps of two
+ consecutive blocks in the canonical chain.
+
+.. note::
+ The block hashes are not available for all blocks for scalability reasons.
+ You can only access the hashes of the most recent 256 blocks, all other
+ values will be zero.
+
.. index:: visibility, public, private, external, internal
Function Visibility Specifiers
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index 27fefd49..546767e4 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -36,7 +36,7 @@ of votes.
::
- pragma solidity ^0.4.16;
+ pragma solidity ^0.4.22;
/// @title Voting with delegation.
contract Ballot {
@@ -87,18 +87,25 @@ of votes.
// Give `voter` the right to vote on this ballot.
// May only be called by `chairperson`.
function giveRightToVote(address voter) public {
- // If the argument of `require` evaluates to `false`,
- // it terminates and reverts all changes to
- // the state and to Ether balances. It is often
- // a good idea to use this if functions are
- // called incorrectly. But watch out, this
- // will currently also consume all provided gas
- // (this is planned to change in the future).
+ // If the first argument of `require` evaluates
+ // to `false`, execution terminates and all
+ // changes to the state and to Ether balances
+ // are reverted.
+ // This used to consume all gas in old EVM versions, but
+ // not anymore.
+ // It is often a good idea to use `require` to check if
+ // functions are called correctly.
+ // As a second argument, you can also provide an
+ // explanation about what went wrong.
require(
- (msg.sender == chairperson) &&
- !voters[voter].voted &&
- (voters[voter].weight == 0)
+ msg.sender == chairperson,
+ "Only chairperson can give right to vote."
);
+ require(
+ !voters[voter].voted,
+ "The voter already voted."
+ );
+ require(voters[voter].weight == 0);
voters[voter].weight = 1;
}
@@ -106,10 +113,9 @@ of votes.
function delegate(address to) public {
// assigns reference
Voter storage sender = voters[msg.sender];
- require(!sender.voted);
+ require(!sender.voted, "You already voted.");
- // Self-delegation is not allowed.
- require(to != msg.sender);
+ require(to != msg.sender, "Self-delegation is disallowed.");
// Forward the delegation as long as
// `to` also delegated.
@@ -123,7 +129,7 @@ of votes.
to = voters[to].delegate;
// We found a loop in the delegation, not allowed.
- require(to != msg.sender);
+ require(to != msg.sender, "Found loop in delegation.");
}
// Since `sender` is a reference, this
@@ -146,7 +152,7 @@ of votes.
/// to proposal `proposals[proposal].name`.
function vote(uint proposal) public {
Voter storage sender = voters[msg.sender];
- require(!sender.voted);
+ require(!sender.voted, "Already voted.");
sender.voted = true;
sender.vote = proposal;
@@ -219,7 +225,7 @@ activate themselves.
::
- pragma solidity ^0.4.21;
+ pragma solidity ^0.4.22;
contract SimpleAuction {
// Parameters of the auction. Times are either
@@ -271,11 +277,17 @@ activate themselves.
// Revert the call if the bidding
// period is over.
- require(now <= auctionEnd);
+ require(
+ now <= auctionEnd,
+ "Auction already ended."
+ );
// If the bid is not higher, send the
// money back.
- require(msg.value > highestBid);
+ require(
+ msg.value > highestBid,
+ "There already is a higher bid."
+ );
if (highestBid != 0) {
// Sending back the money by simply using
@@ -325,8 +337,8 @@ activate themselves.
// external contracts.
// 1. Conditions
- require(now >= auctionEnd); // auction did not yet end
- require(!ended); // this function has already been called
+ require(now >= auctionEnd, "Auction not yet ended.");
+ require(!ended, "auctionEnd has already been called.");
// 2. Effects
ended = true;
@@ -376,7 +388,7 @@ high or low invalid bids.
::
- pragma solidity ^0.4.21;
+ pragma solidity ^0.4.22;
contract BlindAuction {
struct Bid {
@@ -529,7 +541,7 @@ Safe Remote Purchase
::
- pragma solidity ^0.4.21;
+ pragma solidity ^0.4.22;
contract Purchase {
uint public value;
@@ -544,7 +556,7 @@ Safe Remote Purchase
function Purchase() public payable {
seller = msg.sender;
value = msg.value / 2;
- require((2 * value) == msg.value);
+ require((2 * value) == msg.value, "Value has to be even.");
}
modifier condition(bool _condition) {
@@ -553,17 +565,26 @@ Safe Remote Purchase
}
modifier onlyBuyer() {
- require(msg.sender == buyer);
+ require(
+ msg.sender == buyer,
+ "Only buyer can call this."
+ );
_;
}
modifier onlySeller() {
- require(msg.sender == seller);
+ require(
+ msg.sender == seller,
+ "Only seller can call this."
+ );
_;
}
modifier inState(State _state) {
- require(state == _state);
+ require(
+ state == _state,
+ "Invalid state."
+ );
_;
}
diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst
index df40b1d0..d57f1703 100644
--- a/docs/structure-of-a-contract.rst
+++ b/docs/structure-of-a-contract.rst
@@ -62,13 +62,16 @@ Function modifiers can be used to amend the semantics of functions in a declarat
::
- pragma solidity ^0.4.11;
+ pragma solidity ^0.4.22;
contract Purchase {
address public seller;
modifier onlySeller() { // Modifier
- require(msg.sender == seller);
+ require(
+ msg.sender == seller,
+ "Only seller can call this."
+ );
_;
}
diff --git a/docs/style-guide.rst b/docs/style-guide.rst
index 2261746f..ee1ea4bd 100644
--- a/docs/style-guide.rst
+++ b/docs/style-guide.rst
@@ -904,7 +904,7 @@ Constants
=========
Constants should be named with all capital letters with underscores separating
-words. Examples: ``MAX_BLOCKS``, `TOKEN_NAME`, ``TOKEN_TICKER``, ``CONTRACT_VERSION``.
+words. Examples: ``MAX_BLOCKS``, ``TOKEN_NAME``, ``TOKEN_TICKER``, ``CONTRACT_VERSION``.
Modifier Names
diff --git a/docs/types.rst b/docs/types.rst
index e704687e..5c20dc67 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -81,7 +81,7 @@ Fixed Point Numbers
``fixed`` / ``ufixed``: Signed and unsigned fixed point number of various sizes. Keywords ``ufixedMxN`` and ``fixedMxN``, where ``M`` represents the number of bits taken by
the type and ``N`` represents how many decimal points are available. ``M`` must be divisible by 8 and goes from 8 to 256 bits. ``N`` must be between 0 and 80, inclusive.
-``ufixed`` and ``fixed`` are aliases for ``ufixed128x19`` and ``fixed128x19``, respectively.
+``ufixed`` and ``fixed`` are aliases for ``ufixed128x18`` and ``fixed128x18``, respectively.
Operators:
@@ -179,8 +179,8 @@ All three functions ``call``, ``delegatecall`` and ``callcode`` are very low-lev
The ``.gas()`` option is available on all three methods, while the ``.value()`` option is not supported for ``delegatecall``.
.. note::
- All contracts inherit the members of address, so it is possible to query the balance of the
- current contract using ``this.balance``.
+ All contracts can be converted to ``address`` type, so it is possible to query the balance of the
+ current contract using ``address(this).balance``.
.. note::
The use of ``callcode`` is discouraged and will be removed in the future.
@@ -470,7 +470,7 @@ Example that shows how to use internal function types::
Another example that uses external function types::
- pragma solidity ^0.4.21;
+ pragma solidity ^0.4.22;
contract Oracle {
struct Request {
@@ -495,7 +495,10 @@ Another example that uses external function types::
oracle.query("USD", this.oracleResponse);
}
function oracleResponse(bytes response) public {
- require(msg.sender == address(oracle));
+ require(
+ msg.sender == address(oracle),
+ "Only oracle can call this."
+ );
// Use the data
}
}
diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst
index 1b58b1e8..51f7b9f3 100644
--- a/docs/units-and-global-variables.rst
+++ b/docs/units-and-global-variables.rst
@@ -44,15 +44,16 @@ Special Variables and Functions
===============================
There are special variables and functions which always exist in the global
-namespace and are mainly used to provide information about the blockchain.
+namespace and are mainly used to provide information about the blockchain
+or are general-use utility functions.
-.. index:: block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, now, gas price, origin
+.. index:: abi, block, coinbase, difficulty, encode, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, now, gas price, origin
Block and Transaction Properties
--------------------------------
-- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks excluding current
+- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by ``blockhash(uint blockNumber)``.
- ``block.coinbase`` (``address``): current block miner's address
- ``block.difficulty`` (``uint``): current block difficulty
- ``block.gaslimit`` (``uint``): current block gaslimit
@@ -74,7 +75,7 @@ Block and Transaction Properties
This includes calls to library functions.
.. note::
- Do not rely on ``block.timestamp``, ``now`` and ``block.blockhash`` as a source of randomness,
+ Do not rely on ``block.timestamp``, ``now`` and ``blockhash`` as a source of randomness,
unless you know what you are doing.
Both the timestamp and the block hash can be influenced by miners to some degree.
@@ -90,6 +91,26 @@ Block and Transaction Properties
You can only access the hashes of the most recent 256 blocks, all other
values will be zero.
+.. index:: abi, encoding, packed
+
+ABI Encoding Functions
+----------------------
+
+- ``abi.encode(...) returns (bytes)``: ABI-encodes the given arguments
+- ``abi.encodePacked(...) returns (bytes)``: Performes packed encoding of the given arguments
+- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: ABI-encodes the given arguments
+ starting from the second and prepends the given four-byte selector
+- ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(signature), ...)```
+
+.. note::
+ These encoding functions can be used to craft data for function calls without actually
+ calling a function. Furthermore, ``keccak256(abi.encodePacked(a, b))`` is a more
+ explicit way to compute ``keccak256(a, b)``, which will be deprecated in future
+ versions.
+
+See the documentation about the :ref:`ABI <ABI>` and the
+:ref:`tightly packed encoding <abi_packed_mode>` for details about the encoding.
+
.. index:: assert, revert, require
Error Handling
@@ -99,8 +120,12 @@ Error Handling
throws if the condition is not met - to be used for internal errors.
``require(bool condition)``:
throws if the condition is not met - to be used for errors in inputs or external components.
+``require(bool condition, string message)``:
+ throws if the condition is not met - to be used for errors in inputs or external components. Also provides an error message.
``revert()``:
abort execution and revert state changes
+``revert(string reason)``:
+ abort execution and revert state changes, providing an explanatory string
.. index:: keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography,
@@ -169,6 +194,13 @@ For more information, see the section on :ref:`address`.
Use a pattern where the recipient withdraws the money.
.. note::
+ If storage variables are accessed via a low-level delegatecall, the storage layout of the two contracts
+ must align in order for the called contract to correctly access the storage variables of the calling contract by name.
+ This is of course not the case if storage pointers are passed as function arguments as in the case for
+ the high-level libraries.
+
+
+.. note::
The use of ``callcode`` is discouraged and will be removed in the future.
.. index:: this, selfdestruct
@@ -183,7 +215,7 @@ Contract Related
destroy the current contract, sending its funds to the given :ref:`address`
``suicide(address recipient)``:
- alias to ``selfdestruct``
+ deprecated alias to ``selfdestruct``
Furthermore, all functions of the current contract are callable directly including the current function.