Merge pull request #3152 from ethereum/docs-tests

Ensure each code snippet in the docs can be extracted for tests
This commit is contained in:
Alex Beregszaszi 2017-11-22 04:59:28 +00:00 committed by GitHub
commit be34b574bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 107 additions and 115 deletions

View File

@ -330,15 +330,15 @@ For example,
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract Test { contract Test {
function Test(){ b = 0x12345678901234567890123456789012; } function Test(){ b = 0x12345678901234567890123456789012; }
event Event(uint indexed a, bytes32 b); event Event(uint indexed a, bytes32 b);
event Event2(uint indexed a, bytes32 b); event Event2(uint indexed a, bytes32 b);
function foo(uint a) { Event(a, b); } function foo(uint a) { Event(a, b); }
bytes32 b; bytes32 b;
} }
would result in the JSON: would result in the JSON:
@ -377,11 +377,11 @@ As an example, the code
:: ::
contract Test { contract Test {
struct S { uint a; uint[] b; T[] c; } struct S { uint a; uint[] b; T[] c; }
struct T { uint x; uint y; } struct T { uint x; uint y; }
function f(S s, T t, uint a) { } function f(S s, T t, uint a) { }
} }
would result in the JSON: would result in the JSON:

View File

@ -198,7 +198,6 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value
function compute(uint a, uint b) internal returns (uint) { return a+b; } function compute(uint a, uint b) internal returns (uint) { return a+b; }
} }
contract D { contract D {
function readData() { function readData() {
C c = new C(); C c = new C();
@ -209,7 +208,6 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value
} }
} }
contract E is C { contract E is C {
function g() { function g() {
C c = new C(); C c = new C();
@ -238,7 +236,6 @@ be done at declaration.
uint public data = 42; uint public data = 42;
} }
contract Caller { contract Caller {
C c = new C(); C c = new C();
function f() { function f() {
@ -321,7 +318,6 @@ inheritable properties of contracts and may be overridden by derived contracts.
} }
} }
contract mortal is owned { contract mortal is owned {
// This contract inherits the "onlyOwner"-modifier from // This contract inherits the "onlyOwner"-modifier from
// "owned" and applies it to the "close"-function, which // "owned" and applies it to the "close"-function, which
@ -332,7 +328,6 @@ inheritable properties of contracts and may be overridden by derived contracts.
} }
} }
contract priced { contract priced {
// Modifiers can receive arguments: // Modifiers can receive arguments:
modifier costs(uint price) { modifier costs(uint price) {
@ -342,7 +337,6 @@ inheritable properties of contracts and may be overridden by derived contracts.
} }
} }
contract Register is priced, owned { contract Register is priced, owned {
mapping (address => bool) registeredAddresses; mapping (address => bool) registeredAddresses;
uint price; uint price;
@ -570,7 +564,6 @@ Please ensure you test your fallback function thoroughly to ensure the execution
function() payable { } function() payable { }
} }
contract Caller { contract Caller {
function callTest(Test test) { function callTest(Test test) {
test.call(0xabcdef01); // hash does not exist test.call(0xabcdef01); // hash does not exist
@ -687,12 +680,19 @@ as topics. The event call above can be performed in the same way as
:: ::
log3( pragma solidity ^0.4.10;
msg.value,
0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20, contract C {
msg.sender, function f() {
_id bytes32 _id = 0x420042;
); log3(
bytes32(msg.value),
bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
bytes32(msg.sender),
_id
);
}
}
where the long hexadecimal number is equal to where the long hexadecimal number is equal to
``keccak256("Deposit(address,hash256,uint256)")``, the signature of the event. ``keccak256("Deposit(address,hash256,uint256)")``, the signature of the event.
@ -734,7 +734,6 @@ Details are given in the following example.
address owner; address owner;
} }
// Use "is" to derive from another contract. Derived // Use "is" to derive from another contract. Derived
// contracts can access all non-private members including // contracts can access all non-private members including
// internal functions and state variables. These cannot be // internal functions and state variables. These cannot be
@ -745,7 +744,6 @@ Details are given in the following example.
} }
} }
// These abstract contracts are only provided to make the // These abstract contracts are only provided to make the
// interface known to the compiler. Note the function // interface known to the compiler. Note the function
// without body. If a contract does not implement all // without body. If a contract does not implement all
@ -754,13 +752,11 @@ Details are given in the following example.
function lookup(uint id) returns (address adr); function lookup(uint id) returns (address adr);
} }
contract NameReg { contract NameReg {
function register(bytes32 name); function register(bytes32 name);
function unregister(); function unregister();
} }
// Multiple inheritance is possible. Note that "owned" is // Multiple inheritance is possible. Note that "owned" is
// also a base class of "mortal", yet there is only a single // also a base class of "mortal", yet there is only a single
// instance of "owned" (as for virtual inheritance in C++). // instance of "owned" (as for virtual inheritance in C++).
@ -786,7 +782,6 @@ Details are given in the following example.
} }
} }
// If a constructor takes an argument, it needs to be // If a constructor takes an argument, it needs to be
// provided in the header (or modifier-invocation-style at // provided in the header (or modifier-invocation-style at
// the constructor of the derived contract (see below)). // the constructor of the derived contract (see below)).
@ -821,12 +816,10 @@ seen in the following example::
function kill() { /* do cleanup 1 */ mortal.kill(); } function kill() { /* do cleanup 1 */ mortal.kill(); }
} }
contract Base2 is mortal { contract Base2 is mortal {
function kill() { /* do cleanup 2 */ mortal.kill(); } function kill() { /* do cleanup 2 */ mortal.kill(); }
} }
contract Final is Base1, Base2 { contract Final is Base1, Base2 {
} }
@ -848,7 +841,6 @@ derived override, but this function will bypass
} }
} }
contract Base1 is mortal { contract Base1 is mortal {
function kill() { /* do cleanup 1 */ super.kill(); } function kill() { /* do cleanup 1 */ super.kill(); }
} }
@ -858,7 +850,6 @@ derived override, but this function will bypass
function kill() { /* do cleanup 2 */ super.kill(); } function kill() { /* do cleanup 2 */ super.kill(); }
} }
contract Final is Base2, Base1 { contract Final is Base2, Base1 {
} }
@ -888,7 +879,6 @@ the base constructors. This can be done in two ways::
function Base(uint _x) { x = _x; } function Base(uint _x) { x = _x; }
} }
contract Derived is Base(7) { contract Derived is Base(7) {
function Derived(uint _y) Base(_y * _y) { function Derived(uint _y) Base(_y * _y) {
} }
@ -1081,7 +1071,6 @@ more advanced example to implement a set).
} }
} }
contract C { contract C {
Set.Data knownValues; Set.Data knownValues;
@ -1157,7 +1146,6 @@ custom types without the overhead of external function calls:
} }
} }
contract C { contract C {
using BigInt for BigInt.bigint; using BigInt for BigInt.bigint;
@ -1250,7 +1238,6 @@ Let us rewrite the set example from the
} }
} }
contract C { contract C {
using Set for Set.Data; // this is the crucial change using Set for Set.Data; // this is the crucial change
Set.Data knownValues; Set.Data knownValues;
@ -1276,7 +1263,6 @@ It is also possible to extend elementary types in that way::
} }
} }
contract C { contract C {
using Search for uint[]; using Search for uint[];
uint[] data; uint[] data;

View File

@ -194,7 +194,7 @@ Omitted Function Parameter Names
-------------------------------- --------------------------------
The names of unused parameters (especially return parameters) can be omitted. The names of unused parameters (especially return parameters) can be omitted.
Those names will still be present on the stack, but they are inaccessible. Those parameters will still be present on the stack, but they are inaccessible.
:: ::
@ -363,15 +363,19 @@ As a result, the following code is illegal and cause the compiler to throw an er
In addition to this, if a variable is declared, it will be initialized at the beginning of the function to its default value. In addition to this, if a variable is declared, it will be initialized at the beginning of the function to its default value.
As a result, the following code is legal, despite being poorly written:: As a result, the following code is legal, despite being poorly written::
function foo() returns (uint) { pragma solidity ^0.4.0;
// baz is implicitly initialized as 0
uint bar = 5; contract C {
if (true) { function foo() returns (uint) {
bar += baz; // baz is implicitly initialized as 0
} else { uint bar = 5;
uint baz = 10;// never executes if (true) {
bar += baz;
} else {
uint baz = 10;// never executes
}
return bar;// returns 5
} }
return bar;// returns 5
} }
.. index:: ! exception, ! throw, ! assert, ! require, ! revert .. index:: ! exception, ! throw, ! assert, ! require, ! revert

View File

@ -55,18 +55,18 @@ complete contract):
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
// THIS CONTRACT CONTAINS A BUG - DO NOT USE // THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract Fund { contract Fund {
/// Mapping of ether shares of the contract. /// Mapping of ether shares of the contract.
mapping(address => uint) shares; mapping(address => uint) shares;
/// Withdraw your share. /// Withdraw your share.
function withdraw() { function withdraw() {
if (msg.sender.send(shares[msg.sender])) if (msg.sender.send(shares[msg.sender]))
shares[msg.sender] = 0; shares[msg.sender] = 0;
} }
} }
The problem is not too serious here because of the limited gas as part The problem is not too serious here because of the limited gas as part
of ``send``, but it still exposes a weakness: Ether transfer always of ``send``, but it still exposes a weakness: Ether transfer always
@ -79,18 +79,18 @@ outlined further below:
:: ::
pragma solidity ^0.4.11; pragma solidity ^0.4.11;
contract Fund { contract Fund {
/// Mapping of ether shares of the contract. /// Mapping of ether shares of the contract.
mapping(address => uint) shares; mapping(address => uint) shares;
/// Withdraw your share. /// Withdraw your share.
function withdraw() { function withdraw() {
var share = shares[msg.sender]; var share = shares[msg.sender];
shares[msg.sender] = 0; shares[msg.sender] = 0;
msg.sender.transfer(share); msg.sender.transfer(share);
} }
} }
Note that re-entrancy is not only an effect of Ether transfer but of any Note that re-entrancy is not only an effect of Ether transfer but of any
function call on another contract. Furthermore, you also have to take function call on another contract. Furthermore, you also have to take
@ -179,7 +179,9 @@ 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.11;

