mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
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:
commit
be34b574bf
@ -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:
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user