diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/abi-spec.rst | 19 | ||||
| -rw-r--r-- | docs/assembly.rst | 16 | ||||
| -rw-r--r-- | docs/bugs.json | 9 | ||||
| -rw-r--r-- | docs/bugs_by_version.json | 42 | ||||
| -rw-r--r-- | docs/contracts.rst | 37 | ||||
| -rw-r--r-- | docs/control-structures.rst | 30 | ||||
| -rw-r--r-- | docs/frequently-asked-questions.rst | 33 | ||||
| -rw-r--r-- | docs/index.rst | 5 | ||||
| -rw-r--r-- | docs/installing-solidity.rst | 4 | ||||
| -rw-r--r-- | docs/layout-of-source-files.rst | 27 | ||||
| -rw-r--r-- | docs/miscellaneous.rst | 7 | ||||
| -rw-r--r-- | docs/security-considerations.rst | 13 | ||||
| -rw-r--r-- | docs/solidity-by-example.rst | 21 | ||||
| -rw-r--r-- | docs/types.rst | 41 | ||||
| -rw-r--r-- | docs/units-and-global-variables.rst | 15 |
15 files changed, 211 insertions, 108 deletions
diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index e39c8861..2cf57427 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -6,14 +6,14 @@ Application Binary Interface Specification ****************************************** -Basic design +Basic Design ============ The Application Binary Interface is the standard way to interact with contracts in the Ethereum ecosystem, both -from outside the blockchain and for contract-to-contract interaction. Data is encoded following its type, -according to this specification. +from outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type, +as described in this specification. The encoding is not self describing and thus requires a schema in order to decode. -We assume the Application Binary Interface (ABI) is strongly typed, known at compilation time and static. No introspection mechanism will be provided. We assert that all contracts will have the interface definitions of any contracts they call available at compile-time. +We assume the interface functions of a contract are strongly typed, known at compilation time and static. No introspection mechanism will be provided. We assume that all contracts will have the interface definitions of any contracts they call available at compile-time. This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. Should these cases become important they can be adequately handled as facilities built within the Ethereum ecosystem. @@ -58,7 +58,7 @@ The following (fixed-size) array type exists: - `<type>[M]`: a fixed-length array of the given fixed-length type. -The following non-fixed-size types exist: +The following non-fixed-size types exist: - `bytes`: dynamic sized byte sequence. @@ -93,6 +93,7 @@ We distinguish static and dynamic types. Static types are encoded in-place and d * `string` * `T[]` for any `T` * `T[k]` for any dynamic `T` and any `k > 0` +* `(T1,...,Tk)` if any `Ti` is dynamic for `1 <= i <= k` All other types are called "static". @@ -181,6 +182,8 @@ Given the contract: :: + pragma solidity ^0.4.0; + contract Foo { function bar(bytes3[2] xy) {} function baz(uint32 x, bool y) returns (bool r) { r = x > 32 || y; } @@ -313,6 +316,8 @@ For example, :: + pragma solidity ^0.4.0; + contract Test { function Test(){ b = 0x12345678901234567890123456789012; } event Event(uint indexed a, bytes32 b) @@ -334,10 +339,6 @@ would result in the JSON: "inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], "name":"Event2" }, { - "type":"event", - "inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], - "name":"Event2" - }, { "type":"function", "inputs": [{"name":"a","type":"uint256"}], "name":"foo", diff --git a/docs/assembly.rst b/docs/assembly.rst index 83643634..4e665b7e 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -92,7 +92,7 @@ you really know what you are doing. function sumAsm(uint[] _data) returns (uint o_sum) { for (uint i = 0; i < _data.length; ++i) { assembly { - o_sum := mload(add(add(_data, 0x20), mul(i, 0x20))) + o_sum := add(o_sum, mload(add(add(_data, 0x20), mul(i, 0x20)))) } } } @@ -110,7 +110,7 @@ these curly braces, the following can be used (see the later sections for more d - opcodes (in "instruction style"), e.g. ``mload sload dup1 sstore``, for a list see below - opcodes in functional style, e.g. ``add(1, mlod(0))`` - labels, e.g. ``name:`` - - variable declarations, e.g. ``let x := 7`` or ``let x := add(y, 3)`` + - variable declarations, e.g. ``let x := 7``, ``let x := add(y, 3)`` or ``let x`` (initial value of empty (0) is assigned) - identifiers (labels or assembly-local variables and externals if used as inline assembly), e.g. ``jump(name)``, ``3 x add`` - assignments (in "instruction style"), e.g. ``3 =: x`` - assignments in functional style, e.g. ``x := add(y, 3)`` @@ -490,7 +490,7 @@ is performed by replacing the variable's value on the stack by the new value. .. code:: - assembly { + { let v := 0 // functional-style assignment as part of variable declaration let g := add(v, 2) sload(10) @@ -509,7 +509,7 @@ case called ``default``. .. code:: - assembly { + { let x := 0 switch calldataload(4) case 0 { @@ -538,7 +538,7 @@ The following example computes the sum of an area in memory. .. code:: - assembly { + { let x := 0 for { let i := 0 } lt(i, 0x100) { i := add(i, 0x20) } { x := add(x, mload(i)) @@ -565,7 +565,7 @@ The following example implements the power function by square-and-multiply. .. code:: - assembly { + { function power(base, exponent) -> result { switch exponent case 0 { result := 1 } @@ -679,6 +679,8 @@ Example: We will follow an example compilation from Solidity to desugared assembly. We consider the runtime bytecode of the following Solidity program:: + pragma solidity ^0.4.0; + contract C { function f(uint x) returns (uint y) { y = 1; @@ -965,7 +967,7 @@ adjustment. Every time a new local variable is introduced, it is registered together with the current stack height. If a variable is accessed (either for copying its value or for assignment), the appropriate DUP or SWAP instruction is selected depending -on the difference bitween the current stack height and the +on the difference between the current stack height and the stack height at the point the variable was introduced. Pseudocode:: diff --git a/docs/bugs.json b/docs/bugs.json index a0c0e7c4..4fd73492 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,5 +1,12 @@ [ { + "name": "ECRecoverMalformedInput", + "summary": "The ecrecover() builtin can return garbage for malformed input.", + "description": "The ecrecover precompile does not properly signal failure for malformed input (especially in the 'v' argument) and thus the Solidity function can return data that was previously present in the return area in memory.", + "fixed": "0.4.14", + "severity": "medium" + }, + { "name": "SkipEmptyStringLiteral", "summary": "If \"\" is used in a function call, the following function arguments will not be correctly passed to the function.", "description": "If the empty string literal \"\" is used as an argument in a function call, it is skipped by the encoder. This has the effect that the encoding of all arguments following this is shifted left by 32 bytes and thus the function call data is corrupted.", @@ -107,4 +114,4 @@ "severity": "high", "fixed": "0.3.0" } -]
\ No newline at end of file +] diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index d6802eec..1a5b4f5f 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1,6 +1,7 @@ { "0.1.0": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -16,6 +17,7 @@ }, "0.1.1": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -31,6 +33,7 @@ }, "0.1.2": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -46,6 +49,7 @@ }, "0.1.3": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -61,6 +65,7 @@ }, "0.1.4": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -76,6 +81,7 @@ }, "0.1.5": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -91,6 +97,7 @@ }, "0.1.6": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -107,6 +114,7 @@ }, "0.1.7": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -123,6 +131,7 @@ }, "0.2.0": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -139,6 +148,7 @@ }, "0.2.1": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -155,6 +165,7 @@ }, "0.2.2": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -171,6 +182,7 @@ }, "0.3.0": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -186,6 +198,7 @@ }, "0.3.1": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -200,6 +213,7 @@ }, "0.3.2": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -214,6 +228,7 @@ }, "0.3.3": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -227,6 +242,7 @@ }, "0.3.4": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -240,6 +256,7 @@ }, "0.3.5": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -253,6 +270,7 @@ }, "0.3.6": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -264,6 +282,7 @@ }, "0.4.0": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -275,6 +294,7 @@ }, "0.4.1": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -286,6 +306,7 @@ }, "0.4.10": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction" ], @@ -293,20 +314,30 @@ }, "0.4.11": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral" ], "released": "2017-05-03" }, "0.4.12": { - "bugs": [], + "bugs": [ + "ECRecoverMalformedInput" + ], "released": "2017-07-03" }, "0.4.13": { - "bugs": [], + "bugs": [ + "ECRecoverMalformedInput" + ], "released": "2017-07-06" }, + "0.4.14": { + "bugs": [], + "released": "2017-07-31" + }, "0.4.2": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -317,6 +348,7 @@ }, "0.4.3": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -326,6 +358,7 @@ }, "0.4.4": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored" @@ -334,6 +367,7 @@ }, "0.4.5": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored", @@ -343,6 +377,7 @@ }, "0.4.6": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction", "IdentityPrecompileReturnIgnored" @@ -351,6 +386,7 @@ }, "0.4.7": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction" ], @@ -358,6 +394,7 @@ }, "0.4.8": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction" ], @@ -365,6 +402,7 @@ }, "0.4.9": { "bugs": [ + "ECRecoverMalformedInput", "SkipEmptyStringLiteral", "ConstantOptimizerSubtraction" ], diff --git a/docs/contracts.rst b/docs/contracts.rst index e9ea1b3b..da797702 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -84,7 +84,7 @@ This means that cyclic creation dependencies are impossible. // State variables are accessed via their name // and not via e.g. this.owner. This also applies // to functions and especially in the constructors, - // you can only call them like that ("internall"), + // you can only call them like that ("internally"), // because the contract itself does not exist yet. owner = msg.sender; // We do an explicit type conversion from `address` @@ -213,6 +213,8 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value :: + // This will not compile + pragma solidity ^0.4.0; contract C { @@ -244,7 +246,7 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value } .. index:: ! getter;function, ! function;getter -.. _getter_functions: +.. _getter-functions: Getter Functions ================ @@ -545,9 +547,11 @@ Please ensure you test your fallback function thoroughly to ensure the execution test.call(0xabcdef01); // hash does not exist // results in test.x becoming == 1. - // The following call will fail, reject the - // Ether and return false: - test.send(2 ether); + // The following will not compile, but even + // if someone sends ether to that contract, + // the transaction will fail and reject the + // Ether. + //test.send(2 ether); } } @@ -773,13 +777,17 @@ seen in the following example:: pragma solidity ^0.4.0; + contract owned { + function owned() { owner = msg.sender; } + address owner; + } + contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } } - contract Base1 is mortal { function kill() { /* do cleanup 1 */ mortal.kill(); } } @@ -800,6 +808,11 @@ derived override, but this function will bypass pragma solidity ^0.4.0; + contract owned { + function owned() { owner = msg.sender; } + address owner; + } + contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); @@ -879,6 +892,8 @@ error "Linearization of inheritance graph impossible". :: + // This will not compile + pragma solidity ^0.4.0; contract X {} @@ -914,10 +929,16 @@ Contract functions can lack an implementation as in the following example (note function utterance() returns (bytes32); } -Such contracts cannot be compiled (even if they contain implemented functions alongside non-implemented functions), but they can be used as base contracts:: +Such contracts cannot be compiled (even if they contain +implemented functions alongside non-implemented functions), +but they can be used as base contracts:: pragma solidity ^0.4.0; + contract Feline { + function utterance() returns (bytes32); + } + contract Cat is Feline { function utterance() returns (bytes32) { return "miaow"; } } @@ -947,6 +968,8 @@ Interfaces are denoted by their own keyword: :: + pragma solidity ^0.4.11; + interface Token { function transfer(address recipient, uint amount); } diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 03787c20..a7af69f5 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -20,6 +20,8 @@ For example, suppose we want our contract to accept one kind of external calls with two integers, we would write something like:: + pragma solidity ^0.4.0; + contract Simple { function taker(uint _a, uint _b) { // do something with _a and _b. @@ -34,6 +36,8 @@ The output parameters can be declared with the same syntax after the the sum and the product of the two given integers, then we would write:: + pragma solidity ^0.4.0; + contract Simple { function arithmetics(uint _a, uint _b) returns (uint o_sum, uint o_product) { o_sum = _a + _b; @@ -91,6 +95,8 @@ Internal Function Calls Functions of the current contract can be called directly ("internally"), also recursively, as seen in this nonsensical example:: + pragma solidity ^0.4.0; + contract C { function g(uint a) returns (uint ret) { return f(); } function f() returns (uint ret) { return g(7) + f(); } @@ -116,11 +122,12 @@ all function arguments have to be copied to memory. When calling functions of other contracts, the amount of Wei sent with the call and the gas can be specified with special options ``.value()`` and ``.gas()``, respectively:: + pragma solidity ^0.4.0; + contract InfoFeed { function info() payable returns (uint ret) { return 42; } } - contract Consumer { InfoFeed feed; function setFeed(address addr) { feed = InfoFeed(addr); } @@ -173,7 +180,9 @@ parameters from the function declaration, but can be in arbitrary order. pragma solidity ^0.4.0; contract C { - function f(uint key, uint value) { ... } + function f(uint key, uint value) { + // ... + } function g() { // named arguments @@ -221,7 +230,6 @@ creation-dependencies are not possible. } } - contract C { D d = new D(4); // will be executed as part of C's constructor @@ -261,6 +269,8 @@ Destructuring Assignments and Returning Multiple Values Solidity internally allows tuple types, i.e. a list of objects of potentially different types whose size is a constant at compile-time. Those tuples can be used to return multiple values at the same time and also assign them to multiple variables (or LValues in general) at the same time:: + pragma solidity ^0.4.0; + contract C { uint[] data; @@ -313,6 +323,8 @@ 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``:: + // This will not compile + pragma solidity ^0.4.0; contract ScopingErrors { @@ -369,13 +381,11 @@ Error handling: Assert, Require, Revert and Exceptions Solidity uses state-reverting exceptions to handle errors. Such an exception will undo all changes made to the state in the current call (and all its sub-calls) and also flag an error to the caller. The convenience functions ``assert`` and ``require`` can be used to check for conditions and throw an exception -if the condition is not met. The difference between the two is that ``assert`` should only be used for internal errors -and ``require`` should be used to check external conditions (invalid inputs or errors in external components). -The idea behind that is that analysis tools can check your contract and try to come up with situations and -series of function calls that will reach a failing assertion. If this is possible, this means there is a bug -in your contract you should fix. +if the condition is not met. The ``assert`` function should only be used to test for internal errors, and to check invariants. +The ``require`` function should be used to ensure valid conditions, such as inputs, or contract state variables are met, or to validate return values from calls to external contracts. +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 execptions: The ``revert`` function can be used to flag an error and +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()``. @@ -429,4 +439,4 @@ Internally, Solidity performs a revert operation (instruction ``0xfd``) for a `` the EVM to revert all changes made to the state. The reason for reverting is that there is no safe way to continue execution, because an expected effect did not occur. Because we want to retain the atomicity of transactions, the safest thing to do is to revert all changes and make the whole transaction (or at least call) without effect. Note that ``assert``-style exceptions consume all gas available to the call, while -``revert``-style exceptions will not consume any gas starting from the Metropolis release.
\ No newline at end of file +``require``-style exceptions will not consume any gas starting from the Metropolis release. diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index 03ee8388..73210991 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -116,6 +116,8 @@ array in the return statement. Pretty cool, huh? Example:: + pragma solidity ^0.4.0; + contract C { function f() returns (uint8[5]) { string[4] memory adaArr = ["This", "is", "an", "array"]; @@ -192,6 +194,8 @@ should be noted that you must declare them as static memory arrays. Examples:: + pragma solidity ^0.4.0; + contract C { struct S { uint a; @@ -200,10 +204,9 @@ Examples:: S public x = S(1, 2); string name = "Ada"; - string[4] memory adaArr = ["This", "is", "an", "array"]; + string[4] adaArr = ["This", "is", "an", "array"]; } - contract D { C c = new C(); } @@ -243,6 +246,8 @@ which will be extended in the future. In addition, Arachnid has written `solidit For now, if you want to modify a string (even when you only want to know its length), you should always convert it to a ``bytes`` first:: + pragma solidity ^0.4.0; + contract C { string s; @@ -288,6 +293,8 @@ situation. If you do not want to throw, you can return a pair:: + pragma solidity ^0.4.0; + contract C { uint[] counters; @@ -302,9 +309,9 @@ If you do not want to throw, you can return a pair:: function checkCounter(uint index) { var (counter, error) = getCounter(index); if (error) { - ... + // ... } else { - ... + // ... } } } @@ -363,6 +370,8 @@ of variable it concerns: Example:: + pragma solidity ^0.4.0; + contract C { uint[] data1; uint[] data2; @@ -375,7 +384,7 @@ Example:: append(data2); } - function append(uint[] storage d) { + function append(uint[] storage d) internal { d.push(1); } } @@ -393,6 +402,9 @@ A common mistake is to declare a local variable and assume that it will be created in memory, although it will be created in storage:: /// THIS CONTRACT CONTAINS AN ERROR + + pragma solidity ^0.4.0; + contract C { uint someVariable; uint[] data; @@ -417,6 +429,8 @@ slot ``0``) is modified by ``x.push(2)``. The correct way to do this is the following:: + pragma solidity ^0.4.0; + contract C { uint someVariable; uint[] data; @@ -533,11 +547,12 @@ In the case of a ``contract A`` calling a new instance of ``contract B``, parent You will need to make sure that you have both contracts aware of each other's presence and that ``contract B`` has a ``payable`` constructor. In this example:: + pragma solidity ^0.4.0; + contract B { function B() payable {} } - contract A { address child; @@ -580,6 +595,8 @@ Can a contract pass an array (static size) or string or ``bytes`` (dynamic size) Sure. Take care that if you cross the memory / storage boundary, independent copies will be created:: + pragma solidity ^0.4.0; + contract C { uint[20] x; @@ -588,11 +605,11 @@ independent copies will be created:: h(x); } - function g(uint[20] y) { + function g(uint[20] y) internal { y[2] = 3; } - function h(uint[20] storage y) { + function h(uint[20] storage y) internal { y[3] = 4; } } diff --git a/docs/index.rst b/docs/index.rst index 3cdda62d..dea11a86 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -41,9 +41,6 @@ Available Solidity Integrations * `Remix <https://remix.ethereum.org/>`_ Browser-based IDE with integrated compiler and Solidity runtime environment without server-side components. -* `Ethereum Studio <https://live.ether.camp/>`_ - Specialized web IDE that also provides shell access to a complete Ethereum environment. - * `IntelliJ IDEA plugin <https://plugins.jetbrains.com/plugin/9475-intellij-solidity>`_ Solidity plugin for IntelliJ IDEA (and all other JetBrains IDEs) @@ -82,6 +79,8 @@ Discontinued: * `Mix IDE <https://github.com/ethereum/mix/>`_ Qt based IDE for designing, debugging and testing solidity smart contracts. +* `Ethereum Studio <https://live.ether.camp/>`_ + Specialized web IDE that also provides shell access to a complete Ethereum environment. Solidity Tools -------------- diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 9b5ba9f2..e07561c5 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -82,6 +82,10 @@ If you want to use the cutting edge developer version: sudo add-apt-repository ppa:ethereum/ethereum-dev sudo apt-get update sudo apt-get install solc + +We are also releasing a `snap package <https://snapcraft.io/>`_, which is installable in all the `supported Linux distros <https://snapcraft.io/docs/core/install>`_. To help testing the unstable solc with the most recent changes from the development branch: + + sudo snap install solc --edge Arch Linux also has packages, albeit limited to the latest development version: diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst index e4b403f6..f9d197b7 100644 --- a/docs/layout-of-source-files.rst +++ b/docs/layout-of-source-files.rst @@ -197,17 +197,16 @@ for the two input parameters and two returned values. pragma solidity ^0.4.0; - /** @title Shape calculator.*/ - contract shapeCalculator{ - /**@dev Calculates a rectangle's surface and perimeter. - * @param w Width of the rectangle. - * @param h Height of the rectangle. - * @return s The calculated surface. - * @return p The calculated perimeter. - */ - function rectangle(uint w, uint h) returns (uint s, uint p) { - s = w * h; - p = 2 * (w + h); - } - } - + /** @title Shape calculator. */ + contract shapeCalculator { + /** @dev Calculates a rectangle's surface and perimeter. + * @param w Width of the rectangle. + * @param h Height of the rectangle. + * @return s The calculated surface. + * @return p The calculated perimeter. + */ + function rectangle(uint w, uint h) returns (uint s, uint p) { + s = w * h; + p = 2 * (w + h); + } + } diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index 182de33a..e364bee7 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -48,6 +48,8 @@ non-elementary type, the positions are found by adding an offset of ``keccak256( So for the following contract snippet:: + pragma solidity ^0.4.0; + contract C { struct s { uint a; uint b; } uint x; @@ -467,7 +469,7 @@ Global Variables - ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component) - ``revert()``: abort execution and revert state changes - ``keccak256(...) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the (tightly packed) arguments -- ``sha3(...) returns (bytes32)``: an alias to `keccak256()` +- ``sha3(...) returns (bytes32)``: an alias to `keccak256` - ``sha256(...) returns (bytes32)``: compute the SHA-256 hash of the (tightly packed) arguments - ``ripemd160(...) returns (bytes20)``: compute the RIPEMD-160 hash of the (tightly packed) arguments - ``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 @@ -476,6 +478,7 @@ 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 recipieint)``: an 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 @@ -513,7 +516,7 @@ Reserved Keywords These keywords are reserved in Solidity. They might become part of the syntax in the future: -``abstract``, ``after``, ``case``, ``catch``, ``default``, ``final``, ``in``, ``inline``, ``interface``, ``let``, ``match``, ``null``, +``abstract``, ``after``, ``case``, ``catch``, ``default``, ``final``, ``in``, ``inline``, ``let``, ``match``, ``null``, ``of``, ``pure``, ``relocatable``, ``static``, ``switch``, ``try``, ``type``, ``typeof``, ``view``. Language Grammar diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index 33c613d8..6586cb5f 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -14,7 +14,7 @@ the source code is often available. Of course you always have to consider how much is at stake: You can compare a smart contract with a web service that is open to the -public (and thus, also to malicous actors) and perhaps even open source. +public (and thus, also to malicious actors) and perhaps even open source. If you only store your grocery list on that web service, you might not have to take too much care, but if you manage your bank account using that web service, you should be more careful. @@ -179,11 +179,13 @@ Never use tx.origin for authorization. Let's say you have a wallet contract like } } -Now someone tricks you into sending ether to the address of this attack wallet: +Now someone tricks you into sending ether to the address of this attack wallet:: -:: + pragma solidity ^0.4.11; - pragma solidity ^0.4.0; + interface TxUserWallet { + function transferTo(address dest, uint amount); + } contract TxAttackWallet { address owner; @@ -278,8 +280,7 @@ Formal Verification Using formal verification, it is possible to perform an automated mathematical proof that your source code fulfills a certain formal specification. The specification is still formal (just as the source code), but usually much -simpler. There is a prototype in Solidity that performs formal verification and -it will be better documented soon. +simpler. Note that formal verification itself can only help you understand the difference between what you did (the specification) and how you did it diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst index 450b0286..71d27192 100644 --- a/docs/solidity-by-example.rst +++ b/docs/solidity-by-example.rst @@ -101,7 +101,7 @@ of votes. /// Delegate your vote to the voter `to`. function delegate(address to) { // assigns reference - Voter sender = voters[msg.sender]; + Voter storage sender = voters[msg.sender]; require(!sender.voted); // Self-delegation is not allowed. @@ -141,7 +141,7 @@ of votes. /// Give your vote (including votes delegated to you) /// to proposal `proposals[proposal].name`. function vote(uint proposal) { - Voter sender = voters[msg.sender]; + Voter storage sender = voters[msg.sender]; require(!sender.voted); sender.voted = true; sender.vote = proposal; @@ -289,7 +289,7 @@ activate themselves. /// Withdraw a bid that was overbid. function withdraw() returns (bool) { - var amount = pendingReturns[msg.sender]; + uint amount = pendingReturns[msg.sender]; if (amount > 0) { // It is important to set this to zero because the recipient // can call this function again as part of the receiving call @@ -362,8 +362,8 @@ together with the bid. Since value transfers cannot be blinded in Ethereum, anyone can see the value. The following contract solves this problem by -accepting any value that is at least as large as -the bid. Since this can of course only be checked during +accepting any value that is larger than the highest +bid. Since this can of course only be checked during the reveal phase, some bids might be **invalid**, and this is on purpose (it even provides an explicit flag to place invalid bids with high value transfers): @@ -491,8 +491,8 @@ high or low invalid bids. } /// Withdraw a bid that was overbid. - function withdraw() returns (bool) { - var amount = pendingReturns[msg.sender]; + function withdraw() { + uint amount = pendingReturns[msg.sender]; if (amount > 0) { // It is important to set this to zero because the recipient // can call this function again as part of the receiving call @@ -500,13 +500,8 @@ high or low invalid bids. // conditions -> effects -> interaction). pendingReturns[msg.sender] = 0; - if (!msg.sender.send(amount)){ - // No need to call throw here, just reset the amount owing - pendingReturns[msg.sender] = amount; - return false; - } + msg.sender.transfer(amount); } - return true; } /// End the auction and send the highest bid diff --git a/docs/types.rst b/docs/types.rst index 319701c7..dd9c6269 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -135,6 +135,9 @@ The ``.gas()`` option is available on all three methods, while the ``.value()`` All contracts inherit the members of address, so it is possible to query the balance of the current contract using ``this.balance``. +.. note:: + The use of ``callcode`` is discouraged and will be removed in the future. + .. warning:: All these functions are low-level functions and should be used with care. Specifically, any unknown contract might be malicious and if you call it, you @@ -222,14 +225,6 @@ For example, ``(2**800 + 1) - 2**800`` results in the constant ``1`` (of type `` although intermediate results would not even fit the machine word size. Furthermore, ``.5 * 8`` results in the integer ``4`` (although non-integers were used in between). -If the result is not an integer, -an appropriate ``ufixed`` or ``fixed`` type is used whose number of fractional bits is as large as -required (approximating the rational number in the worst case). - -In ``var x = 1/4;``, ``x`` will receive the type ``ufixed0x8`` while in ``var x = 1/3`` it will receive -the type ``ufixed0x256`` because ``1/3`` is not finitely representable in binary and will thus be -approximated. - Any operator that can be applied to integers can also be applied to number literal expressions as long as the operands are integers. If any of the two is fractional, bit operations are disallowed and exponentiation is disallowed if the exponent is fractional (because that might result in @@ -243,20 +238,14 @@ a non-rational number). types. So the number literal expressions ``1 + 2`` and ``2 + 1`` both belong to the same number literal type for the rational number three. -.. note:: - Most finite decimal fractions like ``5.3743`` are not finitely representable in binary. The correct type - for ``5.3743`` is ``ufixed8x248`` because that allows to best approximate the number. If you want to - use the number together with types like ``ufixed`` (i.e. ``ufixed128x128``), you have to explicitly - specify the desired precision: ``x + ufixed(5.3743)``. - .. warning:: Division on integer literals used to truncate in earlier versions, but it will now convert into a rational number, i.e. ``5 / 2`` is not equal to ``2``, but to ``2.5``. .. note:: Number literal expressions are converted into a non-literal type as soon as they are used with non-literal expressions. Even though we know that the value of the - expression assigned to ``b`` in the following example evaluates to an integer, it still - uses fixed point types (and not rational number literals) in between and so the code + expression assigned to ``b`` in the following example evaluates to + an integer, but the partial expression ``2.5 + a`` does not type check so the code does not compile :: @@ -390,7 +379,7 @@ Example that shows how to use internal function types:: function (uint, uint) returns (uint) f ) internal - returns (uint) + returns (uint r) { r = self[0]; for (uint i = 1; i < self.length; i++) { @@ -450,7 +439,8 @@ Another example that uses external function types:: } } -Note that lambda or inline functions are planned but not yet supported. +.. note:: + Lambda or inline functions are planned but not yet supported. .. index:: ! type;reference, ! reference type, storage, memory, location, array, struct @@ -557,7 +547,7 @@ So ``bytes`` should always be preferred over ``byte[]`` because it is cheaper. that you are accessing the low-level bytes of the UTF-8 representation, and not the individual characters! -It is possible to mark arrays ``public`` and have Solidity create a getter. +It is possible to mark arrays ``public`` and have Solidity create a :ref:`getter <visibility-and-getters>`. The numeric index will become a required parameter for the getter. .. index:: ! array;allocating, new @@ -613,6 +603,8 @@ possible: :: + // This will not compile. + pragma solidity ^0.4.0; contract C { @@ -620,6 +612,7 @@ possible: // The next line creates a type error because uint[3] memory // cannot be converted to uint[] memory. uint[] x = [uint(1), 3, 4]; + } } It is planned to remove this restriction in the future but currently creates @@ -750,7 +743,7 @@ shown in the following example: } function contribute(uint campaignID) payable { - Campaign c = campaigns[campaignID]; + Campaign storage c = campaigns[campaignID]; // Creates a new temporary memory struct, initialised with the given values // and copies it over to storage. // Note that you can also use Funder(msg.sender, msg.value) to initialise. @@ -759,7 +752,7 @@ shown in the following example: } function checkGoalReached(uint campaignID) returns (bool reached) { - Campaign c = campaigns[campaignID]; + Campaign storage c = campaigns[campaignID]; if (c.amount < c.fundingGoal) return false; uint amount = c.amount; @@ -806,7 +799,7 @@ Because of this, mappings do not have a length or a concept of a key or value be Mappings are only allowed for state variables (or as storage reference types in internal functions). -It is possible to mark mappings ``public`` and have Solidity create a getter. +It is possible to mark mappings ``public`` and have Solidity create a :ref:`getter <visibility-and-getters>`. The ``_KeyType`` will become a required parameter for the getter and it will return ``_ValueType``. @@ -827,7 +820,9 @@ for each ``_KeyType``, recursively. contract MappingUser { function f() returns (uint) { - return MappingExample(<address>).balances(this); + MappingExample m = new MappingExample(); + m.update(100); + return m.balances(this); } } diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index 7d21f065..64795306 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -35,7 +35,9 @@ These suffixes cannot be applied to variables. If you want to interpret some input variable in e.g. days, you can do it in the following way:: function f(uint start, uint daysAfter) { - if (now >= start + daysAfter * 1 days) { ... } + if (now >= start + daysAfter * 1 days) { + // ... + } } Special Variables and Functions @@ -70,6 +72,7 @@ Block and Transaction Properties ``msg.value`` can change for every **external** function call. This includes calls to library functions. +.. note:: If you want to implement access restrictions in library functions using ``msg.sender``, you have to manually supply the value of ``msg.sender`` as an argument. @@ -102,10 +105,10 @@ Mathematical and Cryptographic Functions compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``. ``keccak256(...) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the (tightly packed) arguments -``sha3(...) returns (bytes32)``: - alias to ``keccak256()`` ``sha256(...) returns (bytes32)``: compute the SHA-256 hash of the (tightly packed) arguments +``sha3(...) returns (bytes32)``: + alias to ``keccak256`` ``ripemd160(...) returns (bytes20)``: compute RIPEMD-160 hash of the (tightly packed) arguments ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: @@ -157,6 +160,9 @@ For more information, see the section on :ref:`address`. to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better: Use a pattern where the recipient withdraws the money. +.. note:: + The use of ``callcode`` is discouraged and will be removed in the future. + .. index:: this, selfdestruct Contract Related @@ -168,5 +174,8 @@ Contract Related ``selfdestruct(address recipient)``: destroy the current contract, sending its funds to the given :ref:`address` +``suicide(address recipient)``: + alias to ``selfdestruct`` + Furthermore, all functions of the current contract are callable directly including the current function. |
