diff options
author | chriseth <chris@ethereum.org> | 2018-08-09 21:36:00 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2018-08-14 21:50:46 +0800 |
commit | 6cf299bec6b89b22d97e39d7db54f9dc4f652cfb (patch) | |
tree | c68420316cbbfb30522a13a5aeae7c716ea49d1a /docs | |
parent | f873389c6227d41dbba9ba4c23ed055f286ecb71 (diff) | |
download | dexon-solidity-6cf299bec6b89b22d97e39d7db54f9dc4f652cfb.tar dexon-solidity-6cf299bec6b89b22d97e39d7db54f9dc4f652cfb.tar.gz dexon-solidity-6cf299bec6b89b22d97e39d7db54f9dc4f652cfb.tar.bz2 dexon-solidity-6cf299bec6b89b22d97e39d7db54f9dc4f652cfb.tar.lz dexon-solidity-6cf299bec6b89b22d97e39d7db54f9dc4f652cfb.tar.xz dexon-solidity-6cf299bec6b89b22d97e39d7db54f9dc4f652cfb.tar.zst dexon-solidity-6cf299bec6b89b22d97e39d7db54f9dc4f652cfb.zip |
Update documentation examples.
Diffstat (limited to 'docs')
-rw-r--r-- | docs/abi-spec.rst | 4 | ||||
-rw-r--r-- | docs/assembly.rst | 18 | ||||
-rw-r--r-- | docs/common-patterns.rst | 2 | ||||
-rw-r--r-- | docs/contracts.rst | 53 | ||||
-rw-r--r-- | docs/control-structures.rst | 40 | ||||
-rw-r--r-- | docs/frequently-asked-questions.rst | 13 | ||||
-rw-r--r-- | docs/layout-of-source-files.rst | 2 | ||||
-rw-r--r-- | docs/solidity-by-example.rst | 10 | ||||
-rw-r--r-- | docs/structure-of-a-contract.rst | 2 | ||||
-rw-r--r-- | docs/types.rst | 41 |
10 files changed, 99 insertions, 86 deletions
diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 69bbe5c3..bf9b8fb7 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -494,8 +494,8 @@ As an example, the code contract Test { struct S { uint a; uint[] b; T[] c; } struct T { uint x; uint y; } - function f(S memory s, T memory t, uint a) public { } - function g() public returns (S memory s, T memory t, uint a) {} + function f(S memory s, T memory t, uint a) public; + function g() public returns (S memory s, T memory t, uint a); } would result in the JSON: diff --git a/docs/assembly.rst b/docs/assembly.rst index 91ba076a..2cbad06f 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -82,7 +82,7 @@ you really know what you are doing. library VectorSum { // This function is less efficient because the optimizer currently fails to // remove the bounds checks in array access. - function sumSolidity(uint[] memory _data) public view returns (uint o_sum) { + function sumSolidity(uint[] memory _data) public pure returns (uint o_sum) { for (uint i = 0; i < _data.length; ++i) o_sum += _data[i]; } @@ -90,7 +90,7 @@ you really know what you are doing. // We know that we only access the array in bounds, so we can avoid the check. // 0x20 needs to be added to an array because the first slot contains the // array length. - function sumAsm(uint[] memory _data) public view returns (uint o_sum) { + function sumAsm(uint[] memory _data) public pure returns (uint o_sum) { for (uint i = 0; i < _data.length; ++i) { assembly { o_sum := add(o_sum, mload(add(add(_data, 0x20), mul(i, 0x20)))) @@ -99,7 +99,7 @@ you really know what you are doing. } // Same as above, but accomplish the entire code within inline assembly. - function sumPureAsm(uint[] memory _data) public view returns (uint o_sum) { + function sumPureAsm(uint[] memory _data) public pure returns (uint o_sum) { assembly { // Load the length (first 32 bytes) let len := mload(_data) @@ -378,23 +378,13 @@ used ``x_slot`` and to retrieve the byte-offset you used ``x_offset``. In assignments (see below), we can even use local Solidity variables to assign to. -Functions external to inline assembly can also be accessed: The assembly will -push their entry label (with virtual function resolution applied). The calling semantics -in solidity are: - - - the caller pushes ``return label``, ``arg1``, ``arg2``, ..., ``argn`` - - the call returns with ``ret1``, ``ret2``, ..., ``retm`` - -This feature is still a bit cumbersome to use, because the stack offset essentially -changes during the call, and thus references to local variables will be wrong. - .. code:: pragma solidity ^0.4.11; contract C { uint b; - function f(uint x) public returns (uint r) { + function f(uint x) public view returns (uint r) { assembly { r := mul(x, sload(b_slot)) // ignore the offset, we know it is zero } diff --git a/docs/common-patterns.rst b/docs/common-patterns.rst index bc8286b2..6b061bf7 100644 --- a/docs/common-patterns.rst +++ b/docs/common-patterns.rst @@ -198,7 +198,7 @@ restrictions highly readable. ); _; if (msg.value > _amount) - msg.sender.send(msg.value - _amount); + msg.sender.transfer(msg.value - _amount); } function forceOwnerChange(address _newOwner) diff --git a/docs/contracts.rst b/docs/contracts.rst index e9ac1af7..7cf715fa 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -110,11 +110,11 @@ This means that cyclic creation dependencies are impossible. function isTokenTransferOK(address currentOwner, address newOwner) public - view + pure returns (bool ok) { // Check some arbitrary condition. - return currentOwner != newOwner; + return keccak256(abi.encodePacked(currentOwner, newOwner))[0] == 0x7f; } } @@ -187,8 +187,6 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value :: - // This will not compile - pragma solidity ^0.4.0; contract C { @@ -200,6 +198,7 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value function compute(uint a, uint b) internal pure returns (uint) { return a + b; } } + // This will not compile contract D { function readData() public { C c = new C(); @@ -227,8 +226,8 @@ The compiler automatically creates getter functions for all **public** state variables. For the contract given below, the compiler will generate a function called ``data`` that does not take any arguments and returns a ``uint``, the value of the state -variable ``data``. The initialization of state variables can -be done at declaration. +variable ``data``. State variables can be initialized +when they are declared. :: @@ -240,8 +239,8 @@ be done at declaration. contract Caller { C c = new C(); - function f() public { - uint local = c.data(); + function f() public view returns (uint) { + return c.data(); } } @@ -256,9 +255,9 @@ it is evaluated as a state variable. If it is accessed externally contract C { uint public data; - function x() public { + function x() public returns (uint) { data = 3; // internal access - uint val = this.data(); // external access + return this.data(); // external access } } @@ -615,14 +614,13 @@ Like any function, the fallback function can execute complex operations as long } contract Caller { - function callTest(Test test) public { - address(test).call(abi.encodeWithSignature("nonExistingFunction()")); + function callTest(Test test) public returns (bool) { + require(address(test).call(abi.encodeWithSignature("nonExistingFunction()"))); // results in test.x becoming == 1. // If someone sends ether to that contract, - // the transaction will fail and reject the - // Ether. - address(test).send(2 ether); + // the transfer will fail, i.e. this returns false here. + return address(test).send(2 ether); } } @@ -633,9 +631,11 @@ Like any function, the fallback function can execute complex operations as long Function Overloading ==================== -A Contract can have multiple functions of the same name but with different arguments. -This also applies to inherited functions. The following example shows overloading of the -``f`` function in the scope of contract ``A``. +A contract can have multiple functions of the same name but with different parameter +types. +This process is called "overloading" and also applies to inherited functions. +The following example shows overloading of the function +``f`` in the scope of contract ``A``. :: @@ -643,11 +643,12 @@ This also applies to inherited functions. The following example shows overloadin contract A { function f(uint _in) public pure returns (uint out) { - out = 1; + out = _in; } - function f(uint _in, bytes32 _key) public pure returns (uint out) { - out = 2; + function f(uint _in, bool _really) public pure returns (uint out) { + if (_really) + out = _in; } } @@ -656,9 +657,9 @@ externally visible functions differ by their Solidity types but not by their ext :: - // This will not compile pragma solidity ^0.4.16; + // This will not compile contract A { function f(B _in) public pure returns (B out) { out = _in; @@ -1037,10 +1038,12 @@ derived contracts need to specify all of them. This can be done in two ways:: constructor(uint _x) public { x = _x; } } + // Either directly specify in the inheritance list... contract Derived1 is Base(7) { - constructor(uint _y) public {} + constructor() public {} } + // or through a "modifier" of the derived constructor. contract Derived2 is Base { constructor(uint _y) Base(_y * _y) public {} } @@ -1079,12 +1082,11 @@ error "Linearization of inheritance graph impossible". :: - // This will not compile - pragma solidity ^0.4.0; contract X {} contract A is X {} + // This will not compile contract C is A, X {} The reason for this is that ``C`` requests ``X`` to override ``A`` @@ -1342,6 +1344,7 @@ custom types without the overhead of external function calls: BigInt.bigint memory x = BigInt.fromUint(7); BigInt.bigint memory y = BigInt.fromUint(uint(-1)); BigInt.bigint memory z = x.add(y); + assert(z.limb(1) > 0); } } diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 9fd017db..7efdc4e1 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -23,8 +23,9 @@ something like:: pragma solidity ^0.4.16; contract Simple { - function taker(uint _a, uint _b) public pure { - // do something with _a and _b. + uint sum; + function taker(uint _a, uint _b) public { + sum = _a + _b; } } @@ -102,7 +103,7 @@ this nonsensical example:: pragma solidity ^0.4.16; contract C { - function g(uint a) public pure returns (uint ret) { return f(); } + function g(uint a) public pure returns (uint ret) { return a + f(); } function f() internal pure returns (uint ret) { return g(7) + f(); } } @@ -184,14 +185,16 @@ parameters from the function declaration, but can be in arbitrary order. pragma solidity ^0.4.0; contract C { - function f(uint key, uint value) public { - // ... + mapping(uint => uint) data; + + function f() public { + set({value: 2, key: 3}); } - function g() public { - // named arguments - f({value: 2, key: 3}); + function set(uint key, uint value) public { + data[key] = value; } + } Omitted Function Parameter Names @@ -228,7 +231,7 @@ creation-dependencies are not possible. pragma solidity >0.4.24; contract D { - uint x; + uint public x; constructor(uint a) public payable { x = a; } @@ -239,11 +242,13 @@ creation-dependencies are not possible. function createD(uint arg) public { D newD = new D(arg); + newD.x(); } function createAndEndowD(uint arg, uint amount) public payable { // Send ether along with the creation D newD = (new D).value(amount)(arg); + newD.x(); } } @@ -287,12 +292,13 @@ These can then either be assigned to newly declared variables or to pre-existing } function g() public { - // Variables declared with type and assigned from the returned tuple. - (uint x, bool b, uint y) = f(); + // Variables declared with type and assigned from the returned tuple, + // not all elements have to be specified (but the amount must match). + (uint x, , uint 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). - (data.length,,) = f(); // Sets the length to 7 + (data.length, , ) = f(); // Sets the length to 7 } } @@ -338,11 +344,13 @@ the two variables have the same name but disjoint scopes. contract C { function minimalScoping() pure public { { - uint same2 = 0; + uint same; + same = 1; } { - uint same2 = 0; + uint same; + same = 3; } } } @@ -354,6 +362,7 @@ In any case, you will get a warning about the outer variable being shadowed. :: pragma solidity >0.4.24; + // This will report a warning contract C { function f() pure public returns (uint) { uint x = 1; @@ -372,9 +381,8 @@ In any case, you will get a warning about the outer variable being shadowed. :: - // This will not compile - pragma solidity >0.4.24; + // This will not compile contract C { function f() pure public returns (uint) { x = 2; diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index 786c3341..b26ff527 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -62,7 +62,8 @@ Example:: contract C { function f() public pure returns (uint8[5] memory) { string[4] memory adaArr = ["This", "is", "an", "array"]; - return ([1, 2, 3, 4, 5]); + adaArr[0] = "That"; + return [1, 2, 3, 4, 5]; } } @@ -186,9 +187,10 @@ If you do not want to throw, you can return a pair:: function checkCounter(uint index) public view { (uint counter, bool error) = getCounter(index); if (error) { - // ... + // Handle the error } else { - // ... + // Do something with counter. + require(counter > 7, "Invalid counter value"); } } } @@ -372,15 +374,14 @@ contract level) with ``arrayname.length = <some new length>;``. If you get the :: - // This will not compile - pragma solidity ^0.4.18; + // This will not compile contract C { int8[] dynamicStorageArray; int8[5] fixedStorageArray; - function f() { + function f() public { int8[] memory memArr; // Case 1 memArr.length++; // illegal diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst index 4bacd704..5cbb6cff 100644 --- a/docs/layout-of-source-files.rst +++ b/docs/layout-of-source-files.rst @@ -204,7 +204,7 @@ for the two input parameters and two returned values. * @return s The calculated surface. * @return p The calculated perimeter. */ - function rectangle(uint w, uint h) public returns (uint s, uint p) { + function rectangle(uint w, uint h) public pure returns (uint s, uint p) { s = w * h; p = 2 * (w + h); } diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst index 3f054297..7d325746 100644 --- a/docs/solidity-by-example.rst +++ b/docs/solidity-by-example.rst @@ -467,22 +467,22 @@ high or low invalid bids. uint refund; for (uint i = 0; i < length; i++) { - Bid storage bid = bids[msg.sender][i]; + Bid storage bidToCheck = bids[msg.sender][i]; (uint value, bool fake, bytes32 secret) = (_values[i], _fake[i], _secret[i]); - if (bid.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) { + if (bidToCheck.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) { // Bid was not actually revealed. // Do not refund deposit. continue; } - refund += bid.deposit; - if (!fake && bid.deposit >= value) { + refund += bidToCheck.deposit; + if (!fake && bidToCheck.deposit >= value) { if (placeBid(msg.sender, value)) refund -= value; } // Make it impossible for the sender to re-claim // the same deposit. - bid.blindedBid = bytes32(0); + bidToCheck.blindedBid = bytes32(0); } msg.sender.transfer(refund); } diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst index 7a6317eb..ae349055 100644 --- a/docs/structure-of-a-contract.rst +++ b/docs/structure-of-a-contract.rst @@ -75,7 +75,7 @@ Function modifiers can be used to amend the semantics of functions in a declarat _; } - function abort() public onlySeller { // Modifier usage + function abort() public view onlySeller { // Modifier usage // ... } } diff --git a/docs/types.rst b/docs/types.rst index 7e222bc1..2cb85387 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -447,7 +447,7 @@ which returns the :ref:`ABI function selector <abi_function_selector>`:: pragma solidity ^0.4.16; contract Selector { - function f() public view returns (bytes4) { + function f() public pure returns (bytes4) { return this.f.selector; } } @@ -510,15 +510,15 @@ Another example that uses external function types:: contract Oracle { struct Request { bytes data; - function(bytes memory) external callback; + function(uint) external callback; } Request[] requests; event NewRequest(uint); - function query(bytes memory data, function(bytes memory) external callback) public { + function query(bytes memory data, function(uint) external callback) public { requests.push(Request(data, callback)); emit NewRequest(requests.length - 1); } - function reply(uint requestID, bytes memory response) public { + function reply(uint requestID, uint response) public { // Here goes the check that the reply comes from a trusted source requests[requestID].callback(response); } @@ -526,15 +526,16 @@ Another example that uses external function types:: contract OracleUser { Oracle constant oracle = Oracle(0x1234567); // known contract + uint exchangeRate; function buySomething() public { oracle.query("USD", this.oracleResponse); } - function oracleResponse(bytes memory response) public { + function oracleResponse(uint response) public { require( msg.sender == address(oracle), "Only oracle can call this." ); - // Use the data + exchangeRate = response; } } @@ -601,8 +602,8 @@ memory-stored reference type do not create a copy. h(x); // calls h and creates an independent, temporary copy in memory } - function g(uint[] storage storageArray) internal {} - function h(uint[] memory memoryArray) public {} + function g(uint[] storage) internal pure {} + function h(uint[] memory) public pure {} } Summary @@ -659,8 +660,9 @@ Allocating Memory Arrays ^^^^^^^^^^^^^^^^^^^^^^^^ Creating arrays with variable length in memory can be done using the ``new`` keyword. -As opposed to storage arrays, it is **not** possible to resize memory arrays by assigning to -the ``.length`` member. +As opposed to storage arrays, it is **not** possible to resize memory arrays (e.g. by assigning to +the ``.length`` member). You either have to calculate the required size in advance +or crete a new memory array and copy every element. :: @@ -670,7 +672,8 @@ the ``.length`` member. function f(uint len) public pure { uint[] memory a = new uint[](7); bytes memory b = new bytes(len); - // Here we have a.length == 7 and b.length == len + assert(a.length == 7); + assert(b.length == len); a[6] = 8; } } @@ -691,7 +694,7 @@ assigned to a variable right away. function f() public pure { g([uint(1), 2, 3]); } - function g(uint[3] memory _data) public pure { + function g(uint[3] memory) public pure { // ... } } @@ -706,10 +709,9 @@ possible: :: - // This will not compile. - pragma solidity ^0.4.0; + // This will not compile. contract C { function f() public { // The next line creates a type error because uint[3] memory @@ -752,9 +754,12 @@ Members uint[2**20] m_aLotOfIntegers; // Note that the following is not a pair of dynamic arrays but a // dynamic array of pairs (i.e. of fixed size arrays of length two). + // Because of that, T[] is always a dynamic array of T, even if T + // itself is an array. bool[2][] m_pairsOfFlags; - // newPairs is stored in memory - the default for function arguments + // newPairs is stored in memory - the only possibility + // for public function arguments function setAllFlagPairs(bool[2][] memory newPairs) public { // assignment to a storage array replaces the complete array m_pairsOfFlags = newPairs; @@ -797,6 +802,11 @@ Members function createMemoryArray(uint size) public pure returns (bytes memory) { // Dynamic memory arrays are created using `new`: uint[2][] memory arrayOfPairs = new uint[2][](size); + + // Inline arrays are always statically-sized and if you only + // use literals, you have to provide at least one type. + arrayOfPairs[0] = [uint(1), 2]; + // Create a dynamic byte array: bytes memory b = new bytes(200); for (uint i = 0; i < b.length; i++) @@ -968,6 +978,7 @@ It is important to note that ``delete a`` really behaves like an assignment to ` // y is affected which is an alias to the storage object // On the other hand: "delete y" is not valid, as assignments to local variables // referencing storage objects can only be made from existing storage objects. + assert(y.length == 0); } } |