diff options
Diffstat (limited to 'docs/contracts.rst')
-rw-r--r-- | docs/contracts.rst | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/docs/contracts.rst b/docs/contracts.rst index 4fe046ed..ef29a686 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -4,7 +4,7 @@ Contracts ########## -Contracts in Solidity are what classes are in object oriented languages. They +Contracts in Solidity are similar to classes in object-oriented languages. They contain persistent data in state variables and functions that can modify these variables. Calling a function on a different contract (instance) will perform an EVM function call and thus switch the context such that state variables are @@ -78,6 +78,11 @@ This means that cyclic creation dependencies are impossible. // This is the constructor which registers the // creator and the assigned name. function OwnedToken(bytes32 _name) { + // 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"), + // because the contract itself does not exist yet. owner = msg.sender; // We do an explicit type conversion from `address` // to `TokenCreator` and assume that the type of @@ -241,7 +246,7 @@ Accessor Functions ================== The compiler automatically creates accessor functions for -all public state variables. For the contract given below, the compiler will +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 @@ -328,7 +333,7 @@ inheritable properties of contracts and may be overridden by derived contracts. // This contract only defines a modifier but does not use // it - it will be used in derived contracts. // The function body is inserted where the special symbol - // "_" in the definition of a modifier appears. + // "_;" in the definition of a modifier appears. // This means that if the owner calls this function, the // function is executed and otherwise, an exception is // thrown. @@ -367,7 +372,10 @@ inheritable properties of contracts and may be overridden by derived contracts. function Register(uint initialPrice) { price = initialPrice; } - function register() costs(price) { + // It is important to also provide the + // "payable" keyword here, otherwise the function will + // automatically reject all Ether sent to it. + function register() payable costs(price) { registeredAddresses[msg.sender] = true; } @@ -450,7 +458,7 @@ functions matches the given function identifier (or if no data was supplied at all). Furthermore, this function is executed whenever the contract receives plain -Ether (without data). In such a context, there is very little gas available to +Ether (without data). In such a context, there is usually very little gas available to the function call (to be precise, 2300 gas), so it is important to make fallback functions as cheap as possible. @@ -474,26 +482,31 @@ Please ensure you test your fallback function thoroughly to ensure the execution pragma solidity ^0.4.0; contract Test { + // This function is called for all messages sent to + // this contract (there is no other function). + // Sending Ether to this contract will cause an exception, + // because the fallback function does not have the "payable" + // modifier. function() { x = 1; } 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 lose Ether. - contract Rejector { - function() { throw; } + // This contract keeps all Ether sent to it with no way + // to get it back. + contract Sink { + function() payable { } } contract Caller { - function callTest(address testAddress) { - Test(testAddress).call(0xabcdef01); // hash does not exist - // results in Test(testAddress).x becoming == 1. - Rejector r = Rejector(0x123); - r.send(2 ether); - // results in r.balance == 0 + function callTest(Test test) { + 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); } } @@ -539,6 +552,11 @@ not possible to filter for specific anonymous events by name. All non-indexed arguments will be stored in the data part of the log. +.. note:: + Indexed arguments will not be stored themselves, you can only + search for the values, but it is impossible to retrieve the + values themselves. + :: pragma solidity ^0.4.0; @@ -622,7 +640,7 @@ Inheritance Solidity supports multiple inheritance by copying code including polymorphism. All function calls are virtual, which means that the most derived function -is called, except when the contract is explicitly given. +is called, except when the contract name is explicitly given. Even if a contract inherits from multiple other contracts, only a single contract is created on the blockchain, the code from the base contracts @@ -636,6 +654,8 @@ Details are given in the following example. :: + pragma solidity ^0.4.0; + contract owned { function owned() { owner = msg.sender; } address owner; @@ -709,6 +729,8 @@ Note that above, we call ``mortal.kill()`` to "forward" the destruction request. The way this is done is problematic, as seen in the following example:: + pragma solidity ^0.4.0; + contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); @@ -734,6 +756,8 @@ derived override, but this function will bypass ``Base1.kill``, basically because it does not even know about ``Base1``. The way around this is to use ``super``:: + pragma solidity ^0.4.0; + contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); @@ -773,6 +797,8 @@ Arguments for Base Constructors Derived contracts need to provide all arguments needed for the base constructors. This can be done at two places:: + pragma solidity ^0.4.0; + contract Base { uint x; function Base(uint _x) { x = _x; } @@ -833,12 +859,16 @@ Abstract Contracts Contract functions can lack an implementation as in the following example (note that the function declaration header is terminated by ``;``):: + pragma solidity ^0.4.0; + contract Feline { 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:: + pragma solidity ^0.4.0; + contract Cat is Feline { function utterance() returns (bytes32) { return "miaow"; } } @@ -1060,6 +1090,8 @@ available without having to add further code. Let us rewrite the set example from the :ref:`libraries` in this way:: + pragma solidity ^0.4.0; + // This is the same code as before, just without comments library Set { struct Data { mapping(uint => bool) flags; } @@ -1106,6 +1138,8 @@ Let us rewrite the set example from the It is also possible to extend elementary types in that way:: + pragma solidity ^0.4.0; + library Search { function indexOf(uint[] storage self, uint value) returns (uint) { for (uint i = 0; i < self.length; i++) |