View File

@ -20,12 +20,12 @@ State variables are values which are permanently stored in contract storage.
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract SimpleStorage { contract SimpleStorage {
uint storedData; // State variable uint storedData; // State variable
// ... // ...
} }
See the :ref:`types` section for valid state variable types and See the :ref:`types` section for valid state variable types and
:ref:`visibility-and-getters` for possible choices for :ref:`visibility-and-getters` for possible choices for
@ -40,13 +40,13 @@ Functions are the executable units of code within a contract.
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract SimpleAuction { contract SimpleAuction {
function bid() payable { // Function function bid() payable { // Function
// ... // ...
} }
} }
:ref:`function-calls` can happen internally or externally :ref:`function-calls` can happen internally or externally
and have different levels of visibility (:ref:`visibility-and-getters`) and have different levels of visibility (:ref:`visibility-and-getters`)
@ -62,20 +62,20 @@ Function modifiers can be used to amend the semantics of functions in a declarat
:: ::
pragma solidity ^0.4.11; pragma solidity ^0.4.11;
contract Purchase { contract Purchase {
address public seller; address public seller;
modifier onlySeller() { // Modifier modifier onlySeller() { // Modifier
require(msg.sender == seller); require(msg.sender == seller);
_; _;
} }
function abort() onlySeller { // Modifier usage function abort() onlySeller { // Modifier usage
// ... // ...
} }
} }
.. _structure-events: .. _structure-events:
@ -86,16 +86,16 @@ Events are convenience interfaces with the EVM logging facilities.
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract SimpleAuction { contract SimpleAuction {
event HighestBidIncreased(address bidder, uint amount); // Event event HighestBidIncreased(address bidder, uint amount); // Event
function bid() payable { function bid() payable {
// ... // ...
HighestBidIncreased(msg.sender, msg.value); // Triggering event HighestBidIncreased(msg.sender, msg.value); // Triggering event
} }
} }
See :ref:`events` in contracts section for information on how events are declared See :ref:`events` in contracts section for information on how events are declared
and can be used from within a dapp. and can be used from within a dapp.
@ -110,16 +110,16 @@ Structs are custom defined types that can group several variables (see
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract Ballot { contract Ballot {
struct Voter { // Struct struct Voter { // Struct
uint weight; uint weight;
bool voted; bool voted;
address delegate; address delegate;
uint vote; uint vote;
} }
} }
.. _structure-enum-types: .. _structure-enum-types:
@ -131,8 +131,8 @@ Enums can be used to create custom types with a finite set of values (see
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract Purchase { contract Purchase {
enum State { Created, Locked, Inactive } // Enum enum State { Created, Locked, Inactive } // Enum
} }