Merge pull request #1024 from ethereum/docupdate

Update documentation to version 0.4.0.
This commit is contained in:
chriseth 2016-09-08 01:56:27 +02:00 committed by GitHub
commit 8951affb62
13 changed files with 139 additions and 88 deletions

View File

@ -36,12 +36,12 @@ become the new richest.
mapping (address => uint) pendingWithdrawals;
function WithdrawalContract() {
function WithdrawalContract() payable {
richest = msg.sender;
mostSent = msg.value;
}
function becomeRichest() returns (bool) {
function becomeRichest() payable returns (bool) {
if (msg.value > mostSent) {
pendingWithdrawals[richest] += msg.value;
richest = msg.sender;
@ -66,7 +66,7 @@ become the new richest.
}
}
This is as opposed to the more intuitive sending pattern.
This is as opposed to the more intuitive sending pattern:
::
@ -76,7 +76,7 @@ This is as opposed to the more intuitive sending pattern.
address public richest;
uint public mostSent;
function SendContract() {
function SendContract() payable {
richest = msg.sender;
mostSent = msg.value;
}
@ -156,7 +156,7 @@ restrictions highly readable.
throw;
// Do not forget the "_;"! It will
// be replaced by the actual function
// body when the modifier is invoked.
// body when the modifier is used.
_;
}
@ -187,9 +187,8 @@ restrictions highly readable.
// fee being associated with a function call.
// If the caller sent too much, he or she is
// refunded, but only after the function body.
// This is dangerous, because if the function
// uses `return` explicitly, this will not be
// done! This behavior will be fixed in Version 0.4.0.
// This was dangerous before Solidity version 0.4.0,
// where it was possible to skip the part after `_;`.
modifier costs(uint _amount) {
if (msg.value < _amount)
throw;
@ -204,10 +203,10 @@ restrictions highly readable.
owner = _newOwner;
// just some example condition
if (uint(owner) & 0 == 1)
// in this case, overpaid fees will not
// be refunded
// This did not refund for Solidity
// before version 0.4.0.
return;
// otherwise, refund overpaid fees
// refund overpaid fees
}
}
@ -265,13 +264,14 @@ function finishes.
.. note::
**Modifier May be Skipped**.
This only applies to Solidity before version 0.4.0:
Since modifiers are applied by simply replacing
code and not by using a function call,
the code in the transitionNext modifier
can be skipped if the function itself uses
return. If you want to do that, make sure
to call nextStage manually from those functions.
With version 0.4.0 (unreleased), modifier code
to call nextStage manually from those functions.
Starting with version 0.4.0, modifier code
will run even if the function explicitly returns.
::
@ -317,6 +317,7 @@ function finishes.
// Order of the modifiers matters here!
function bid()
payable
timedTransitions
atStage(Stages.AcceptingBlindedBids)
{
@ -331,9 +332,6 @@ function finishes.
// This modifier goes to the next stage
// after the function is done.
// If you use `return` in the function,
// `nextStage` will not be called
// automatically.
modifier transitionNext()
{
_;
@ -345,8 +343,6 @@ function finishes.
atStage(Stages.AnotherStage)
transitionNext
{
// If you want to use `return` here,
// you have to call `nextStage()` manually.
}
function h()

View File

@ -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++)

View File

@ -25,17 +25,21 @@ To report an issue, please use the
reporting issues, please mention the following details:
* Which version of Solidity you are using
* What was the source code (if applicable)
* Which platform are you running on
* How to reproduce the issue
* What was the result of the issue
* What the expected behaviour is
Reducing the source code that caused the issue to a bare minimum is always
very helpful and sometimes even clarifies a misunderstanding.
Workflow for Pull Requests
==========================
In order to contribute, please fork off of the ``develop`` branch and make your
changes there. Your commit messages should detail *why* you made your change, as
opposed to *what* you did.
changes there. Your commit messages should detail *why* you made your change
in addition to *what* you did (unless it is a tiny change).
If you need to pull in any changes from ``develop`` after making your fork (for
example, to resolve potential merge conflicts), please avoid using ``git merge``

View File

@ -44,8 +44,12 @@ contract can be called internally.
External Function Calls
-----------------------
The expression ``this.g(8);`` is also a valid function call, but this time, the function
The expressions ``this.g(8);`` and ``c.g(2);`` (where ``g`` is a contract
instance) are also valid function calls, but this time, the function
will be called "externally", via a message call and not directly via jumps.
Please note that function calls on ``this`` cannot be used in the constructor, as the
actual contract has not been created yet.
Functions of other contracts have to be called externally. For an external call,
all function arguments have to be copied to memory.
@ -53,7 +57,7 @@ When calling functions
of other contracts, the amount of Wei sent with the call and the gas can be specified::
contract InfoFeed {
function info() returns (uint ret) { return 42; }
function info() payable returns (uint ret) { return 42; }
}
@ -63,9 +67,17 @@ of other contracts, the amount of Wei sent with the call and the gas can be spec
function callFeed() { feed.info.value(10).gas(800)(); }
}
The modifier ``payable`` has to be used for ``info``, because otherwise,
we would not be able to send Ether to it in the call ``feed.info.value(10).gas(800)()``.
Note that the expression ``InfoFeed(addr)`` performs an explicit type conversion stating
that "we know that the type of the contract at the given address is ``InfoFeed``" and
this does not execute a constructor. We could also have used ``function setFeed(InfoFeed _feed) { feed = _feed; }`` directly. Be careful about the fact that ``feed.info.value(10).gas(800)``
this does not execute a constructor. Explicit type conversions have to be
handled with extreme caution. Never call a function on a contract where you
are not sure about its type.
We could also have used ``function setFeed(InfoFeed _feed) { feed = _feed; }`` directly.
Be careful about the fact that ``feed.info.value(10).gas(800)``
only (locally) sets the value and amount of gas sent with the function call and only the
parentheses at the end perform the actual call.
@ -144,7 +156,7 @@ creation-dependencies are now possible.
contract D {
uint x;
function D(uint a) {
function D(uint a) payable {
x = a;
}
}
@ -241,6 +253,8 @@ This happens because Solidity inherits its scoping rules from JavaScript.
This is in contrast to many languages where variables are only scoped where they are declared until the end of the semantic block.
As a result, the following code is illegal and cause the compiler to throw an error, ``Identifier already declared``::
pragma solidity ^0.4.0;
contract ScopingErrors {
function scoping() {
uint i = 0;
@ -298,8 +312,10 @@ Catching exceptions is not yet possible.
In the following example, we show how ``throw`` can be used to easily revert an Ether transfer and also how to check the return value of ``send``::
pragma solidity ^0.4.0;
contract Sharer {
function sendHalf(address addr) returns (uint balance) {
function sendHalf(address addr) payable returns (uint balance) {
if (!addr.send(msg.value / 2))
throw; // also reverts the transfer to Sharer
return this.balance;
@ -337,8 +353,9 @@ arising when writing manual assembly by the following features:
We now want to describe the inline assembly language in detail.
.. warning::
Inline assembly is still a relatively new feature and might change if it does not prove useful,
so please try to keep up to date.
Inline assembly is a way to access the Ethereum Virtual Machine
at a low level. This discards several important safety
features of Solidity.
Example
-------

View File

@ -317,17 +317,12 @@ providing any data or if someone messed up the types so that they tried to
call a function that does not exist.
The default behaviour (if no fallback function is explicitly given) in
these situations is to just accept the call and do nothing.
This is desireable in many cases, but should only be used if there is
a way to pull out Ether from a contract.
these situations is to throw an exception.
If the contract is not meant to receive Ether with simple transfers, you
If the contract is meant to receive Ether with simple transfers, you
should implement the fallback function as
``function() { throw; }``
this will cause all transactions to this contract that do not call an
existing function to be reverted, so that all Ether is sent back.
``function() payable { }``
Another use of the fallback function is to e.g. register that your
contract received ether by using an event.
@ -488,6 +483,8 @@ What happens if you send ether along with a function call to a contract?
========================================================================
It gets added to the total balance of the contract, just like when you send ether when creating a contract.
You can only send ether along to a function that has the ``payable`` modifier,
otherwise an exception is thrown.
Is it possible to get a tx receipt for a transaction executed contract-to-contract?
===================================================================================

View File

@ -71,6 +71,9 @@ Discontinued:
Solidity Tools
--------------
* `Dapple <https://github.com/nexusdev/dapple>`_
Package and deployment manager for Solidity.
* `Solidity REPL <https://github.com/raineorshine/solidity-repl>`_
Try Solidity instantly with a command-line Solidity console.

View File

@ -30,6 +30,11 @@ Storage
}
}
The first line simply tells that the source code is written for
Solidity version 0.4.0 or anything newer that does not break functionality
(up to, but not including, version 0.5.0). This is to ensure that the
contract does not suddenly behave differently with a new compiler version.
A contract in the sense of Solidity is a collection of code (its functions) and
data (its *state*) that resides at a specific address on the Ethereum
blockchain. The line ``uint storedData;`` declares a state variable called ``storedData`` of

View File

@ -212,7 +212,6 @@ Tips and Tricks
* Make your state variables public - the compiler will create :ref:`getters <visibility-and-accessors>` for you for free.
* If you end up checking conditions on input or state a lot at the beginning of your functions, try using :ref:`modifiers`.
* If your contract has a function called ``send`` but you want to use the built-in send-function, use ``address(contractVariable).send(amount)``.
* If you do **not** want your contracts to receive ether when called via ``send``, you can add a throwing fallback function ``function() { throw; }``.
* Initialise storage structs with a single assignment: ``x = MyStruct({a: 1, b: 2});``
**********
@ -338,3 +337,4 @@ Modifiers
- ``constant`` for functions: Disallows modification of state - this is not enforced yet.
- ``anonymous`` for events: Does not store event signature as topic.
- ``indexed`` for event parameters: Stores the parameter as topic.
- ``payable`` for functions: Allows them to receive Ether together with a call.

View File

@ -51,7 +51,7 @@ complete contract):
::
pragma solidity ^0.4.0;
pragma solidity ^0.4.0;
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract Fund {
@ -75,7 +75,7 @@ outlined further below:
::
pragma solidity ^0.4.0;
pragma solidity ^0.4.0;
contract Fund {
/// Mapping of ether shares of the contract.
@ -107,6 +107,11 @@ and stall those. Please be explicit about such cases in the documentation of you
Sending and Receiving Ether
===========================
- Neither contracts nor "external accounts" are currently able to prevent that someone sends them Ether.
Contracts can react on and reject a regular transfer, but there are ways
to move Ether without creating a message call. One way is to simply "mine to"
the contract address and the second way is using ``selfdestruct(x)``.
- If a contract receives Ether (without a function being called), the fallback function is executed.
If it does not have a fallback function, the Ether will be rejected (by throwing an exception).
During the execution of the fallback function, the contract can only rely
@ -155,6 +160,7 @@ Never use tx.origin for authorization. Let's say you have a wallet contract like
pragma solidity ^0.4.0;
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract TxUserWallet {
address owner;
@ -186,7 +192,7 @@ Now someone tricks you into sending ether to the address of this attack wallet:
}
}
If your wallet had checked msg.sender for authorization, it would get the address of the attack wallet, instead of the owner address. But by checking tx.origin, it gets the original address that kicked off the transaction, which is still the owner address. The attack wallet instantly drains all your funds.
If your wallet had checked ``msg.sender`` for authorization, it would get the address of the attack wallet, instead of the owner address. But by checking ``tx.origin``, it gets the original address that kicked off the transaction, which is still the owner address. The attack wallet instantly drains all your funds.
Minor Details

View File

@ -255,10 +255,12 @@ activate themselves.
/// together with this transaction.
/// The value will only be refunded if the
/// auction is not won.
function bid() {
function bid() payable {
// No arguments are necessary, all
// information is already part of
// the transaction.
// the transaction. The keyword payable
// is required for the function to
// be able to receive Ether.
if (now > auctionStart + biddingTime) {
// Revert the call if the bidding
// period is over.
@ -330,16 +332,6 @@ activate themselves.
if (!beneficiary.send(highestBid))
throw;
}
function () {
// This function gets executed if a
// transaction with invalid data is sent to
// the contract or just ether without data.
// We revert the send so that no-one
// accidentally loses money when using the
// contract.
throw;
}
}
Blind Auction
@ -433,6 +425,7 @@ high or low invalid bids.
/// still make the required deposit. The same address can
/// place multiple bids.
function bid(bytes32 _blindedBid)
payable
onlyBefore(biddingEnd)
{
bids[msg.sender].push(Bid({
@ -535,10 +528,6 @@ high or low invalid bids.
if (!beneficiary.send(this.balance))
throw;
}
function () {
throw;
}
}
.. index:: purchase, remote purchase, escrow
@ -558,7 +547,7 @@ Safe Remote Purchase
enum State { Created, Locked, Inactive }
State public state;
function Purchase() {
function Purchase() payable {
seller = msg.sender;
value = msg.value / 2;
if (2 * value != msg.value) throw;
@ -566,22 +555,22 @@ Safe Remote Purchase
modifier require(bool _condition) {
if (!_condition) throw;
_
_;
}
modifier onlyBuyer() {
if (msg.sender != buyer) throw;
_
_;
}
modifier onlySeller() {
if (msg.sender != seller) throw;
_
_;
}
modifier inState(State _state) {
if (state != _state) throw;
_
_;
}
event aborted();
@ -608,6 +597,7 @@ Safe Remote Purchase
function confirmPurchase()
inState(State.Created)
require(msg.value == 2 * value)
payable
{
purchaseConfirmed();
buyer = msg.sender;
@ -630,10 +620,6 @@ Safe Remote Purchase
if (!buyer.send(value) || !seller.send(this.balance))
throw;
}
function() {
throw;
}
}
********************

View File

@ -43,7 +43,7 @@ Functions are the executable units of code within a contract.
pragma solidity ^0.4.0;
contract SimpleAuction {
function bid() { // Function
function bid() payable { // Function
// ...
}
}
@ -69,7 +69,7 @@ Function modifiers can be used to amend the semantics of functions in a declarat
modifier onlySeller() { // Modifier
if (msg.sender != seller) throw;
_
_;
}
function abort() onlySeller { // Modifier usage
@ -91,7 +91,7 @@ Events are convenience interfaces with the EVM logging facilities.
contract SimpleAuction {
event HighestBidIncreased(address bidder, uint amount); // Event
function bid() {
function bid() payable {
// ...
HighestBidIncreased(msg.sender, msg.value); // Triggering event
}

View File

@ -615,7 +615,7 @@ indistinguishable from the numerals one and zero.
Contract and Library Names
==========================
Contracts should be named using the CapWords style.
Contracts and libraries should be named using the CapWords style.
Events

View File

@ -559,7 +559,7 @@ shown in the following example:
campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0);
}
function contribute(uint campaignID) {
function contribute(uint campaignID) payable {
Campaign c = campaigns[campaignID];
// Creates a new temporary memory struct, initialised with the given values
// and copies it over to storage.
@ -572,9 +572,10 @@ shown in the following example:
Campaign c = campaigns[campaignID];
if (c.amount < c.fundingGoal)
return false;
if (!c.beneficiary.send(c.amount))
throw;
uint amount = c.amount;
c.amount = 0;
if (!c.beneficiary.send(amount))
throw;
return true;
}
}
@ -636,6 +637,8 @@ It is important to note that ``delete a`` really behaves like an assignment to `
::
pragma solidity ^0.4.0;
contract DeleteExample {
uint data;
uint[] dataArray;