Changed whitespace formatting

This commit is contained in:
Denton Liu 2016-05-18 11:05:28 -04:00
parent ff26ea6c08
commit 7c22a387f3
9 changed files with 219 additions and 186 deletions

View File

@ -179,6 +179,7 @@ function finishes.
AreWeDoneYet, AreWeDoneYet,
Finished Finished
} }
// This is the current stage. // This is the current stage.
Stages public stage = Stages.AcceptingBlindedBids; Stages public stage = Stages.AcceptingBlindedBids;
@ -188,9 +189,11 @@ function finishes.
if (stage != _stage) throw; if (stage != _stage) throw;
_ _
} }
function nextStage() internal { function nextStage() internal {
stage = Stages(uint(stage) + 1); stage = Stages(uint(stage) + 1);
} }
// Perform timed transitions. Be sure to mention // Perform timed transitions. Be sure to mention
// this modifier first, otherwise the guards // this modifier first, otherwise the guards
// will not take the new stage into account. // will not take the new stage into account.
@ -211,6 +214,7 @@ function finishes.
{ {
// We will not implement that here // We will not implement that here
} }
function reveal() function reveal()
timedTransitions timedTransitions
atStage(Stages.RevealBids) atStage(Stages.RevealBids)
@ -227,6 +231,7 @@ function finishes.
_ _
nextStage(); nextStage();
} }
function g() function g()
timedTransitions timedTransitions
atStage(Stages.AnotherStage) atStage(Stages.AnotherStage)
@ -235,12 +240,14 @@ function finishes.
// If you want to use `return` here, // If you want to use `return` here,
// you have to call `nextStage()` manually. // you have to call `nextStage()` manually.
} }
function h() function h()
timedTransitions timedTransitions
atStage(Stages.AreWeDoneYet) atStage(Stages.AreWeDoneYet)
transitionNext transitionNext
{ {
} }
function i() function i()
timedTransitions timedTransitions
atStage(Stages.Finished) atStage(Stages.Finished)

View File

@ -25,27 +25,28 @@ API, this is done as follows::
// The json abi array generated by the compiler // The json abi array generated by the compiler
var abiArray = [ var abiArray = [
{ {
"inputs":[ "inputs":[
{"name":"x","type":"uint256"}, {"name":"x","type":"uint256"},
{"name":"y","type":"uint256"} {"name":"y","type":"uint256"}
], ],
"type":"constructor" "type":"constructor"
}, },
{ {
"constant":true, "constant":true,
"inputs":[], "inputs":[],
"name":"x", "name":"x",
"outputs":[{"name":"","type":"bytes32"}], "outputs":[{"name":"","type":"bytes32"}],
"type":"function" "type":"function"
} }
]; ];
var MyContract = web3.eth.contract(abiArray); var MyContract = web3.eth.contract(abiArray);
// deploy new contract // deploy new contract
var contractInstance = MyContract.new( var contractInstance = MyContract.new(
10, 11, 10,
{from: myAccount, gas: 1000000} 11,
{from: myAccount, gas: 1000000}
); );
.. index:: constructor;arguments .. index:: constructor;arguments
@ -375,13 +376,13 @@ possible.
contract Caller { contract Caller {
function callTest(address testAddress) { function callTest(address testAddress) {
Test(testAddress).call(0xabcdef01); // hash does not exist Test(testAddress).call(0xabcdef01); // hash does not exist
// results in Test(testAddress).x becoming == 1. // results in Test(testAddress).x becoming == 1.
Rejector r = Rejector(0x123); Rejector r = Rejector(0x123);
r.send(2 ether); r.send(2 ether);
// results in r.balance == 0 // results in r.balance == 0
} }
} }
.. index:: ! event .. index:: ! event

View File

