aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/common-patterns.rst7
-rw-r--r--docs/contracts.rst47
-rw-r--r--docs/control-structures.rst7
-rw-r--r--docs/frequently-asked-questions.rst30
-rw-r--r--docs/miscellaneous.rst2
-rw-r--r--docs/solidity-by-example.rst2
-rw-r--r--docs/structure-of-a-contract.rst50
-rw-r--r--docs/types.rst258
-rw-r--r--docs/units-and-global-variables.rst2
9 files changed, 219 insertions, 186 deletions
diff --git a/docs/common-patterns.rst b/docs/common-patterns.rst
index 842b7c37..679552ff 100644
--- a/docs/common-patterns.rst
+++ b/docs/common-patterns.rst
@@ -179,6 +179,7 @@ function finishes.
AreWeDoneYet,
Finished
}
+
// This is the current stage.
Stages public stage = Stages.AcceptingBlindedBids;
@@ -188,9 +189,11 @@ function finishes.
if (stage != _stage) throw;
_
}
+
function nextStage() internal {
stage = Stages(uint(stage) + 1);
}
+
// Perform timed transitions. Be sure to mention
// this modifier first, otherwise the guards
// will not take the new stage into account.
@@ -211,6 +214,7 @@ function finishes.
{
// We will not implement that here
}
+
function reveal()
timedTransitions
atStage(Stages.RevealBids)
@@ -227,6 +231,7 @@ function finishes.
_
nextStage();
}
+
function g()
timedTransitions
atStage(Stages.AnotherStage)
@@ -235,12 +240,14 @@ function finishes.
// If you want to use `return` here,
// you have to call `nextStage()` manually.
}
+
function h()
timedTransitions
atStage(Stages.AreWeDoneYet)
transitionNext
{
}
+
function i()
timedTransitions
atStage(Stages.Finished)
diff --git a/docs/contracts.rst b/docs/contracts.rst
index ddfeb78c..dd75e857 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -25,27 +25,28 @@ API, this is done as follows::
// The json abi array generated by the compiler
var abiArray = [
- {
- "inputs":[
- {"name":"x","type":"uint256"},
- {"name":"y","type":"uint256"}
- ],
- "type":"constructor"
- },
- {
- "constant":true,
- "inputs":[],
- "name":"x",
- "outputs":[{"name":"","type":"bytes32"}],
- "type":"function"
- }
+ {
+ "inputs":[
+ {"name":"x","type":"uint256"},
+ {"name":"y","type":"uint256"}
+ ],
+ "type":"constructor"
+ },
+ {
+ "constant":true,
+ "inputs":[],
+ "name":"x",
+ "outputs":[{"name":"","type":"bytes32"}],
+ "type":"function"
+ }
];
var MyContract = web3.eth.contract(abiArray);
// deploy new contract
var contractInstance = MyContract.new(
- 10, 11,
- {from: myAccount, gas: 1000000}
+ 10,
+ 11,
+ {from: myAccount, gas: 1000000}
);
.. index:: constructor;arguments
@@ -375,13 +376,13 @@ possible.
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(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
+ }
}
.. index:: ! event
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index 0a233763..8d1788d3 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -55,6 +55,8 @@ of other contracts, the amount of Wei sent with the call and the gas can be spec
contract InfoFeed {
function info() returns (uint ret) { return 42; }
}
+
+
contract Consumer {
InfoFeed feed;
function setFeed(address addr) { feed = InfoFeed(addr); }
@@ -77,10 +79,12 @@ of unused parameters (especially return parameters) can be omitted.
contract c {
function f(uint key, uint value) { ... }
+
function g() {
// named arguments
f({value: 2, key: 3});
}
+
// omitted parameters
function func(uint k, uint) returns(uint) {
return k;
@@ -212,7 +216,7 @@ In the following example, we show how `throw` can be used to easily revert an Et
contract Sharer {
function sendHalf(address addr) returns (uint balance) {
- if (!addr.send(msg.value/2))
+ if (!addr.send(msg.value / 2))
throw; // also reverts the transfer to Sharer
return this.balance;
}
@@ -290,6 +294,7 @@ you really know what you are doing.
for (uint i = 0; i < _data.length; ++i)
o_sum += _data[i];
}
+
// We know that we only access the array in bounds, so we can avoid the check.
// 0x20 needs to be added to an array because the first slot contains the
// array length.
diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst
index 1b78d666..ff4d6fc0 100644
--- a/docs/frequently-asked-questions.rst
+++ b/docs/frequently-asked-questions.rst
@@ -692,11 +692,11 @@ What happens to a struct's mapping when copying over a struct?
This is a very interesting question. Suppose that we have a contract field set up like such::
- struct user{
+ struct user {
mapping(string => address) usedContracts;
}
- function somefunction{
+ function somefunction {
user user1;
user1.usedContracts["Hello"] = "World";
user user2 = user1;
@@ -715,6 +715,8 @@ You will need to make sure that you have both contracts aware of each other's pr
In this example::
contract B {}
+
+
contract A {
address child;
@@ -758,21 +760,21 @@ Sure. Take care that if you cross the memory / storage boundary,
independent copies will be created::
contract C {
- uint[20] x;
+ uint[20] x;
- function f() {
- g(x);
- h(x);
- }
+ function f() {
+ g(x);
+ h(x);
+ }
- function g(uint[20] y) {
- y[2] = 3;
- }
+ function g(uint[20] y) {
+ y[2] = 3;
+ }
- function h(uint[20] storage y) {
- y[3] = 4;
- }
- }
+ function h(uint[20] storage y) {
+ y[3] = 4;
+ }
+ }
The call to `g(x)` will not have an effect on `x` because it needs
to create an independent copy of the storage value in memory
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index f2ad0f88..19fbe85c 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -51,9 +51,11 @@ There are some types in Solidity's type system that have no counterpart in the s
if (useB) f = b;
return f(x);
}
+
function a(uint x) returns (uint z) {
return x * x;
}
+
function b(uint x) returns (uint z) {
return 2 * x;
}
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index 028bfa22..6aa072e3 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -292,7 +292,7 @@ activate themselves.
}
Blind Auction
-================
+=============
The previous open auction is extended to a blind auction
in the following. The advantage of a blind auction is
diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst
index 6685566d..79f78422 100644
--- a/docs/structure-of-a-contract.rst
+++ b/docs/structure-of-a-contract.rst
@@ -21,8 +21,8 @@ State variables are values which are permanently stored in contract storage.
::
contract SimpleStorage {
- uint storedData; // State variable
- // ...
+ uint storedData; // State variable
+ // ...
}
See the :ref:`types` section for valid state variable types and
@@ -39,9 +39,9 @@ Functions are the executable units of code within a contract.
::
contract SimpleAuction {
- function bid() { // Function
- // ...
- }
+ function bid() { // Function
+ // ...
+ }
}
:ref:`function-calls` can happen internally or externally
@@ -59,16 +59,16 @@ Function modifiers can be used to amend the semantics of functions in a declarat
::
contract Purchase {
- address public seller;
+ address public seller;
- modifier onlySeller() { // Modifier
- if (msg.sender != seller) throw;
- _
- }
+ modifier onlySeller() { // Modifier
+ if (msg.sender != seller) throw;
+ _
+ }
- function abort() onlySeller { // Modifier usage
- // ...
- }
+ function abort() onlySeller { // Modifier usage
+ // ...
+ }
}
.. _structure-events:
@@ -81,12 +81,12 @@ Events are convenience interfaces with the EVM logging facilities.
::
contract SimpleAuction {
- event HighestBidIncreased(address bidder, uint amount); // Event
+ event HighestBidIncreased(address bidder, uint amount); // Event
- function bid() {
- // ...
- HighestBidIncreased(msg.sender, msg.value); // Triggering event
- }
+ function bid() {
+ // ...
+ HighestBidIncreased(msg.sender, msg.value); // Triggering event
+ }
}
See :ref:`events` in contracts section for information on how events are declared
@@ -103,12 +103,12 @@ Structs are custom defined types that can group several variables (see
::
contract Ballot {
- struct Voter { // Struct
- uint weight;
- bool voted;
- address delegate;
- uint vote;
- }
+ struct Voter { // Struct
+ uint weight;
+ bool voted;
+ address delegate;
+ uint vote;
+ }
}
.. _structure-enum-types:
@@ -122,5 +122,5 @@ Enums can be used to create custom types with a finite set of values (see
::
contract Purchase {
- enum State { Created, Locked, Inactive } // Enum
+ enum State { Created, Locked, Inactive } // Enum
}
diff --git a/docs/types.rst b/docs/types.rst
index bd972bef..4beea9e0 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -171,21 +171,21 @@ to and from all integer types but implicit conversion is not allowed.
enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }
ActionChoices choice;
ActionChoices constant defaultChoice = ActionChoices.GoStraight;
- function setGoStraight()
- {
+
+ function setGoStraight() {
choice = ActionChoices.GoStraight;
}
+
// Since enum types are not part of the ABI, the signature of "getChoice"
// will automatically be changed to "getChoice() returns (uint8)"
// for all matters external to Solidity. The integer type used is just
// large enough to hold all enum values, i.e. if you have more values,
// `uint16` will be used and so on.
- function getChoice() returns (ActionChoices)
- {
+ function getChoice() returns (ActionChoices) {
return choice;
}
- function getDefaultChoice() returns (uint)
- {
+
+ function getDefaultChoice() returns (uint) {
return uint(defaultChoice);
}
}
@@ -226,26 +226,28 @@ memory-stored reference type does not create a copy.
::
- contract c {
- uint[] x; // the data location of x is storage
- // the data location of memoryArray is memory
- function f(uint[] memoryArray) {
- x = memoryArray; // works, copies the whole array to storage
- var y = x; // works, assigns a pointer, data location of y is storage
- y[7]; // fine, returns the 8th element
- y.length = 2; // fine, modifies x through y
- delete x; // fine, clears the array, also modifies y
- // The following does not work; it would need to create a new temporary /
- // unnamed array in storage, but storage is "statically" allocated:
- // y = memoryArray;
- // This does not work either, since it would "reset" the pointer, but there
- // is no sensible location it could point to.
- // delete y;
- g(x); // calls g, handing over a reference to x
- h(x); // calls h and creates an independent, temporary copy in memory
- }
- function g(uint[] storage storageArray) internal {}
- function h(uint[] memoryArray) {}
+ contract C {
+ uint[] x; // the data location of x is storage
+
+ // the data location of memoryArray is memory
+ function f(uint[] memoryArray) {
+ x = memoryArray; // works, copies the whole array to storage
+ var y = x; // works, assigns a pointer, data location of y is storage
+ y[7]; // fine, returns the 8th element
+ y.length = 2; // fine, modifies x through y
+ delete x; // fine, clears the array, also modifies y
+ // The following does not work; it would need to create a new temporary /
+ // unnamed array in storage, but storage is "statically" allocated:
+ // y = memoryArray;
+ // This does not work either, since it would "reset" the pointer, but there
+ // is no sensible location it could point to.
+ // delete y;
+ g(x); // calls g, handing over a reference to x
+ h(x); // calls h and creates an independent, temporary copy in memory
+ }
+
+ function g(uint[] storage storageArray) internal {}
+ function h(uint[] memoryArray) {}
}
Summary
@@ -303,12 +305,12 @@ the `.length` member.
::
contract C {
- function f(uint len) {
- uint[] memory a = new uint[](7);
- bytes memory b = new bytes(len);
- // Here we have a.length == 7 and b.length == len
- a[6] = 8;
- }
+ function f(uint len) {
+ uint[] memory a = new uint[](7);
+ bytes memory b = new bytes(len);
+ // Here we have a.length == 7 and b.length == len
+ a[6] = 8;
+ }
}
@@ -339,51 +341,59 @@ Members
::
contract ArrayContract {
- uint[2**20] m_aLotOfIntegers;
- // Note that the following is not a pair of arrays but an array of pairs.
- bool[2][] m_pairsOfFlags;
- // newPairs is stored in memory - the default for function arguments
- function setAllFlagPairs(bool[2][] newPairs) {
- // assignment to a storage array replaces the complete array
- m_pairsOfFlags = newPairs;
- }
- function setFlagPair(uint index, bool flagA, bool flagB) {
- // access to a non-existing index will throw an exception
- m_pairsOfFlags[index][0] = flagA;
- m_pairsOfFlags[index][1] = flagB;
- }
- function changeFlagArraySize(uint newSize) {
- // if the new size is smaller, removed array elements will be cleared
- m_pairsOfFlags.length = newSize;
- }
- function clear() {
- // these clear the arrays completely
- delete m_pairsOfFlags;
- delete m_aLotOfIntegers;
- // identical effect here
- m_pairsOfFlags.length = 0;
- }
- bytes m_byteData;
- function byteArrays(bytes data) {
- // byte arrays ("bytes") are different as they are stored without padding,
- // but can be treated identical to "uint8[]"
- m_byteData = data;
- m_byteData.length += 7;
- m_byteData[3] = 8;
- delete m_byteData[2];
- }
- function addFlag(bool[2] flag) returns (uint) {
- return m_pairsOfFlags.push(flag);
- }
- function createMemoryArray(uint size) returns (bytes) {
- // Dynamic memory arrays are created using `new`:
- uint[2][] memory arrayOfPairs = new uint[2][](size);
- // Create a dynamic byte array:
- bytes memory b = new bytes(200);
- for (uint i = 0; i < b.length; i++)
- b[i] = byte(i);
- return b;
- }
+ uint[2**20] m_aLotOfIntegers;
+ // Note that the following is not a pair of arrays but an array of pairs.
+ bool[2][] m_pairsOfFlags;
+ // newPairs is stored in memory - the default for function arguments
+
+ function setAllFlagPairs(bool[2][] newPairs) {
+ // assignment to a storage array replaces the complete array
+ m_pairsOfFlags = newPairs;
+ }
+
+ function setFlagPair(uint index, bool flagA, bool flagB) {
+ // access to a non-existing index will throw an exception
+ m_pairsOfFlags[index][0] = flagA;
+ m_pairsOfFlags[index][1] = flagB;
+ }
+
+ function changeFlagArraySize(uint newSize) {
+ // if the new size is smaller, removed array elements will be cleared
+ m_pairsOfFlags.length = newSize;
+ }
+
+ function clear() {
+ // these clear the arrays completely
+ delete m_pairsOfFlags;
+ delete m_aLotOfIntegers;
+ // identical effect here
+ m_pairsOfFlags.length = 0;
+ }
+
+ bytes m_byteData;
+
+ function byteArrays(bytes data) {
+ // byte arrays ("bytes") are different as they are stored without padding,
+ // but can be treated identical to "uint8[]"
+ m_byteData = data;
+ m_byteData.length += 7;
+ m_byteData[3] = 8;
+ delete m_byteData[2];
+ }
+
+ function addFlag(bool[2] flag) returns (uint) {
+ return m_pairsOfFlags.push(flag);
+ }
+
+ function createMemoryArray(uint size) returns (bytes) {
+ // Dynamic memory arrays are created using `new`:
+ uint[2][] memory arrayOfPairs = new uint[2][](size);
+ // Create a dynamic byte array:
+ bytes memory b = new bytes(200);
+ for (uint i = 0; i < b.length; i++)
+ b[i] = byte(i);
+ return b;
+ }
}
@@ -400,41 +410,46 @@ shown in the following example:
::
contract CrowdFunding {
- // Defines a new type with two fields.
- struct Funder {
- address addr;
- uint amount;
- }
- struct Campaign {
- address beneficiary;
- uint fundingGoal;
- uint numFunders;
- uint amount;
- mapping (uint => Funder) funders;
- }
- uint numCampaigns;
- mapping (uint => Campaign) campaigns;
- function newCampaign(address beneficiary, uint goal) returns (uint campaignID) {
- campaignID = numCampaigns++; // campaignID is return variable
- // Creates new struct and saves in storage. We leave out the mapping type.
- campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0);
- }
- function contribute(uint campaignID) {
- Campaign c = campaigns[campaignID];
+ // Defines a new type with two fields.
+ struct Funder {
+ address addr;
+ uint amount;
+ }
+
+ struct Campaign {
+ address beneficiary;
+ uint fundingGoal;
+ uint numFunders;
+ uint amount;
+ mapping (uint => Funder) funders;
+ }
+
+ uint numCampaigns;
+ mapping (uint => Campaign) campaigns;
+
+ function newCampaign(address beneficiary, uint goal) returns (uint campaignID) {
+ campaignID = numCampaigns++; // campaignID is return variable
+ // Creates new struct and saves in storage. We leave out the mapping type.
+ campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0);
+ }
+
+ function contribute(uint campaignID) {
+ Campaign c = campaigns[campaignID];
// Creates a new temporary memory struct, initialised with the given values
// and copies it over to storage.
// Note that you can also use Funder(msg.sender, msg.value) to initialise.
- c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value});
- c.amount += msg.value;
- }
- function checkGoalReached(uint campaignID) returns (bool reached) {
- Campaign c = campaigns[campaignID];
- if (c.amount < c.fundingGoal)
- return false;
- c.beneficiary.send(c.amount);
- c.amount = 0;
- return true;
- }
+ c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value});
+ c.amount += msg.value;
+ }
+
+ function checkGoalReached(uint campaignID) returns (bool reached) {
+ Campaign c = campaigns[campaignID];
+ if (c.amount < c.fundingGoal)
+ return false;
+ c.beneficiary.send(c.amount);
+ c.amount = 0;
+ return true;
+ }
}
The contract does not provide the full functionality of a crowdfunding
@@ -495,18 +510,19 @@ It is important to note that `delete a` really behaves like an assignment to `a`
::
contract DeleteExample {
- uint data;
- uint[] dataArray;
- function f() {
- uint x = data;
- delete x; // sets x to 0, does not affect data
- delete data; // sets data to 0, does not affect x which still holds a copy
- uint[] y = dataArray;
- delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also
- // y is affected which is an alias to the storage object
- // On the other hand: "delete y" is not valid, as assignments to local variables
- // referencing storage objects can only be made from existing storage objects.
- }
+ uint data;
+ uint[] dataArray;
+
+ function f() {
+ uint x = data;
+ delete x; // sets x to 0, does not affect data
+ delete data; // sets data to 0, does not affect x which still holds a copy
+ uint[] y = dataArray;
+ delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also
+ // y is affected which is an alias to the storage object
+ // On the other hand: "delete y" is not valid, as assignments to local variables
+ // referencing storage objects can only be made from existing storage objects.
+ }
}
.. index:: ! type;conversion, ! cast
diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst
index 05fb4b3c..9ddf52b1 100644
--- a/docs/units-and-global-variables.rst
+++ b/docs/units-and-global-variables.rst
@@ -35,7 +35,7 @@ These suffixes cannot be applied to variables. If you want to
interpret some input variable in e.g. days, you can do it in the following way::
function f(uint start, uint daysAfter) {
- if (now >= start + daysAfter * 1 days) { ... }
+ if (now >= start + daysAfter * 1 days) { ... }
}
Special Variables and Functions