diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/050-breaking-changes.rst | 12 | ||||
-rw-r--r-- | docs/abi-spec.rst | 2 | ||||
-rw-r--r-- | docs/assembly.rst | 10 | ||||
-rw-r--r-- | docs/contracts.rst | 121 | ||||
-rw-r--r-- | docs/contributing.rst | 5 | ||||
-rw-r--r-- | docs/control-structures.rst | 2 | ||||
-rw-r--r-- | docs/frequently-asked-questions.rst | 2 | ||||
-rw-r--r-- | docs/installing-solidity.rst | 6 | ||||
-rw-r--r-- | docs/introduction-to-smart-contracts.rst | 7 | ||||
-rw-r--r-- | docs/miscellaneous.rst | 29 | ||||
-rw-r--r-- | docs/solidity-by-example.rst | 2 | ||||
-rw-r--r-- | docs/types.rst | 3 | ||||
-rw-r--r-- | docs/using-the-compiler.rst | 18 | ||||
-rw-r--r-- | docs/yul.rst | 12 |
14 files changed, 163 insertions, 68 deletions
diff --git a/docs/050-breaking-changes.rst b/docs/050-breaking-changes.rst index 9094000e..7b227297 100644 --- a/docs/050-breaking-changes.rst +++ b/docs/050-breaking-changes.rst @@ -154,6 +154,18 @@ Command Line and JSON Interfaces * The JSON AST fields ``constant`` and ``payable`` were removed. The information is now present in the ``stateMutability`` field. +* The JSON AST field ``isConstructor`` of the ``FunctionDefinition`` + node was replaced by a field called ``kind`` which can have the + value ``"constructor"``, ``"fallback"`` or ``"function"``. + +* In unlinked binary hex files, library address placeholders are now + the first 36 hex characters of the keccak256 hash of the fully qualified + library name, surrounded by ``$...$``. Previously, + just the fully qualified library name was used. + This recudes the chances of collisions, especially when long paths are used. + Binary files now also contain a list of mappings from these placeholders + to the fully qualified names. + Constructors ------------ diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index f31d9d45..2c206dad 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -405,6 +405,8 @@ Offset ``f`` points to the start of the content of the array ``[[1, 2], [3]]`` w Offset ``g`` points to the start of the content of the array ``["one", "two", "three"]`` which is line 10 (320 bytes); thus ``g = 0x0000000000000000000000000000000000000000000000000000000000000140``. +.. _abi_events: + Events ====== diff --git a/docs/assembly.rst b/docs/assembly.rst index 20fb0cd5..5bb9825a 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -282,14 +282,14 @@ In the grammar, opcodes are represented as pre-defined identifiers. +-------------------------+-----+---+-----------------------------------------------------------------+ | extcodehash(a) | | C | code hash of address a | +-------------------------+-----+---+-----------------------------------------------------------------+ -| create(v, p, s) | | F | create new contract with code mem[p...(p+s)) and send v wei | +| create(v, p, n) | | F | create new contract with code mem[p...(p+n)) 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(0xff . self . n . keccak256(mem[p...(p+s))) | +| create2(v, p, n, s) | | C | create new contract with code mem[p...(p+n)) at address | +| | | | keccak256(0xff . this . s . keccak256(mem[p...(p+n))) | | | | | and send v wei and return the new address, where ``0xff`` is a | -| | | | 8 byte value, ``self`` is the current contract's address | -| | | | as a 20 byte value and ``n`` is a big-endian 256-bit value | +| | | | 8 byte value, ``this`` is the current contract's address | +| | | | as a 20 byte value and ``s`` is a big-endian 256-bit value | +-------------------------+-----+---+-----------------------------------------------------------------+ | 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 | diff --git a/docs/contracts.rst b/docs/contracts.rst index be89727d..d4160eac 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -31,6 +31,11 @@ When a contract is created, its constructor_ (a function declared with the ``co A constructor is optional. Only one constructor is allowed, which means overloading is not supported. +After the constructor has executed, the final code of the contract is deployed to the +blockchain. This code includes all public and external functions and all functions +that are reachable from there through function calls. The deployed code does not +include the constructor code or internal functions only called from the constructor. + .. index:: constructor;arguments Internally, constructor arguments are passed :ref:`ABI encoded <ABI>` after the code of @@ -485,7 +490,11 @@ Functions can be declared ``view`` in which case they promise not to modify the .. note:: If the compiler's EVM target is Byzantium or newer (default) the opcode ``STATICCALL`` is used for ``view`` functions which enforces the state - to stay unmodified as part of the EVM execution. + to stay unmodified as part of the EVM execution. For library ``view`` functions + ``DELEGATECALL`` is used, because there is no combined ``DELEGATECALL`` and ``STATICCALL``. + This means library ``view`` functions do not have run-time checks that prevent state + modifications. This should not impact security negatively because library code is + usually known at compile-time and the static checker performs compile-time checks. The following statements are considered modifying the state: @@ -756,39 +765,60 @@ converted to ``uint8``. Events ****** -Events allow the convenient usage of the EVM logging facilities, -which in turn can be used to "call" JavaScript callbacks in the user interface -of a dapp, which listen for these events. +Solidity events give an abstraction on top of the EVM's logging functionality. +Applications can subscribe and listen to these events through the RPC interface of an Ethereum client. -Events are -inheritable members of contracts. When they are called, they cause the +Events are inheritable members of contracts. When you call them, they cause the arguments to be stored in the transaction's log - a special data structure -in the blockchain. These logs are associated with the address of -the contract and will be incorporated into the blockchain -and stay there as long as a block is accessible (forever as of -Frontier and Homestead, but this might change with Serenity). Log and -event data is not accessible from within contracts (not even from -the contract that created them). - -"Simple payment verification" (SPV) proofs for logs are possible, so if an external entity supplies -a contract with such a proof, it can check that the log actually -exists inside the blockchain. Be aware that block headers have to be supplied because -the contract can only see the last 256 block hashes. - -Up to three parameters can -receive the attribute ``indexed`` which will cause the respective arguments -to be stored in a special data structure as so-called "topics", which allows them to be searched for, -for example when filtering a sequence of blocks for certain events. Events can always -be filtered by the address of the contract that emitted the event. Also, -the hash of the signature of the event is one of the topics except if you -declared the event with ``anonymous`` specifier. This means that it is -not possible to filter for specific anonymous events by name. +in the blockchain. These logs are associated with the address of the contract, +are incorporated into the blockchain, and stay there as long as a block is +accessible (forever as of the Frontier and Homestead releases, but this might +change with Serenity). The Log and its event data is not accessible from within +contracts (not even from the contract that created them). + +It is possible to request a simple payment verification (SPV) for logs, so if +an external entity supplies a contract with such a verification, it can check +that the log actually exists inside the blockchain. You have to supply block headers +because the contract can only see the last 256 block hashes. + +You can add the attribute ``indexed`` to up to three parameters which adds them +to a special data structure known as :ref:`"topics" <abi_events>` instead of +the data part of the log. If you use arrays (including ``string`` and ``bytes``) +as indexed arguments, its Keccak-256 hash is stored as a topic instead, this is +because a topic can only hold a single word (32 bytes). + +All parameters without the ``indexed`` attribute are :ref:`ABI-encoded <ABI>` +into the data part of the log. + +Topics allow you to search for events, for example when filtering a sequence of +blocks for certain events. You can also filter events by the address of the +contract that emitted the event. + +For example, the code below uses the web3.js ``subscribe("logs")`` +`method <https://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html#subscribe-logs>`_ to filter +logs that match a topic with a certain address value: + +.. code-block:: javascript + + var options = { + fromBlock: 0, + address: web3.eth.defaultAccount, + topics: ["0x0000000000000000000000000000000000000000000000000000000000000000", null, null] + }; + web3.eth.subscribe('logs', options, function (error, result) { + if (!error) + console.log(result); + }) + .on("data", function (log) { + console.log(log); + }) + .on("changed", function (log) { + }); -If arrays (including ``string`` and ``bytes``) are used as indexed arguments, the -Keccak-256 hash of it is stored as topic instead. This is because a topic -can only hold a single word (32 bytes). -All non-indexed arguments will be :ref:`ABI-encoded <ABI>` into the data part of the log. +The hash of the signature of the event is one of the topics, except if you +declared the event with the ``anonymous`` specifier. This means that it is +not possible to filter for specific anonymous events by name. :: @@ -811,7 +841,7 @@ All non-indexed arguments will be :ref:`ABI-encoded <ABI>` into the data part of } } -The use in the JavaScript API would be as follows: +The use in the JavaScript API is as follows: :: @@ -823,19 +853,35 @@ The use in the JavaScript API would be as follows: // watch for changes event.watch(function(error, result){ - // result will contain various information - // including the arguments given to the `Deposit` - // call. + // result contains non-indexed arguments and topics + // given to the `Deposit` call. if (!error) console.log(result); }); + // Or pass a callback to start watching immediately var event = clientReceipt.Deposit(function(error, result) { if (!error) console.log(result); }); +The output of the above looks like the following (trimmed): + +.. code-block:: json + + { + "returnValues": { + "_from": "0x1111…FFFFCCCC", + "_id": "0x50…sd5adb20", + "_value": "0x420042" + }, + "raw": { + "data": "0x7f…91385", + "topics": ["0xfd4…b4ead7", "0x7f…1a91385"] + } + } + .. index:: ! log Low-Level Interface to Logs @@ -1048,8 +1094,13 @@ initialisation code. Before the constructor code is executed, state variables are initialised to their specified value if you initialise them inline, or zero if you do not. -After the constructor has run, the final code of the contract is returned. The deployment of +After the constructor has run, the final code of the contract is deployed +to the blockchain. The deployment of the code costs additional gas linear to the length of the code. +This code includes all functions that are part of the public interface +and all functions that are reachable from there through function calls. +It does not include the constructor code or internal functions that are +only called from the constructor. Constructor functions can be either ``public`` or ``internal``. If there is no constructor, the contract will assume the default constructor, which is diff --git a/docs/contributing.rst b/docs/contributing.rst index 361570a0..32696520 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -82,6 +82,11 @@ To run a basic set of tests that neither require ``aleth`` nor ``libz3``, run ``./scripts/soltest.sh --no-ipc --no-smt``. This script will run ``build/test/soltest`` internally. +.. note :: + + Those working in a Windows environment wanting to run the above basic sets without aleth or libz3 in Git Bash, you would have to do: ``./build/test/RelWithDebInfo/soltest.exe -- --no-ipc --no-smt``. + If you're running this in plain Command Prompt, use ``.\build\test\RelWithDebInfo\soltest.exe -- --no-ipc --no-smt``. + The option ``--no-smt`` disables the tests that require ``libz3`` and ``--no-ipc`` disables those that require ``aleth``. diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 80311a63..353bb61d 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -279,7 +279,7 @@ groupings of expressions. :: - pragma solidity >0.4.23 <0.5.0; + pragma solidity >0.4.23 <0.6.0; contract C { uint[] data; diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index a474f905..0f8b34f8 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -173,7 +173,7 @@ situation. If you do not want to throw, you can return a pair:: - pragma solidity >0.4.23 <0.5.0; + pragma solidity >0.4.23 <0.6.0; contract C { uint[] counters; diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 9d4be70d..f8de0e8d 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -245,12 +245,6 @@ you should fork Solidity and add your personal fork as a second remote: git remote add personal git@github.com:[username]/solidity.git -Solidity has git submodules. Ensure they are properly loaded: - -.. code-block:: bash - - git submodule update --init --recursive - External Dependencies --------------------- diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index f5d5f89e..c8a45d30 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -332,14 +332,15 @@ Transactions ============ A transaction is a message that is sent from one account to another -account (which might be the same or the special zero-account, see below). +account (which might be the same or empty, see below). It can include binary data (which is called "payload") and Ether. If the target account contains code, that code is executed and the payload is provided as input data. -If the target account is the zero-account (the account with the -address ``0``), the transaction creates a **new contract**. +If the target account is not set (the transaction does not have +a recipient or the recipient is set to ``null``), the transaction +creates a **new contract**. As already mentioned, the address of that contract is not the zero address but an address derived from the sender and its number of transactions sent (the "nonce"). The payload diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index 12603f2e..8cc52c8f 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -34,18 +34,20 @@ Statically-sized variables (everything except mapping and dynamically-sized arra The elements of structs and arrays are stored after each other, just as if they were given explicitly. +Mappings and Dynamic Arrays +=========================== + Due to their unpredictable size, mapping and dynamically-sized array types use a Keccak-256 hash computation to find the starting position of the value or the array data. These starting positions are always full stack slots. -The mapping or the dynamic array itself -occupies an (unfilled) slot in storage at some position ``p`` according to the above rule (or by -recursively applying this rule for mappings to mappings or arrays of arrays). For a dynamic array, this slot stores the number of elements in the array (byte arrays and strings are an exception here, see below). For a mapping, the slot is unused (but it is needed so that two equal mappings after each other will use a different hash distribution). -Array data is located at ``keccak256(p)`` and the value corresponding to a mapping key +The mapping or the dynamic array itself occupies a slot in storage at some position ``p`` +according to the above rule (or by recursively applying this rule for mappings of mappings or arrays of arrays). For dynamic arrays, +this slot stores the number of elements in the array (byte arrays and strings are an exception, see :ref:`below <bytes-and-string>`). +For mappings, the slot is unused (but it is needed so that two equal mappings after each other will use a different +hash distribution). Array data is located at ``keccak256(p)`` and the value corresponding to a mapping key ``k`` is located at ``keccak256(k . p)`` where ``.`` is concatenation. If the value is again a non-elementary type, the positions are found by adding an offset of ``keccak256(k . p)``. -``bytes`` and ``string`` store their data in the same slot where also the length is stored if they are short. In particular: If the data is at most ``31`` bytes long, it is stored in the higher-order bytes (left aligned) and the lowest-order byte stores ``length * 2``. If it is longer, the main slot stores ``length * 2 + 1`` and the data is stored as usual in ``keccak256(slot)``. - So for the following contract snippet:: pragma solidity >=0.4.0 <0.6.0; @@ -58,6 +60,21 @@ So for the following contract snippet:: The position of ``data[4][9].b`` is at ``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1``. +.. _bytes-and-string: + +``bytes`` and ``string`` +------------------------ + +``bytes`` and ``string`` are encoded identically. For short byte arrays, they store their data in the same +slot where the length is also stored. In particular: if the data is at most ``31`` bytes long, it is stored +in the higher-order bytes (left aligned) and the lowest-order byte stores ``length * 2``. +For byte arrays that store data which is ``32`` or more bytes long, the main slot stores ``length * 2 + 1`` and the data is +stored as usual in ``keccak256(slot)``. This means that you can distinguish a short array from a long array +by checking if the lowest bit is set: short (not set) and long (set). + +.. note:: + Handling invalidly encoded slots is currently not supported but may be added in the future. + .. index: memory layout **************** diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst index 1bbd42f8..8f58f339 100644 --- a/docs/solidity-by-example.rst +++ b/docs/solidity-by-example.rst @@ -389,7 +389,7 @@ high or low invalid bids. :: - pragma solidity >0.4.23 <0.5.0; + pragma solidity >0.4.23 <0.6.0; contract BlindAuction { struct Bid { diff --git a/docs/types.rst b/docs/types.rst index 50a2dc60..bd5d1734 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -458,6 +458,7 @@ a non-rational number). uint128 b = 2.5 + a + 0.5; .. index:: literal, literal;string, string +.. _string_literals: String Literals --------------- @@ -501,7 +502,7 @@ Hexadecimal Literals Hexadecimal literals are prefixed with the keyword ``hex`` and are enclosed in double or single-quotes (``hex"001122FF"``). Their content must be a hexadecimal string and their value will be the binary representation of those values. -Hexadecimal literals behave like string literals and have the same convertibility restrictions. +Hexadecimal literals behave like :ref:`string literals <string_literals>` and have the same convertibility restrictions. .. index:: enum diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 39520bec..9ba6caa5 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -41,14 +41,26 @@ If there are multiple matches due to remappings, the one with the longest common For security reasons the compiler has restrictions what directories it can access. Paths (and their subdirectories) of source files specified on the commandline and paths defined by remappings are allowed for import statements, but everything else is rejected. Additional paths (and their subdirectories) can be allowed via the ``--allow-paths /sample/path,/another/sample/path`` switch. -If your contracts use :ref:`libraries <libraries>`, you will notice that the bytecode contains substrings of the form ``__LibraryName______``. You can use ``solc`` as a linker meaning that it will insert the library addresses for you at those points: +If your contracts use :ref:`libraries <libraries>`, you will notice that the bytecode contains substrings of the form ``__$53aea86b7d70b31448b230b20ae141a537$__``. These are placeholders for the actual library addresses. +The placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library name. +The bytecode file will also contain lines of the form ``// <placeholder> -> <fq library name>`` at the end to help +identify which libraries the placeholders represent. Note that the fully qualified library name +is the path of its source file and the library name separated by ``:``. +You can use ``solc`` as a linker meaning that it will insert the library addresses for you at those points: -Either add ``--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456"`` to your command to provide an address for each library or store the string in a file (one library per line) and run ``solc`` using ``--libraries fileName``. +Either add ``--libraries "file.sol:Math:0x1234567890123456789012345678901234567890 file.sol:Heap:0xabCD567890123456789012345678901234567890"`` to your command to provide an address for each library or store the string in a file (one library per line) and run ``solc`` using ``--libraries fileName``. -If ``solc`` is called with the option ``--link``, all input files are interpreted to be unlinked binaries (hex-encoded) in the ``__LibraryName____``-format given above and are linked in-place (if the input is read from stdin, it is written to stdout). All options except ``--libraries`` are ignored (including ``-o``) in this case. +If ``solc`` is called with the option ``--link``, all input files are interpreted to be unlinked binaries (hex-encoded) in the ``__$53aea86b7d70b31448b230b20ae141a537$__``-format given above and are linked in-place (if the input is read from stdin, it is written to stdout). All options except ``--libraries`` are ignored (including ``-o``) in this case. If ``solc`` is called with the option ``--standard-json``, it will expect a JSON input (as explained below) on the standard input, and return a JSON output on the standard output. This is the recommended interface for more complex and especially automated uses. +.. note:: + The library placeholder used to be the fully qualified name of the library itself + instead of the hash of it. This format is still supported by ``solc --link`` but + the compiler will no longer output it. This change was made to reduce + the likelihood of a collision between libraries, since only the first 36 characters + of the fully qualified library name could be used. + .. _evm-version: .. index:: ! EVM version, compile target diff --git a/docs/yul.rst b/docs/yul.rst index cfeec4db..9e9fac8e 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -44,7 +44,7 @@ and ``mod`` are available either natively or as functions and computes exponenti switch exponent case 0:u256 { result := 1:u256 } case 1:u256 { result := base } - default: + default { result := power(mul(base, base), div(exponent, 2:u256)) switch mod(exponent, 2:u256) @@ -415,14 +415,14 @@ The following functions must be available: +---------------------------------------------+-----------------------------------------------------------------+ | *Execution control* | +---------------------------------------------+-----------------------------------------------------------------+ -| create(v:u256, p:u256, s:u256) | create new contract with code mem[p..(p+s)) and send v wei | +| create(v:u256, p:u256, n:u256) | create new contract with code mem[p..(p+n)) and send v wei | | | and return the new address | +---------------------------------------------+-----------------------------------------------------------------+ -| create2(v:u256, n:u256, p:u256, s:u256) | create new contract with code mem[p...(p+s)) at address | -| | keccak256(0xff . self . n . keccak256(mem[p...(p+s))) | +| create2(v:u256, p:u256, n:u256, s:u256) | create new contract with code mem[p...(p+n)) at address | +| | keccak256(0xff . this . s . keccak256(mem[p...(p+n))) | | | and send v wei and return the new address, where ``0xff`` is a | -| | 8 byte value, ``self`` is the current contract's address | -| | as a 20 byte value and ``n`` is a big-endian 256-bit value | +| | 8 byte value, ``this`` is the current contract's address | +| | as a 20 byte value and ``s`` is a big-endian 256-bit value | +---------------------------------------------+-----------------------------------------------------------------+ | 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 | |