@ -55,6 +55,8 @@ of other contracts, the amount of Wei sent with the call and the gas can be spec
contract InfoFeed { contract InfoFeed {
function info() returns (uint ret) { return 42; } function info() returns (uint ret) { return 42; }
} }
contract Consumer { contract Consumer {
InfoFeed feed; InfoFeed feed;
function setFeed(address addr) { feed = InfoFeed(addr); } function setFeed(address addr) { feed = InfoFeed(addr); }
@ -77,10 +79,12 @@ of unused parameters (especially return parameters) can be omitted.
contract c { contract c {
function f(uint key, uint value) { ... } function f(uint key, uint value) { ... }
function g() { function g() {
// named arguments // named arguments
f({value: 2, key: 3}); f({value: 2, key: 3});
} }
// omitted parameters // omitted parameters
function func(uint k, uint) returns(uint) { function func(uint k, uint) returns(uint) {
return k; return k;
@ -212,7 +216,7 @@ In the following example, we show how `throw` can be used to easily revert an Et
contract Sharer { contract Sharer {
function sendHalf(address addr) returns (uint balance) { 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 throw; // also reverts the transfer to Sharer
return this.balance; return this.balance;
} }
@ -290,6 +294,7 @@ you really know what you are doing.
for (uint i = 0; i < _data.length; ++i) for (uint i = 0; i < _data.length; ++i)
o_sum += _data[i]; o_sum += _data[i];
} }
// We know that we only access the array in bounds, so we can avoid the check. // 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 // 0x20 needs to be added to an array because the first slot contains the
// array length. // array length.

View File

@ -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:: 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; mapping(string => address) usedContracts;
} }
function somefunction{ function somefunction {
user user1; user user1;
user1.usedContracts["Hello"] = "World"; user1.usedContracts["Hello"] = "World";
user user2 = user1; 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:: In this example::
contract B {} contract B {}
contract A { contract A {
address child; address child;
@ -758,21 +760,21 @@ Sure. Take care that if you cross the memory / storage boundary,
independent copies will be created:: independent copies will be created::
contract C { contract C {
uint[20] x; uint[20] x;
function f() { function f() {
g(x); g(x);
h(x); h(x);
} }
function g(uint[20] y) { function g(uint[20] y) {
y[2] = 3; y[2] = 3;
} }
function h(uint[20] storage y) { function h(uint[20] storage y) {
y[3] = 4; y[3] = 4;
} }
} }
The call to `g(x)` will not have an effect on `x` because it needs 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 to create an independent copy of the storage value in memory

View File

@ -51,9 +51,11 @@ There are some types in Solidity's type system that have no counterpart in the s
if (useB) f = b; if (useB) f = b;
return f(x); return f(x);
} }
function a(uint x) returns (uint z) { function a(uint x) returns (uint z) {
return x * x; return x * x;
} }
function b(uint x) returns (uint z) { function b(uint x) returns (uint z) {
return 2 * x; return 2 * x;
} }

View File

@ -292,7 +292,7 @@ activate themselves.
} }
Blind Auction Blind Auction
================ =============
The previous open auction is extended to a blind auction The previous open auction is extended to a blind auction
in the following. The advantage of a blind auction is in the following. The advantage of a blind auction is

View File

@ -21,8 +21,8 @@ State variables are values which are permanently stored in contract storage.
:: ::
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
@ -39,9 +39,9 @@ Functions are the executable units of code within a contract.
:: ::
contract SimpleAuction { contract SimpleAuction {
function bid() { // Function function bid() { // Function
// ... // ...
} }
} }
:ref:`function-calls` can happen internally or externally :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 { contract Purchase {
address public seller; address public seller;
modifier onlySeller() { // Modifier modifier onlySeller() { // Modifier
if (msg.sender != seller) throw; if (msg.sender != seller) throw;
_ _
} }
function abort() onlySeller { // Modifier usage function abort() onlySeller { // Modifier usage
// ... // ...
} }
} }
.. _structure-events: .. _structure-events:
@ -81,12 +81,12 @@ Events are convenience interfaces with the EVM logging facilities.
:: ::
contract SimpleAuction { contract SimpleAuction {
event HighestBidIncreased(address bidder, uint amount); // Event event HighestBidIncreased(address bidder, uint amount); // Event
function bid() { function bid() {
// ... // ...
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
@ -103,12 +103,12 @@ Structs are custom defined types that can group several variables (see
:: ::
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:
@ -122,5 +122,5 @@ Enums can be used to create custom types with a finite set of values (see
:: ::
contract Purchase { contract Purchase {
enum State { Created, Locked, Inactive } // Enum enum State { Created, Locked, Inactive } // Enum
} }

View File

@ -171,21 +171,21 @@ to and from all integer types but implicit conversion is not allowed.
enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }
ActionChoices choice; ActionChoices choice;
ActionChoices constant defaultChoice = ActionChoices.GoStraight; ActionChoices constant defaultChoice = ActionChoices.GoStraight;
function setGoStraight()
{ function setGoStraight() {
choice = ActionChoices.GoStraight; choice = ActionChoices.GoStraight;
} }
// Since enum types are not part of the ABI, the signature of "getChoice" // Since enum types are not part of the ABI, the signature of "getChoice"
// will automatically be changed to "getChoice() returns (uint8)" // will automatically be changed to "getChoice() returns (uint8)"
// for all matters external to Solidity. The integer type used is just // 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, // large enough to hold all enum values, i.e. if you have more values,
// `uint16` will be used and so on. // `uint16` will be used and so on.
function getChoice() returns (ActionChoices) function getChoice() returns (ActionChoices) {
{
return choice; return choice;
} }
function getDefaultChoice() returns (uint)
{ function getDefaultChoice() returns (uint) {
return uint(defaultChoice); return uint(defaultChoice);
} }
} }
@ -226,26 +226,28 @@ memory-stored reference type does not create a copy.
:: ::
contract c { contract C {
uint[] x; // the data location of x is storage uint[] x; // the data location of x is storage
// the data location of memoryArray is memory
function f(uint[] memoryArray) { // the data location of memoryArray is memory
x = memoryArray; // works, copies the whole array to storage function f(uint[] memoryArray) {
var y = x; // works, assigns a pointer, data location of y is storage x = memoryArray; // works, copies the whole array to storage
y[7]; // fine, returns the 8th element var y = x; // works, assigns a pointer, data location of y is storage
y.length = 2; // fine, modifies x through y y[7]; // fine, returns the 8th element
delete x; // fine, clears the array, also modifies y y.length = 2; // fine, modifies x through y
// The following does not work; it would need to create a new temporary / delete x; // fine, clears the array, also modifies y
// unnamed array in storage, but storage is "statically" allocated: // The following does not work; it would need to create a new temporary /
// y = memoryArray; // unnamed array in storage, but storage is "statically" allocated:
// This does not work either, since it would "reset" the pointer, but there // y = memoryArray;
// is no sensible location it could point to. // This does not work either, since it would "reset" the pointer, but there
// delete y; // is no sensible location it could point to.
g(x); // calls g, handing over a reference to x // delete y;
h(x); // calls h and creates an independent, temporary copy in memory 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) {}
function g(uint[] storage storageArray) internal {}
function h(uint[] memoryArray) {}
} }
Summary Summary
@ -303,12 +305,12 @@ the `.length` member.
:: ::
contract C { contract C {
function f(uint len) { function f(uint len) {
uint[] memory a = new uint[](7); uint[] memory a = new uint[](7);
bytes memory b = new bytes(len); bytes memory b = new bytes(len);
// Here we have a.length == 7 and b.length == len // Here we have a.length == 7 and b.length == len
a[6] = 8; a[6] = 8;
} }
} }
@ -339,51 +341,59 @@ Members
:: ::
contract ArrayContract { contract ArrayContract {
uint[2**20] m_aLotOfIntegers; uint[2**20] m_aLotOfIntegers;
// Note that the following is not a pair of arrays but an array of pairs. // Note that the following is not a pair of arrays but an array of pairs.
bool[2][] m_pairsOfFlags; bool[2][] m_pairsOfFlags;
// newPairs is stored in memory - the default for function arguments // newPairs is stored in memory - the default for function arguments
function setAllFlagPairs(bool[2][] newPairs) {
// assignment to a storage array replaces the complete array function setAllFlagPairs(bool[2][] newPairs) {
m_pairsOfFlags = 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; function setFlagPair(uint index, bool flagA, bool flagB) {
m_pairsOfFlags[index][1] = flagB; // access to a non-existing index will throw an exception
} m_pairsOfFlags[index][0] = flagA;
function changeFlagArraySize(uint newSize) { m_pairsOfFlags[index][1] = flagB;
// if the new size is smaller, removed array elements will be cleared }
m_pairsOfFlags.length = newSize;
} function changeFlagArraySize(uint newSize) {
function clear() { // if the new size is smaller, removed array elements will be cleared
// these clear the arrays completely m_pairsOfFlags.length = newSize;
delete m_pairsOfFlags; }
delete m_aLotOfIntegers;
// identical effect here function clear() {
m_pairsOfFlags.length = 0; // these clear the arrays completely
} delete m_pairsOfFlags;
bytes m_byteData; delete m_aLotOfIntegers;
function byteArrays(bytes data) { // identical effect here
// byte arrays ("bytes") are different as they are stored without padding, m_pairsOfFlags.length = 0;
// but can be treated identical to "uint8[]" }
m_byteData = data;
m_byteData.length += 7; bytes m_byteData;
m_byteData[3] = 8;
delete m_byteData[2]; function byteArrays(bytes data) {
} // byte arrays ("bytes") are different as they are stored without padding,
function addFlag(bool[2] flag) returns (uint) { // but can be treated identical to "uint8[]"
return m_pairsOfFlags.push(flag); m_byteData = data;
} m_byteData.length += 7;
function createMemoryArray(uint size) returns (bytes) { m_byteData[3] = 8;
// Dynamic memory arrays are created using `new`: delete m_byteData[2];
uint[2][] memory arrayOfPairs = new uint[2][](size); }
// Create a dynamic byte array:
bytes memory b = new bytes(200); function addFlag(bool[2] flag) returns (uint) {
for (uint i = 0; i < b.length; i++) return m_pairsOfFlags.push(flag);
b[i] = byte(i); }
return b;
} 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 { contract CrowdFunding {
// Defines a new type with two fields. // Defines a new type with two fields.
struct Funder { struct Funder {
address addr; address addr;
uint amount; uint amount;
} }
struct Campaign {
address beneficiary; struct Campaign {
uint fundingGoal; address beneficiary;
uint numFunders; uint fundingGoal;
uint amount; uint numFunders;
mapping (uint => Funder) funders; uint amount;
} mapping (uint => Funder) funders;
uint numCampaigns; }
mapping (uint => Campaign) campaigns;
function newCampaign(address beneficiary, uint goal) returns (uint campaignID) { uint numCampaigns;
campaignID = numCampaigns++; // campaignID is return variable mapping (uint => Campaign) campaigns;
// Creates new struct and saves in storage. We leave out the mapping type.
campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0); function newCampaign(address beneficiary, uint goal) returns (uint campaignID) {
} campaignID = numCampaigns++; // campaignID is return variable
function contribute(uint campaignID) { // Creates new struct and saves in storage. We leave out the mapping type.
Campaign c = campaigns[campaignID]; 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 // Creates a new temporary memory struct, initialised with the given values
// and copies it over to storage. // and copies it over to storage.
// Note that you can also use Funder(msg.sender, msg.value) to initialise. // 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.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value});
c.amount += msg.value; c.amount += msg.value;
} }
function checkGoalReached(uint campaignID) returns (bool reached) {
Campaign c = campaigns[campaignID]; function checkGoalReached(uint campaignID) returns (bool reached) {
if (c.amount < c.fundingGoal) Campaign c = campaigns[campaignID];
return false; if (c.amount < c.fundingGoal)
c.beneficiary.send(c.amount); return false;
c.amount = 0; c.beneficiary.send(c.amount);
return true; c.amount = 0;
} return true;
}
} }
The contract does not provide the full functionality of a crowdfunding 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 { contract DeleteExample {
uint data; uint data;
uint[] dataArray; uint[] dataArray;
function f() {
uint x = data; function f() {
delete x; // sets x to 0, does not affect data uint x = data;
delete data; // sets data to 0, does not affect x which still holds a copy delete x; // sets x to 0, does not affect data
uint[] y = dataArray; delete data; // sets data to 0, does not affect x which still holds a copy
delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also uint[] y = dataArray;
// y is affected which is an alias to the storage object delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also
// On the other hand: "delete y" is not valid, as assignments to local variables // y is affected which is an alias to the storage object
// referencing storage objects can only be made from existing storage objects. // 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 .. index:: ! type;conversion, ! cast

View File

@ -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:: interpret some input variable in e.g. days, you can do it in the following way::
function f(uint start, uint daysAfter) { function f(uint start, uint daysAfter) {
if (now >= start + daysAfter * 1 days) { ... } if (now >= start + daysAfter * 1 days) { ... }
} }
Special Variables and Functions Special Variables and Functions