diff options
Diffstat (limited to 'docs/contracts.rst')
-rw-r--r-- | docs/contracts.rst | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/docs/contracts.rst b/docs/contracts.rst index 9923b1d2..68905fa4 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -67,6 +67,7 @@ This means that cyclic creation dependencies are impossible. TokenCreator creator; address owner; bytes32 name; + // This is the constructor which registers the // creator and the assigned name. function OwnedToken(bytes32 _name) { @@ -78,12 +79,14 @@ This means that cyclic creation dependencies are impossible. creator = TokenCreator(msg.sender); name = _name; } + function changeName(bytes32 newName) { // Only the creator can alter the name -- // the comparison is possible since contracts // are implicitly convertible to addresses. if (msg.sender == creator) name = newName; } + function transfer(address newOwner) { // Only the current owner can transfer the token. if (msg.sender != owner) return; @@ -107,11 +110,13 @@ This means that cyclic creation dependencies are impossible. // the ABI. return new OwnedToken(name); } + function changeName(OwnedToken tokenAddress, bytes32 name) { // Again, the external type of "tokenAddress" is // simply "address". tokenAddress.changeName(name); } + function isTokenTransferOK( address currentOwner, address newOwner @@ -222,8 +227,7 @@ The next example is a bit more complex: It will generate a function of the following form:: - function data(uint arg1, bool arg2, uint arg3) returns (uint a, bytes3 b) - { + function data(uint arg1, bool arg2, uint arg3) returns (uint a, bytes3 b) { a = data[arg1][arg2][arg3].a; b = data[arg1][arg2][arg3].b; } @@ -258,6 +262,8 @@ inheritable properties of contracts and may be overridden by derived contracts. // thrown. modifier onlyowner { if (msg.sender != owner) throw; _ } } + + contract mortal is owned { // This contract inherits the "onlyowner"-modifier from // "owned" and applies it to the "close"-function, which @@ -267,10 +273,14 @@ inheritable properties of contracts and may be overridden by derived contracts. selfdestruct(owner); } } + + contract priced { // Modifiers can receive arguments: modifier costs(uint price) { if (msg.value >= price) _ } } + + contract Register is priced, owned { mapping (address => bool) registeredAddresses; uint price; @@ -339,13 +349,15 @@ possible. uint x; } + // This contract rejects any Ether sent to it. It is good // practise to include such a function for every contract - // in order not to loose Ether. + // in order not to lose Ether. contract Rejector { function() { throw; } } + contract Caller { function callTest(address testAddress) { Test(testAddress).call(0xabcdef01); // hash does not exist @@ -406,6 +418,7 @@ All non-indexed arguments will be stored in the data part of the log. bytes32 indexed _id, uint _value ); + function deposit(bytes32 _id) { // Any call to this function (even deeply nested) can // be detected from the JavaScript API by filtering @@ -497,6 +510,7 @@ Details are given in the following example. address owner; } + // Use "is" to derive from another contract. Derived // contracts can access all non-private members including // internal functions and state variables. These cannot be @@ -507,6 +521,7 @@ Details are given in the following example. } } + // These abstract contracts are only provided to make the // interface known to the compiler. Note the function // without body. If a contract does not implement all @@ -514,11 +529,14 @@ Details are given in the following example. contract Config { function lookup(uint id) returns (address adr); } + + contract NameReg { function register(bytes32 name); function unregister(); } + // Multiple inheritance is possible. Note that "owned" is // also a base class of "mortal", yet there is only a single // instance of "owned" (as for virtual inheritance in C++). @@ -542,6 +560,7 @@ Details are given in the following example. } } + // If a constructor takes an argument, it needs to be // provided in the header (or modifier-invocation-style at // the constructor of the derived contract (see below)). @@ -564,12 +583,18 @@ seen in the following example:: if (msg.sender == owner) selfdestruct(owner); } } + + contract Base1 is mortal { function kill() { /* do cleanup 1 */ mortal.kill(); } } + + contract Base2 is mortal { function kill() { /* do cleanup 2 */ mortal.kill(); } } + + contract Final is Base1, Base2 { } @@ -583,12 +608,18 @@ derived override, but this function will bypass if (msg.sender == owner) selfdestruct(owner); } } + + contract Base1 is mortal { function kill() { /* do cleanup 1 */ super.kill(); } } + + contract Base2 is mortal { function kill() { /* do cleanup 2 */ super.kill(); } } + + contract Final is Base2, Base1 { } @@ -615,6 +646,8 @@ the base constructors. This can be done at two places:: uint x; function Base(uint _x) { x = _x; } } + + contract Derived is Base(7) { function Derived(uint _y) Base(_y * _y) { } @@ -721,6 +754,7 @@ more advanced example to implement a set). // We define a new struct datatype that will be used to // hold its data in the calling contract. struct Data { mapping(uint => bool) flags; } + // Note that the first parameter is of type "storage // reference" and thus only its storage address and not // its contents is passed as part of the call. This is a @@ -735,6 +769,7 @@ more advanced example to implement a set). self.flags[value] = true; return true; } + function remove(Data storage self, uint value) returns (bool) { @@ -743,14 +778,18 @@ more advanced example to implement a set). self.flags[value] = false; return true; } + function contains(Data storage self, uint value) returns (bool) { return self.flags[value]; } } + + contract C { Set.Data knownValues; + function register(uint value) { // The library functions can be called without a // specific instance of the library, since the @@ -783,12 +822,14 @@ custom types without the overhead of external function calls: library bigint { struct bigint { - uint[] limbs; + uint[] limbs; } + function fromUint(uint x) internal returns (bigint r) { r.limbs = new uint[](1); r.limbs[0] = x; } + function add(bigint _a, bigint _b) internal returns (bigint r) { r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length)); uint carry = 0; @@ -820,6 +861,7 @@ custom types without the overhead of external function calls: } } + contract C { using bigint for bigint.bigint; function f() { @@ -882,6 +924,7 @@ Let us rewrite the set example from the // This is the same code as before, just without comments library Set { struct Data { mapping(uint => bool) flags; } + function insert(Data storage self, uint value) returns (bool) { @@ -890,6 +933,7 @@ Let us rewrite the set example from the self.flags[value] = true; return true; } + function remove(Data storage self, uint value) returns (bool) { @@ -898,6 +942,7 @@ Let us rewrite the set example from the self.flags[value] = false; return true; } + function contains(Data storage self, uint value) returns (bool) { @@ -905,9 +950,11 @@ Let us rewrite the set example from the } } + contract C { using Set for Set.Data; // this is the crucial change Set.Data knownValues; + function register(uint value) { // Here, all variables of type Set.Data have // corresponding member functions. @@ -928,12 +975,15 @@ It is also possible to extend elementary types in that way:: } } + contract C { using Search for uint[]; uint[] data; + function append(uint value) { data.push(value); } + function replace(uint _old, uint _new) { // This performs the library function call uint index = data.find(_old); |