Fix Solidity warnings

This commit is contained in:
Jim McDonald 2017-12-12 18:47:30 +00:00
parent 7614b16dc9
commit 6e521d59b0
13 changed files with 291 additions and 250 deletions

View File

@ -190,9 +190,9 @@ Given the contract:
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract Foo { contract Foo {
function bar(bytes3[2] xy) {} function bar(bytes3[2] xy) public {}
function baz(uint32 x, bool y) returns (bool r) { r = x > 32 || y; } function baz(uint32 x, bool y) public returns (bool r) { r = x > 32 || y; }
function sam(bytes name, bool z, uint[] data) {} function sam(bytes name, bool z, uint[] data) public {}
} }
@ -333,10 +333,10 @@ For example,
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract Test { contract Test {
function Test(){ b = 0x12345678901234567890123456789012; } function Test() public { b = 0x12345678901234567890123456789012; }
event Event(uint indexed a, bytes32 b); event Event(uint indexed a, bytes32 b);
event Event2(uint indexed a, bytes32 b); event Event2(uint indexed a, bytes32 b);
function foo(uint a) { Event(a, b); } function foo(uint a) public { Event(a, b); }
bytes32 b; bytes32 b;
} }
@ -383,8 +383,8 @@ As an example, the code
contract Test { contract Test {
struct S { uint a; uint[] b; T[] c; } struct S { uint a; uint[] b; T[] c; }
struct T { uint x; uint y; } struct T { uint x; uint y; }
function f(S s, T t, uint a) { } function f(S s, T t, uint a) public { }
function g() returns (S s, T t, uint a) {} function g() public returns (S s, T t, uint a) {}
} }
would result in the JSON: would result in the JSON:

View File

@ -23,7 +23,7 @@ arising when writing manual assembly by the following features:
* functional-style opcodes: ``mul(1, add(2, 3))`` instead of ``push1 3 push1 2 add push1 1 mul`` * functional-style opcodes: ``mul(1, add(2, 3))`` instead of ``push1 3 push1 2 add push1 1 mul``
* assembly-local variables: ``let x := add(2, 3) let y := mload(0x40) x := add(x, y)`` * assembly-local variables: ``let x := add(2, 3) let y := mload(0x40) x := add(x, y)``
* access to external variables: ``function f(uint x) { assembly { x := sub(x, 1) } }`` * access to external variables: ``function f(uint x) public { assembly { x := sub(x, 1) } }``
* labels: ``let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0))`` * labels: ``let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0))``
* loops: ``for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) }`` * loops: ``for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) }``
* if statements: ``if slt(x, 0) { x := sub(0, x) }`` * if statements: ``if slt(x, 0) { x := sub(0, x) }``
@ -54,7 +54,7 @@ idea is that assembly libraries will be used to enhance the language in such way
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
library GetCode { library GetCode {
function at(address _addr) returns (bytes o_code) { function at(address _addr) public returns (bytes o_code) {
assembly { assembly {
// retrieve the size of the code, this needs assembly // retrieve the size of the code, this needs assembly
let size := extcodesize(_addr) let size := extcodesize(_addr)
@ -83,7 +83,7 @@ you really know what you are doing.
library VectorSum { library VectorSum {
// This function is less efficient because the optimizer currently fails to // This function is less efficient because the optimizer currently fails to
// remove the bounds checks in array access. // remove the bounds checks in array access.
function sumSolidity(uint[] _data) returns (uint o_sum) { function sumSolidity(uint[] _data) public returns (uint o_sum) {
for (uint i = 0; i < _data.length; ++i) for (uint i = 0; i < _data.length; ++i)
o_sum += _data[i]; o_sum += _data[i];
} }
@ -91,7 +91,7 @@ you really know what you are doing.
// 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.
function sumAsm(uint[] _data) returns (uint o_sum) { function sumAsm(uint[] _data) returns (uint o_sum) public {
for (uint i = 0; i < _data.length; ++i) { for (uint i = 0; i < _data.length; ++i) {
assembly { assembly {
o_sum := add(o_sum, mload(add(add(_data, 0x20), mul(i, 0x20)))) o_sum := add(o_sum, mload(add(add(_data, 0x20), mul(i, 0x20))))
@ -100,7 +100,7 @@ you really know what you are doing.
} }
// Same as above, but accomplish the entire code within inline assembly. // Same as above, but accomplish the entire code within inline assembly.
function sumPureAsm(uint[] _data) returns (uint o_sum) { function sumPureAsm(uint[] _data) returns (uint o_sum) public {
assembly { assembly {
// Load the length (first 32 bytes) // Load the length (first 32 bytes)
let len := mload(_data) let len := mload(_data)
@ -388,7 +388,7 @@ changes during the call, and thus references to local variables will be wrong.
contract C { contract C {
uint b; uint b;
function f(uint x) returns (uint r) { function f(uint x) public returns (uint r) {
assembly { assembly {
r := mul(x, sload(b_slot)) // ignore the offset, we know it is zero r := mul(x, sload(b_slot)) // ignore the offset, we know it is zero
} }
@ -462,7 +462,7 @@ be just ``0``, but it can also be a complex functional-style expression.
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract C { contract C {
function f(uint x) returns (uint b) { function f(uint x) public returns (uint b) {
assembly { assembly {
let v := add(x, 1) let v := add(x, 1)
mstore(0x80, v) mstore(0x80, v)
@ -574,7 +574,7 @@ Simply leave the initialization and post-iteration parts empty.
x := add(x, mload(i)) x := add(x, mload(i))
i := add(i, 0x20) i := add(i, 0x20)
} }
} }
Functions Functions
--------- ---------
@ -713,7 +713,7 @@ We consider the runtime bytecode of the following Solidity program::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract C { contract C {
function f(uint x) returns (uint y) { function f(uint x) public returns (uint y) {
y = 1; y = 1;
for (uint i = 0; i < x; i++) for (uint i = 0; i < x; i++)
y = 2 * y; y = 2 * y;

View File

@ -36,12 +36,12 @@ become the new richest.
mapping (address => uint) pendingWithdrawals; mapping (address => uint) pendingWithdrawals;
function WithdrawalContract() payable { function WithdrawalContract() public payable {
richest = msg.sender; richest = msg.sender;
mostSent = msg.value; mostSent = msg.value;
} }
function becomeRichest() payable returns (bool) { function becomeRichest() public payable returns (bool) {
if (msg.value > mostSent) { if (msg.value > mostSent) {
pendingWithdrawals[richest] += msg.value; pendingWithdrawals[richest] += msg.value;
richest = msg.sender; richest = msg.sender;
@ -52,7 +52,7 @@ become the new richest.
} }
} }
function withdraw() { function withdraw() public {
uint amount = pendingWithdrawals[msg.sender]; uint amount = pendingWithdrawals[msg.sender];
// Remember to zero the pending refund before // Remember to zero the pending refund before
// sending to prevent re-entrancy attacks // sending to prevent re-entrancy attacks
@ -71,12 +71,12 @@ This is as opposed to the more intuitive sending pattern:
address public richest; address public richest;
uint public mostSent; uint public mostSent;
function SendContract() payable { function SendContract() public payable {
richest = msg.sender; richest = msg.sender;
mostSent = msg.value; mostSent = msg.value;
} }
function becomeRichest() payable returns (bool) { function becomeRichest() public payable returns (bool) {
if (msg.value > mostSent) { if (msg.value > mostSent) {
// This line can cause problems (explained below). // This line can cause problems (explained below).
richest.transfer(msg.value); richest.transfer(msg.value);
@ -157,6 +157,7 @@ restrictions highly readable.
/// Make `_newOwner` the new owner of this /// Make `_newOwner` the new owner of this
/// contract. /// contract.
function changeOwner(address _newOwner) function changeOwner(address _newOwner)
public
onlyBy(owner) onlyBy(owner)
{ {
owner = _newOwner; owner = _newOwner;
@ -171,6 +172,7 @@ restrictions highly readable.
/// May only be called 6 weeks after /// May only be called 6 weeks after
/// the contract has been created. /// the contract has been created.
function disown() function disown()
public
onlyBy(owner) onlyBy(owner)
onlyAfter(creationTime + 6 weeks) onlyAfter(creationTime + 6 weeks)
{ {
@ -191,6 +193,7 @@ restrictions highly readable.
} }
function forceOwnerChange(address _newOwner) function forceOwnerChange(address _newOwner)
public
costs(200 ether) costs(200 ether)
{ {
owner = _newOwner; owner = _newOwner;
@ -310,6 +313,7 @@ function finishes.
// Order of the modifiers matters here! // Order of the modifiers matters here!
function bid() function bid()
public
payable payable
timedTransitions timedTransitions
atStage(Stages.AcceptingBlindedBids) atStage(Stages.AcceptingBlindedBids)
@ -318,6 +322,7 @@ function finishes.
} }
function reveal() function reveal()
public
timedTransitions timedTransitions
atStage(Stages.RevealBids) atStage(Stages.RevealBids)
{ {
@ -332,6 +337,7 @@ function finishes.
} }
function g() function g()
public
timedTransitions timedTransitions
atStage(Stages.AnotherStage) atStage(Stages.AnotherStage)
transitionNext transitionNext
@ -339,6 +345,7 @@ function finishes.
} }
function h() function h()
public
timedTransitions timedTransitions
atStage(Stages.AreWeDoneYet) atStage(Stages.AreWeDoneYet)
transitionNext transitionNext
@ -346,6 +353,7 @@ function finishes.
} }
function i() function i()
public
timedTransitions timedTransitions
atStage(Stages.Finished) atStage(Stages.Finished)
{ {

View File

@ -40,7 +40,7 @@ This means that cyclic creation dependencies are impossible.
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract OwnedToken { contract OwnedToken {
// TokenCreator is a contract type that is defined below. // TokenCreator is a contract type that is defined below.
@ -52,7 +52,7 @@ This means that cyclic creation dependencies are impossible.
// This is the constructor which registers the // This is the constructor which registers the
// creator and the assigned name. // creator and the assigned name.
function OwnedToken(bytes32 _name) { function OwnedToken(bytes32 _name) public {
// State variables are accessed via their name // State variables are accessed via their name
// and not via e.g. this.owner. This also applies // and not via e.g. this.owner. This also applies
// to functions and especially in the constructors, // to functions and especially in the constructors,
@ -67,7 +67,7 @@ This means that cyclic creation dependencies are impossible.
name = _name; name = _name;
} }
function changeName(bytes32 newName) { function changeName(bytes32 newName) public {
// Only the creator can alter the name -- // Only the creator can alter the name --
// the comparison is possible since contracts // the comparison is possible since contracts
// are implicitly convertible to addresses. // are implicitly convertible to addresses.
@ -75,7 +75,7 @@ This means that cyclic creation dependencies are impossible.
name = newName; name = newName;
} }
function transfer(address newOwner) { function transfer(address newOwner) public {
// Only the current owner can transfer the token. // Only the current owner can transfer the token.
if (msg.sender != owner) return; if (msg.sender != owner) return;
// We also want to ask the creator if the transfer // We also want to ask the creator if the transfer
@ -90,6 +90,7 @@ This means that cyclic creation dependencies are impossible.
contract TokenCreator { contract TokenCreator {
function createToken(bytes32 name) function createToken(bytes32 name)
public
returns (OwnedToken tokenAddress) returns (OwnedToken tokenAddress)
{ {
// Create a new Token contract and return its address. // Create a new Token contract and return its address.
@ -99,16 +100,17 @@ This means that cyclic creation dependencies are impossible.
return new OwnedToken(name); return new OwnedToken(name);
} }
function changeName(OwnedToken tokenAddress, bytes32 name) { function changeName(OwnedToken tokenAddress, bytes32 name) public {
// Again, the external type of "tokenAddress" is // Again, the external type of "tokenAddress" is
// simply "address". // simply "address".
tokenAddress.changeName(name); tokenAddress.changeName(name);
} }
function isTokenTransferOK( function isTokenTransferOK(address currentOwner, address newOwner)
address currentOwner, public
address newOwner view
) returns (bool ok) { returns (bool ok)
{
// Check some arbitrary condition. // Check some arbitrary condition.
address tokenAddress = msg.sender; address tokenAddress = msg.sender;
return (keccak256(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff); return (keccak256(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff);
@ -171,10 +173,10 @@ return parameter list for functions.
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract C { contract C {
function f(uint a) private returns (uint b) { return a + 1; } function f(uint a) private pure returns (uint b) { return a + 1; }
function setData(uint a) internal { data = a; } function setData(uint a) internal { data = a; }
uint public data; uint public data;
} }
@ -193,13 +195,13 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value
uint private data; uint private data;
function f(uint a) private returns(uint b) { return a + 1; } function f(uint a) private returns(uint b) { return a + 1; }
function setData(uint a) { data = a; } function setData(uint a) public { data = a; }
function getData() public returns(uint) { return data; } function getData() public returns(uint) { return data; }
function compute(uint a, uint b) internal returns (uint) { return a+b; } function compute(uint a, uint b) internal returns (uint) { return a+b; }
} }
contract D { contract D {
function readData() { function readData() public {
C c = new C(); C c = new C();
uint local = c.f(7); // error: member "f" is not visible uint local = c.f(7); // error: member "f" is not visible
c.setData(3); c.setData(3);
@ -209,7 +211,7 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value
} }
contract E is C { contract E is C {
function g() { function g() public {
C c = new C(); C c = new C();
uint val = compute(3, 5); // access to internal member (from derived to parent contract) uint val = compute(3, 5); // access to internal member (from derived to parent contract)
} }
@ -238,7 +240,7 @@ be done at declaration.
contract Caller { contract Caller {
C c = new C(); C c = new C();
function f() { function f() public {
uint local = c.data(); uint local = c.data();
} }
} }
@ -254,7 +256,7 @@ it is evaluated as a state variable. If it is accessed externally
contract C { contract C {
uint public data; uint public data;
function x() { function x() public {
data = 3; // internal access data = 3; // internal access
uint val = this.data(); // external access uint val = this.data(); // external access
} }
@ -277,7 +279,7 @@ The next example is a bit more complex:
It will generate a function of the following form:: 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) public returns (uint a, bytes3 b) {
a = data[arg1][arg2][arg3].a; a = data[arg1][arg2][arg3].a;
b = data[arg1][arg2][arg3].b; b = data[arg1][arg2][arg3].b;
} }
@ -302,7 +304,7 @@ inheritable properties of contracts and may be overridden by derived contracts.
pragma solidity ^0.4.11; pragma solidity ^0.4.11;
contract owned { contract owned {
function owned() { owner = msg.sender; } function owned() public { owner = msg.sender; }
address owner; address owner;
// This contract only defines a modifier but does not use // This contract only defines a modifier but does not use
@ -323,7 +325,7 @@ inheritable properties of contracts and may be overridden by derived contracts.
// "owned" and applies it to the "close"-function, which // "owned" and applies it to the "close"-function, which
// causes that calls to "close" only have an effect if // causes that calls to "close" only have an effect if
// they are made by the stored owner. // they are made by the stored owner.
function close() onlyOwner { function close() public onlyOwner {
selfdestruct(owner); selfdestruct(owner);
} }
} }
@ -341,16 +343,16 @@ inheritable properties of contracts and may be overridden by derived contracts.
mapping (address => bool) registeredAddresses; mapping (address => bool) registeredAddresses;
uint price; uint price;
function Register(uint initialPrice) { price = initialPrice; } function Register(uint initialPrice) public { price = initialPrice; }
// It is important to also provide the // It is important to also provide the
// "payable" keyword here, otherwise the function will // "payable" keyword here, otherwise the function will
// automatically reject all Ether sent to it. // automatically reject all Ether sent to it.
function register() payable costs(price) { function register() public payable costs(price) {
registeredAddresses[msg.sender] = true; registeredAddresses[msg.sender] = true;
} }
function changePrice(uint _price) onlyOwner { function changePrice(uint _price) public onlyOwner {
price = _price; price = _price;
} }
} }
@ -368,7 +370,7 @@ inheritable properties of contracts and may be overridden by derived contracts.
/// reentrant calls from within msg.sender.call cannot call f again. /// reentrant calls from within msg.sender.call cannot call f again.
/// The `return 7` statement assigns 7 to the return value but still /// The `return 7` statement assigns 7 to the return value but still
/// executes the statement `locked = false` in the modifier. /// executes the statement `locked = false` in the modifier.
function f() noReentrancy returns (uint) { function f() public noReentrancy returns (uint) {
require(msg.sender.call()); require(msg.sender.call());
return 7; return 7;
} }
@ -459,7 +461,7 @@ The following statements are considered modifying the state:
pragma solidity ^0.4.16; pragma solidity ^0.4.16;
contract C { contract C {
function f(uint a, uint b) view returns (uint) { function f(uint a, uint b) public view returns (uint) {
return a * (b + 42) + now; return a * (b + 42) + now;
} }
} }
@ -495,7 +497,7 @@ In addition to the list of state modifying statements explained above, the follo
pragma solidity ^0.4.16; pragma solidity ^0.4.16;
contract C { contract C {
function f(uint a, uint b) pure returns (uint) { function f(uint a, uint b) public pure returns (uint) {
return a * (b + 42); return a * (b + 42);
} }
} }
@ -561,7 +563,7 @@ Please ensure you test your fallback function thoroughly to ensure the execution
// Sending Ether to this contract will cause an exception, // Sending Ether to this contract will cause an exception,
// because the fallback function does not have the "payable" // because the fallback function does not have the "payable"
// modifier. // modifier.
function() { x = 1; } function() public { x = 1; }
uint x; uint x;
} }
@ -569,11 +571,11 @@ Please ensure you test your fallback function thoroughly to ensure the execution
// This contract keeps all Ether sent to it with no way // This contract keeps all Ether sent to it with no way
// to get it back. // to get it back.
contract Sink { contract Sink {
function() payable { } function() public payable { }
} }
contract Caller { contract Caller {
function callTest(Test test) { function callTest(Test test) public {
test.call(0xabcdef01); // hash does not exist test.call(0xabcdef01); // hash does not exist
// results in test.x becoming == 1. // results in test.x becoming == 1.
@ -597,7 +599,7 @@ This also applies to inherited functions. The following example shows overloadin
``f`` function in the scope of contract ``A``. ``f`` function in the scope of contract ``A``.
:: ::
pragma solidity ^0.4.16; pragma solidity ^0.4.16;
contract A { contract A {
@ -721,7 +723,7 @@ All non-indexed arguments will be stored in the data part of the log.
uint _value uint _value
); );
function deposit(bytes32 _id) payable { function deposit(bytes32 _id) public payable {
// Any call to this function (even deeply nested) can // Any call to this function (even deeply nested) can
// be detected from the JavaScript API by filtering // be detected from the JavaScript API by filtering
// for `Deposit` to be called. // for `Deposit` to be called.
@ -770,7 +772,7 @@ as topics. The event call above can be performed in the same way as
pragma solidity ^0.4.10; pragma solidity ^0.4.10;
contract C { contract C {
function f() { function f() public payable {
bytes32 _id = 0x420042; bytes32 _id = 0x420042;
log3( log3(
bytes32(msg.value), bytes32(msg.value),
@ -814,7 +816,7 @@ Details are given in the following example.
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract owned { contract owned {
function owned() { owner = msg.sender; } function owned() { owner = msg.sender; }
@ -836,12 +838,12 @@ Details are given in the following example.
// without body. If a contract does not implement all // without body. If a contract does not implement all
// functions it can only be used as an interface. // functions it can only be used as an interface.
contract Config { contract Config {
function lookup(uint id) returns (address adr); function lookup(uint id) public returns (address adr);
} }
contract NameReg { contract NameReg {
function register(bytes32 name); function register(bytes32 name) public;
function unregister(); function unregister() public;
} }
// Multiple inheritance is possible. Note that "owned" is // Multiple inheritance is possible. Note that "owned" is
@ -849,7 +851,7 @@ Details are given in the following example.
// instance of "owned" (as for virtual inheritance in C++). // instance of "owned" (as for virtual inheritance in C++).
contract named is owned, mortal { contract named is owned, mortal {
function named(bytes32 name) { function named(bytes32 name) {
Config config = Config(0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970); Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);
NameReg(config.lookup(1)).register(name); NameReg(config.lookup(1)).register(name);
} }
@ -858,9 +860,9 @@ Details are given in the following example.
// types of output parameters, that causes an error. // types of output parameters, that causes an error.
// Both local and message-based function calls take these overrides // Both local and message-based function calls take these overrides
// into account. // into account.
function kill() { function kill() public {
if (msg.sender == owner) { if (msg.sender == owner) {
Config config = Config(0xd5f9d8d94886e70b06e474c3fb14fd43e2f23970); Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);
NameReg(config.lookup(1)).unregister(); NameReg(config.lookup(1)).unregister();
// It is still possible to call a specific // It is still possible to call a specific
// overridden function. // overridden function.
@ -873,11 +875,11 @@ Details are given in the following example.
// provided in the header (or modifier-invocation-style at // provided in the header (or modifier-invocation-style at
// the constructor of the derived contract (see below)). // the constructor of the derived contract (see below)).
contract PriceFeed is owned, mortal, named("GoldFeed") { contract PriceFeed is owned, mortal, named("GoldFeed") {
function updateInfo(uint newInfo) { function updateInfo(uint newInfo) public {
if (msg.sender == owner) info = newInfo; if (msg.sender == owner) info = newInfo;
} }
function get() constant returns(uint r) { return info; } function get() public view returns(uint r) { return info; }
uint info; uint info;
} }
@ -889,22 +891,22 @@ seen in the following example::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract owned { contract owned {
function owned() { owner = msg.sender; } function owned() public { owner = msg.sender; }
address owner; address owner;
} }
contract mortal is owned { contract mortal is owned {
function kill() { function kill() public {
if (msg.sender == owner) selfdestruct(owner); if (msg.sender == owner) selfdestruct(owner);
} }
} }
contract Base1 is mortal { contract Base1 is mortal {
function kill() { /* do cleanup 1 */ mortal.kill(); } function kill() public { /* do cleanup 1 */ mortal.kill(); }
} }
contract Base2 is mortal { contract Base2 is mortal {
function kill() { /* do cleanup 2 */ mortal.kill(); } function kill() public { /* do cleanup 2 */ mortal.kill(); }
} }
contract Final is Base1, Base2 { contract Final is Base1, Base2 {
@ -918,23 +920,23 @@ derived override, but this function will bypass
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract owned { contract owned {
function owned() { owner = msg.sender; } function owned() public { owner = msg.sender; }
address owner; address owner;
} }
contract mortal is owned { contract mortal is owned {
function kill() { function kill() public {
if (msg.sender == owner) selfdestruct(owner); if (msg.sender == owner) selfdestruct(owner);
} }
} }
contract Base1 is mortal { contract Base1 is mortal {
function kill() { /* do cleanup 1 */ super.kill(); } function kill() public { /* do cleanup 1 */ super.kill(); }
} }
contract Base2 is mortal { contract Base2 is mortal {
function kill() { /* do cleanup 2 */ super.kill(); } function kill() public { /* do cleanup 2 */ super.kill(); }
} }
contract Final is Base2, Base1 { contract Final is Base2, Base1 {
@ -963,11 +965,11 @@ the base constructors. This can be done in two ways::
contract Base { contract Base {
uint x; uint x;
function Base(uint _x) { x = _x; } function Base(uint _x) public { x = _x; }
} }
contract Derived is Base(7) { contract Derived is Base(7) {
function Derived(uint _y) Base(_y * _y) { function Derived(uint _y) Base(_y * _y) public {
} }
} }
@ -1032,7 +1034,7 @@ Contract functions can lack an implementation as in the following example (note
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract Feline { contract Feline {
function utterance() returns (bytes32); function utterance() public returns (bytes32);
} }
Such contracts cannot be compiled (even if they contain Such contracts cannot be compiled (even if they contain
@ -1042,11 +1044,11 @@ but they can be used as base contracts::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract Feline { contract Feline {
function utterance() returns (bytes32); function utterance() public returns (bytes32);
} }
contract Cat is Feline { contract Cat is Feline {
function utterance() returns (bytes32) { return "miaow"; } function utterance() public returns (bytes32) { return "miaow"; }
} }
If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it will itself be abstract. If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it will itself be abstract.
@ -1077,7 +1079,7 @@ Interfaces are denoted by their own keyword:
pragma solidity ^0.4.11; pragma solidity ^0.4.11;
interface Token { interface Token {
function transfer(address recipient, uint amount); function transfer(address recipient, uint amount) public;
} }
Contracts can inherit interfaces as they would inherit other contracts. Contracts can inherit interfaces as they would inherit other contracts.
@ -1120,7 +1122,7 @@ more advanced example to implement a set).
:: ::
pragma solidity ^0.4.11; pragma solidity ^0.4.16;
library Set { library Set {
// We define a new struct datatype that will be used to // We define a new struct datatype that will be used to
@ -1134,6 +1136,7 @@ more advanced example to implement a set).
// to call the first parameter 'self', if the function can // to call the first parameter 'self', if the function can
// be seen as a method of that object. // be seen as a method of that object.
function insert(Data storage self, uint value) function insert(Data storage self, uint value)
public
returns (bool) returns (bool)
{ {
if (self.flags[value]) if (self.flags[value])
@ -1143,6 +1146,7 @@ more advanced example to implement a set).
} }
function remove(Data storage self, uint value) function remove(Data storage self, uint value)
public
returns (bool) returns (bool)
{ {
if (!self.flags[value]) if (!self.flags[value])
@ -1152,6 +1156,8 @@ more advanced example to implement a set).
} }
function contains(Data storage self, uint value) function contains(Data storage self, uint value)
public
view
returns (bool) returns (bool)
{ {
return self.flags[value]; return self.flags[value];
@ -1161,7 +1167,7 @@ more advanced example to implement a set).
contract C { contract C {
Set.Data knownValues; Set.Data knownValues;
function register(uint value) { function register(uint value) public {
// The library functions can be called without a // The library functions can be called without a
// specific instance of the library, since the // specific instance of the library, since the
// "instance" will be the current contract. // "instance" will be the current contract.
@ -1190,19 +1196,19 @@ custom types without the overhead of external function calls:
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
library BigInt { library BigInt {
struct bigint { struct bigint {
uint[] limbs; uint[] limbs;
} }
function fromUint(uint x) internal returns (bigint r) { function fromUint(uint x) internal pure returns (bigint r) {
r.limbs = new uint[](1); r.limbs = new uint[](1);
r.limbs[0] = x; r.limbs[0] = x;
} }
function add(bigint _a, bigint _b) internal returns (bigint r) { function add(bigint _a, bigint _b) internal pure returns (bigint r) {
r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length)); r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length));
uint carry = 0; uint carry = 0;
for (uint i = 0; i < r.limbs.length; ++i) { for (uint i = 0; i < r.limbs.length; ++i) {
@ -1224,11 +1230,11 @@ custom types without the overhead of external function calls:
} }
} }
function limb(bigint _a, uint _limb) internal returns (uint) { function limb(bigint _a, uint _limb) internal pure returns (uint) {
return _limb < _a.limbs.length ? _a.limbs[_limb] : 0; return _limb < _a.limbs.length ? _a.limbs[_limb] : 0;
} }
function max(uint a, uint b) private returns (uint) { function max(uint a, uint b) private pure returns (uint) {
return a > b ? a : b; return a > b ? a : b;
} }
} }
@ -1236,7 +1242,7 @@ custom types without the overhead of external function calls:
contract C { contract C {
using BigInt for BigInt.bigint; using BigInt for BigInt.bigint;
function f() { function f() public pure {
var x = BigInt.fromUint(7); var x = BigInt.fromUint(7);
var y = BigInt.fromUint(uint(-1)); var y = BigInt.fromUint(uint(-1));
var z = x.add(y); var z = x.add(y);
@ -1294,13 +1300,14 @@ available without having to add further code.
Let us rewrite the set example from the Let us rewrite the set example from the
:ref:`libraries` in this way:: :ref:`libraries` in this way::
pragma solidity ^0.4.11; pragma solidity ^0.4.16;
// This is the same code as before, just without comments // This is the same code as before, just without comments
library Set { library Set {
struct Data { mapping(uint => bool) flags; } struct Data { mapping(uint => bool) flags; }
function insert(Data storage self, uint value) function insert(Data storage self, uint value)
public
returns (bool) returns (bool)
{ {
if (self.flags[value]) if (self.flags[value])
@ -1310,6 +1317,7 @@ Let us rewrite the set example from the
} }
function remove(Data storage self, uint value) function remove(Data storage self, uint value)
public
returns (bool) returns (bool)
{ {
if (!self.flags[value]) if (!self.flags[value])
@ -1319,6 +1327,8 @@ Let us rewrite the set example from the
} }
function contains(Data storage self, uint value) function contains(Data storage self, uint value)
public
view
returns (bool) returns (bool)
{ {
return self.flags[value]; return self.flags[value];
@ -1329,7 +1339,7 @@ Let us rewrite the set example from the
using Set for Set.Data; // this is the crucial change using Set for Set.Data; // this is the crucial change
Set.Data knownValues; Set.Data knownValues;
function register(uint value) { function register(uint value) public {
// Here, all variables of type Set.Data have // Here, all variables of type Set.Data have
// corresponding member functions. // corresponding member functions.
// The following function call is identical to // The following function call is identical to
@ -1340,10 +1350,14 @@ Let us rewrite the set example from the
It is also possible to extend elementary types in that way:: It is also possible to extend elementary types in that way::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
library Search { library Search {
function indexOf(uint[] storage self, uint value) returns (uint) { function indexOf(uint[] storage self, uint value)
public
view
returns (uint)
{
for (uint i = 0; i < self.length; i++) for (uint i = 0; i < self.length; i++)
if (self[i] == value) return i; if (self[i] == value) return i;
return uint(-1); return uint(-1);
@ -1354,11 +1368,11 @@ It is also possible to extend elementary types in that way::
using Search for uint[]; using Search for uint[];
uint[] data; uint[] data;
function append(uint value) { function append(uint value) public {
data.push(value); data.push(value);
} }
function replace(uint _old, uint _new) { function replace(uint _old, uint _new) public {
// This performs the library function call // This performs the library function call
uint index = data.indexOf(_old); uint index = data.indexOf(_old);
if (index == uint(-1)) if (index == uint(-1))

View File

@ -20,10 +20,10 @@ For example, suppose we want our contract to
accept one kind of external calls with two integers, we would write accept one kind of external calls with two integers, we would write
something like:: something like::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract Simple { contract Simple {
function taker(uint _a, uint _b) { function taker(uint _a, uint _b) public pure {
// do something with _a and _b. // do something with _a and _b.
} }
} }
@ -36,10 +36,14 @@ The output parameters can be declared with the same syntax after the
the sum and the product of the two given integers, then we would the sum and the product of the two given integers, then we would
write:: write::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract Simple { contract Simple {
function arithmetics(uint _a, uint _b) returns (uint o_sum, uint o_product) { function arithmetics(uint _a, uint _b)
public
pure
returns (uint o_sum, uint o_product)
{
o_sum = _a + _b; o_sum = _a + _b;
o_product = _a * _b; o_product = _a * _b;
} }
@ -95,11 +99,11 @@ Internal Function Calls
Functions of the current contract can be called directly ("internally"), also recursively, as seen in Functions of the current contract can be called directly ("internally"), also recursively, as seen in
this nonsensical example:: this nonsensical example::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract C { contract C {
function g(uint a) returns (uint ret) { return f(); } function g(uint a) public pure returns (uint ret) { return f(); }
function f() returns (uint ret) { return g(7) + f(); } function f() internal pure returns (uint ret) { return g(7) + f(); }
} }
These function calls are translated into simple jumps inside the EVM. This has These function calls are translated into simple jumps inside the EVM. This has
@ -125,13 +129,13 @@ the gas can be specified with special options ``.value()`` and ``.gas()``, respe
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract InfoFeed { contract InfoFeed {
function info() payable returns (uint ret) { return 42; } function info() public payable returns (uint ret) { return 42; }
} }
contract Consumer { contract Consumer {
InfoFeed feed; InfoFeed feed;
function setFeed(address addr) { feed = InfoFeed(addr); } function setFeed(address addr) public { feed = InfoFeed(addr); }
function callFeed() { feed.info.value(10).gas(800)(); } function public callFeed() { feed.info.value(10).gas(800)(); }
} }
The modifier ``payable`` has to be used for ``info``, because otherwise, the `.value()` The modifier ``payable`` has to be used for ``info``, because otherwise, the `.value()`
@ -180,11 +184,11 @@ parameters from the function declaration, but can be in arbitrary order.
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract C { contract C {
function f(uint key, uint value) { function f(uint key, uint value) public {
// ... // ...
} }
function g() { function g() public {
// named arguments // named arguments
f({value: 2, key: 3}); f({value: 2, key: 3});
} }
@ -198,11 +202,11 @@ Those parameters will still be present on the stack, but they are inaccessible.
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract C { contract C {
// omitted name for parameter // omitted name for parameter
function func(uint k, uint) returns(uint) { function func(uint k, uint) public pure returns(uint) {
return k; return k;
} }
} }
@ -225,7 +229,7 @@ creation-dependencies are not possible.
contract D { contract D {
uint x; uint x;
function D(uint a) payable { function D(uint a) public payable {
x = a; x = a;
} }
} }
@ -233,11 +237,11 @@ creation-dependencies are not possible.
contract C { contract C {
D d = new D(4); // will be executed as part of C's constructor D d = new D(4); // will be executed as part of C's constructor
function createD(uint arg) { function createD(uint arg) public {
D newD = new D(arg); D newD = new D(arg);
} }
function createAndEndowD(uint arg, uint amount) payable { function createAndEndowD(uint arg, uint amount) public payable {
// Send ether along with the creation // Send ether along with the creation
D newD = (new D).value(amount)(arg); D newD = (new D).value(amount)(arg);
} }
@ -270,16 +274,16 @@ Destructuring Assignments and Returning Multiple Values
Solidity internally allows tuple types, i.e. a list of objects of potentially different types whose size is a constant at compile-time. Those tuples can be used to return multiple values at the same time and also assign them to multiple variables (or LValues in general) at the same time:: Solidity internally allows tuple types, i.e. a list of objects of potentially different types whose size is a constant at compile-time. Those tuples can be used to return multiple values at the same time and also assign them to multiple variables (or LValues in general) at the same time::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract C { contract C {
uint[] data; uint[] data;
function f() returns (uint, bool, uint) { function f() public pure returns (uint, bool, uint) {
return (7, true, 2); return (7, true, 2);
} }
function g() { function g() public {
// Declares and assigns the variables. Specifying the type explicitly is not possible. // Declares and assigns the variables. Specifying the type explicitly is not possible.
var (x, b, y) = f(); var (x, b, y) = f();
// Assigns to a pre-existing variable. // Assigns to a pre-existing variable.
@ -326,10 +330,10 @@ As a result, the following code is illegal and cause the compiler to throw an er
// This will not compile // This will not compile
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract ScopingErrors { contract ScopingErrors {
function scoping() { function scoping() public {
uint i = 0; uint i = 0;
while (i++ < 1) { while (i++ < 1) {
@ -341,7 +345,7 @@ As a result, the following code is illegal and cause the compiler to throw an er
} }
} }
function minimalScoping() { function minimalScoping() public {
{ {
uint same2 = 0; uint same2 = 0;
} }
@ -351,7 +355,7 @@ As a result, the following code is illegal and cause the compiler to throw an er
} }
} }
function forLoopScoping() { function forLoopScoping() public {
for (uint same3 = 0; same3 < 1; same3++) { for (uint same3 = 0; same3 < 1; same3++) {
} }
@ -364,9 +368,9 @@ In addition to this, if a variable is declared, it will be initialized at the be
As a result, the following code is legal, despite being poorly written:: As a result, the following code is legal, despite being poorly written::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract C { contract C {
function foo() returns (uint) { function foo() public pure returns (uint) {
// baz is implicitly initialized as 0 // baz is implicitly initialized as 0
uint bar = 5; uint bar = 5;
if (true) { if (true) {
@ -412,7 +416,7 @@ and how ``assert`` can be used for internal error checking::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract Sharer { contract Sharer {
function sendHalf(address addr) payable returns (uint balance) { function sendHalf(address addr) public payable returns (uint balance) {
require(msg.value % 2 == 0); // Only allow even numbers require(msg.value % 2 == 0); // Only allow even numbers
uint balanceBeforeTransfer = this.balance; uint balanceBeforeTransfer = this.balance;
addr.transfer(msg.value / 2); addr.transfer(msg.value / 2);

View File

@ -111,10 +111,10 @@ array in the return statement. Pretty cool, huh?
Example:: Example::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract C { contract C {
function f() returns (uint8[5]) { function f() public pure returns (uint8[5]) {
string[4] memory adaArr = ["This", "is", "an", "array"]; string[4] memory adaArr = ["This", "is", "an", "array"];
return ([1, 2, 3, 4, 5]); return ([1, 2, 3, 4, 5]);
} }
@ -190,11 +190,11 @@ you should always convert it to a ``bytes`` first::
contract C { contract C {
string s; string s;
function append(byte c) { function append(byte c) public {
bytes(s).push(c); bytes(s).push(c);
} }
function set(uint i, byte c) { function set(uint i, byte c) public {
bytes(s)[i] = c; bytes(s)[i] = c;
} }
} }
@ -232,12 +232,14 @@ situation.
If you do not want to throw, you can return a pair:: If you do not want to throw, you can return a pair::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract C { contract C {
uint[] counters; uint[] counters;
function getCounter(uint index) function getCounter(uint index)
public
view
returns (uint counter, bool error) { returns (uint counter, bool error) {
if (index >= counters.length) if (index >= counters.length)
return (0, true); return (0, true);
@ -245,7 +247,7 @@ If you do not want to throw, you can return a pair::
return (counters[index], false); return (counters[index], false);
} }
function checkCounter(uint index) { function checkCounter(uint index) public view {
var (counter, error) = getCounter(index); var (counter, error) = getCounter(index);
if (error) { if (error) {
// ... // ...
@ -316,11 +318,11 @@ Example::
uint[] data1; uint[] data1;
uint[] data2; uint[] data2;
function appendOne() { function appendOne() public {
append(data1); append(data1);
} }
function appendTwo() { function appendTwo() public {
append(data2); append(data2);
} }
@ -349,7 +351,7 @@ be created in memory, although it will be created in storage::
uint someVariable; uint someVariable;
uint[] data; uint[] data;
function f() { function f() public {
uint[] x; uint[] x;
x.push(2); x.push(2);
data = x; data = x;
@ -375,7 +377,7 @@ The correct way to do this is the following::
uint someVariable; uint someVariable;
uint[] data; uint[] data;
function f() { function f() public {
uint[] x = data; uint[] x = data;
x.push(2); x.push(2);
} }
@ -435,7 +437,7 @@ This is a very interesting question. Suppose that we have a contract field set u
mapping(string => string) comments; mapping(string => string) comments;
} }
function somefunction { function somefunction public {
user user1; user user1;
user1.comments["Hello"] = "World"; user1.comments["Hello"] = "World";
user user2 = user1; user user2 = user1;
@ -456,13 +458,13 @@ In this example::
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract B { contract B {
function B() payable {} function B() public payable {}
} }
contract A { contract A {
address child; address child;
function test() { function test() public {
child = (new B).value(10)(); //construct a new B with 10 wei child = (new B).value(10)(); //construct a new B with 10 wei
} }
} }
@ -501,17 +503,17 @@ Can a contract pass an array (static size) or string or ``bytes`` (dynamic size)
Sure. Take care that if you cross the memory / storage boundary, Sure. Take care that if you cross the memory / storage boundary,
independent copies will be created:: independent copies will be created::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract C { contract C {
uint[20] x; uint[20] x;
function f() { function f() public {
g(x); g(x);
h(x); h(x);
} }
function g(uint[20] y) internal { function g(uint[20] y) internal pure {
y[2] = 3; y[2] = 3;
} }

View File

@ -21,11 +21,11 @@ Storage
contract SimpleStorage { contract SimpleStorage {
uint storedData; uint storedData;
function set(uint x) { function set(uint x) public {
storedData = x; storedData = x;
} }
function get() constant returns (uint) { function get() public constant returns (uint) {
return storedData; return storedData;
} }
} }
@ -94,16 +94,16 @@ registering with username and password - all you need is an Ethereum keypair.
// This is the constructor whose code is // This is the constructor whose code is
// run only when the contract is created. // run only when the contract is created.
function Coin() { function Coin() public {
minter = msg.sender; minter = msg.sender;
} }
function mint(address receiver, uint amount) { function mint(address receiver, uint amount) public {
if (msg.sender != minter) return; if (msg.sender != minter) return;
balances[receiver] += amount; balances[receiver] += amount;
} }
function send(address receiver, uint amount) { function send(address receiver, uint amount) public {
if (balances[msg.sender] < amount) return; if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount; balances[msg.sender] -= amount;
balances[receiver] += amount; balances[receiver] += amount;
@ -145,7 +145,7 @@ like this one. The :ref:`getter function<getter-functions>` created by the ``pub
is a bit more complex in this case. It roughly looks like the is a bit more complex in this case. It roughly looks like the
following:: following::
function balances(address _account) returns (uint) { function balances(address _account) public view returns (uint) {
return balances[_account]; return balances[_account];
} }

View File

@ -62,7 +62,7 @@ complete contract):
/// Mapping of ether shares of the contract. /// Mapping of ether shares of the contract.
mapping(address => uint) shares; mapping(address => uint) shares;
/// Withdraw your share. /// Withdraw your share.
function withdraw() { function withdraw() public {
if (msg.sender.send(shares[msg.sender])) if (msg.sender.send(shares[msg.sender]))
shares[msg.sender] = 0; shares[msg.sender] = 0;
} }
@ -85,7 +85,7 @@ as it uses ``call`` which forwards all remaining gas by default:
/// Mapping of ether shares of the contract. /// Mapping of ether shares of the contract.
mapping(address => uint) shares; mapping(address => uint) shares;
/// Withdraw your share. /// Withdraw your share.
function withdraw() { function withdraw() public {
if (msg.sender.call.value(shares[msg.sender])()) if (msg.sender.call.value(shares[msg.sender])())
shares[msg.sender] = 0; shares[msg.sender] = 0;
} }
@ -102,7 +102,7 @@ outlined further below:
/// Mapping of ether shares of the contract. /// Mapping of ether shares of the contract.
mapping(address => uint) shares; mapping(address => uint) shares;
/// Withdraw your share. /// Withdraw your share.
function withdraw() { function withdraw() public {
var share = shares[msg.sender]; var share = shares[msg.sender];
shares[msg.sender] = 0; shares[msg.sender] = 0;
msg.sender.transfer(share); msg.sender.transfer(share);
@ -130,7 +130,7 @@ Sending and Receiving Ether
- Neither contracts nor "external accounts" are currently able to prevent that someone sends them 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 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" 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)``. 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 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). If it does not have a fallback function, the Ether will be rejected (by throwing an exception).
@ -186,11 +186,11 @@ Never use tx.origin for authorization. Let's say you have a wallet contract like
contract TxUserWallet { contract TxUserWallet {
address owner; address owner;
function TxUserWallet() { function TxUserWallet() public {
owner = msg.sender; owner = msg.sender;
} }
function transferTo(address dest, uint amount) { function transferTo(address dest, uint amount) public {
require(tx.origin == owner); require(tx.origin == owner);
dest.transfer(amount); dest.transfer(amount);
} }
@ -203,17 +203,17 @@ Now someone tricks you into sending ether to the address of this attack wallet:
pragma solidity ^0.4.11; pragma solidity ^0.4.11;
interface TxUserWallet { interface TxUserWallet {
function transferTo(address dest, uint amount); function transferTo(address dest, uint amount) public;
} }
contract TxAttackWallet { contract TxAttackWallet {
address owner; address owner;
function TxAttackWallet() { function TxAttackWallet() public {
owner = msg.sender; owner = msg.sender;
} }
function() { function() public {
TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance); TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);
} }
} }

View File

@ -36,7 +36,7 @@ of votes.
:: ::
pragma solidity ^0.4.11; pragma solidity ^0.4.16;
/// @title Voting with delegation. /// @title Voting with delegation.
contract Ballot { contract Ballot {
@ -66,7 +66,7 @@ of votes.
Proposal[] public proposals; Proposal[] public proposals;
/// Create a new ballot to choose one of `proposalNames`. /// Create a new ballot to choose one of `proposalNames`.
function Ballot(bytes32[] proposalNames) { function Ballot(bytes32[] proposalNames) public {
chairperson = msg.sender; chairperson = msg.sender;
voters[chairperson].weight = 1; voters[chairperson].weight = 1;
@ -86,7 +86,7 @@ of votes.
// Give `voter` the right to vote on this ballot. // Give `voter` the right to vote on this ballot.
// May only be called by `chairperson`. // May only be called by `chairperson`.
function giveRightToVote(address voter) { function giveRightToVote(address voter) public {
// If the argument of `require` evaluates to `false`, // If the argument of `require` evaluates to `false`,
// it terminates and reverts all changes to // it terminates and reverts all changes to
// the state and to Ether balances. It is often // the state and to Ether balances. It is often
@ -99,7 +99,7 @@ of votes.
} }
/// Delegate your vote to the voter `to`. /// Delegate your vote to the voter `to`.
function delegate(address to) { function delegate(address to) public {
// assigns reference // assigns reference
Voter storage sender = voters[msg.sender]; Voter storage sender = voters[msg.sender];
require(!sender.voted); require(!sender.voted);
@ -140,7 +140,7 @@ of votes.
/// Give your vote (including votes delegated to you) /// Give your vote (including votes delegated to you)
/// to proposal `proposals[proposal].name`. /// to proposal `proposals[proposal].name`.
function vote(uint proposal) { function vote(uint proposal) public {
Voter storage sender = voters[msg.sender]; Voter storage sender = voters[msg.sender];
require(!sender.voted); require(!sender.voted);
sender.voted = true; sender.voted = true;
@ -154,13 +154,13 @@ of votes.
/// @dev Computes the winning proposal taking all /// @dev Computes the winning proposal taking all
/// previous votes into account. /// previous votes into account.
function winningProposal() constant function winningProposal() public view
returns (uint winningProposal) returns (uint winningProposal)
{ {
uint winningVoteCount = 0; uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) { for (uint p = 0; p < winningProposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) { if (winningProposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount; winningVoteCount = winningProposals[p].voteCount;
winningProposal = p; winningProposal = p;
} }
} }
@ -169,10 +169,10 @@ of votes.
// Calls winningProposal() function to get the index // Calls winningProposal() function to get the index
// of the winner contained in the proposals array and then // of the winner contained in the proposals array and then
// returns the name of the winner // returns the name of the winner
function winnerName() constant function winnerName() public view
returns (bytes32 winnerName) returns (bytes32 winnerName)
{ {
winnerName = proposals[winningProposal()].name; name = proposals[winningProposal()].name;
} }
} }
@ -248,7 +248,7 @@ activate themselves.
function SimpleAuction( function SimpleAuction(
uint _biddingTime, uint _biddingTime,
address _beneficiary address _beneficiary
) { ) public {
beneficiary = _beneficiary; beneficiary = _beneficiary;
auctionEnd = now + _biddingTime; auctionEnd = now + _biddingTime;
} }
@ -257,7 +257,7 @@ activate themselves.
/// together with this transaction. /// together with this transaction.
/// The value will only be refunded if the /// The value will only be refunded if the
/// auction is not won. /// auction is not won.
function bid() payable { function bid() public payable {
// No arguments are necessary, all // No arguments are necessary, all
// information is already part of // information is already part of
// the transaction. The keyword payable // the transaction. The keyword payable
@ -286,7 +286,7 @@ activate themselves.
} }
/// Withdraw a bid that was overbid. /// Withdraw a bid that was overbid.
function withdraw() returns (bool) { function withdraw() public returns (bool) {
uint amount = pendingReturns[msg.sender]; uint amount = pendingReturns[msg.sender];
if (amount > 0) { if (amount > 0) {
// It is important to set this to zero because the recipient // It is important to set this to zero because the recipient
@ -305,7 +305,7 @@ activate themselves.
/// End the auction and send the highest bid /// End the auction and send the highest bid
/// to the beneficiary. /// to the beneficiary.
function auctionEnd() { function auctionEnd() public {
// It is a good guideline to structure functions that interact // It is a good guideline to structure functions that interact
// with other contracts (i.e. they call functions or send Ether) // with other contracts (i.e. they call functions or send Ether)
// into three phases: // into three phases:
@ -405,7 +405,7 @@ high or low invalid bids.
uint _biddingTime, uint _biddingTime,
uint _revealTime, uint _revealTime,
address _beneficiary address _beneficiary
) { ) public {
beneficiary = _beneficiary; beneficiary = _beneficiary;
biddingEnd = now + _biddingTime; biddingEnd = now + _biddingTime;
revealEnd = biddingEnd + _revealTime; revealEnd = biddingEnd + _revealTime;
@ -421,6 +421,7 @@ high or low invalid bids.
/// still make the required deposit. The same address can /// still make the required deposit. The same address can
/// place multiple bids. /// place multiple bids.
function bid(bytes32 _blindedBid) function bid(bytes32 _blindedBid)
public
payable payable
onlyBefore(biddingEnd) onlyBefore(biddingEnd)
{ {
@ -438,6 +439,7 @@ high or low invalid bids.
bool[] _fake, bool[] _fake,
bytes32[] _secret bytes32[] _secret
) )
public
onlyAfter(biddingEnd) onlyAfter(biddingEnd)
onlyBefore(revealEnd) onlyBefore(revealEnd)
{ {
@ -487,7 +489,7 @@ high or low invalid bids.
} }
/// Withdraw a bid that was overbid. /// Withdraw a bid that was overbid.
function withdraw() { function withdraw() public {
uint amount = pendingReturns[msg.sender]; uint amount = pendingReturns[msg.sender];
if (amount > 0) { if (amount > 0) {
// It is important to set this to zero because the recipient // It is important to set this to zero because the recipient
@ -503,6 +505,7 @@ high or low invalid bids.
/// End the auction and send the highest bid /// End the auction and send the highest bid
/// to the beneficiary. /// to the beneficiary.
function auctionEnd() function auctionEnd()
public
onlyAfter(revealEnd) onlyAfter(revealEnd)
{ {
require(!ended); require(!ended);
@ -533,7 +536,7 @@ Safe Remote Purchase
// Ensure that `msg.value` is an even number. // Ensure that `msg.value` is an even number.
// Division will truncate if it is an odd number. // Division will truncate if it is an odd number.
// Check via multiplication that it wasn't an odd number. // Check via multiplication that it wasn't an odd number.
function Purchase() payable { function Purchase() public payable {
seller = msg.sender; seller = msg.sender;
value = msg.value / 2; value = msg.value / 2;
require((2 * value) == msg.value); require((2 * value) == msg.value);
@ -567,6 +570,7 @@ Safe Remote Purchase
/// Can only be called by the seller before /// Can only be called by the seller before
/// the contract is locked. /// the contract is locked.
function abort() function abort()
public
onlySeller onlySeller
inState(State.Created) inState(State.Created)
{ {
@ -580,6 +584,7 @@ Safe Remote Purchase
/// The ether will be locked until confirmReceived /// The ether will be locked until confirmReceived
/// is called. /// is called.
function confirmPurchase() function confirmPurchase()
public
inState(State.Created) inState(State.Created)
condition(msg.value == (2 * value)) condition(msg.value == (2 * value))
payable payable
@ -592,6 +597,7 @@ Safe Remote Purchase
/// Confirm that you (the buyer) received the item. /// Confirm that you (the buyer) received the item.
/// This will release the locked ether. /// This will release the locked ether.
function confirmReceived() function confirmReceived()
public
onlyBuyer onlyBuyer
inState(State.Locked) inState(State.Locked)
{ {

View File

@ -43,7 +43,7 @@ Functions are the executable units of code within a contract.
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract SimpleAuction { contract SimpleAuction {
function bid() payable { // Function function bid() public payable { // Function
// ... // ...
} }
} }
@ -72,7 +72,7 @@ Function modifiers can be used to amend the semantics of functions in a declarat
_; _;
} }
function abort() onlySeller { // Modifier usage function abort() public onlySeller { // Modifier usage
// ... // ...
} }
} }
@ -91,7 +91,7 @@ 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() payable { function bid() public payable {
// ... // ...
HighestBidIncreased(msg.sender, msg.value); // Triggering event HighestBidIncreased(msg.sender, msg.value); // Triggering event
} }

View File

@ -86,17 +86,17 @@ Blank lines may be omitted between groups of related one-liners (such as stub fu
Yes:: Yes::
contract A { contract A {
function spam(); function spam() public;
function ham(); function ham() public;
} }
contract B is A { contract B is A {
function spam() { function spam() public {
... ...
} }
function ham() { function ham() public {
... ...
} }
} }
@ -104,10 +104,10 @@ Yes::
No:: No::
contract A { contract A {
function spam() { function spam() public {
... ...
} }
function ham() { function ham() public {
... ...
} }
} }
@ -169,26 +169,26 @@ Within a grouping, place the ``constant`` functions last.
Yes:: Yes::
contract A { contract A {
function A() { function A() public {
... ...
} }
function() { function() public {
... ...
} }
// External functions // External functions
// ... // ...
// External functions that are constant // External functions that are constant
// ... // ...
// Public functions // Public functions
// ... // ...
// Internal functions // Internal functions
// ... // ...
// Private functions // Private functions
// ... // ...
} }
@ -196,7 +196,7 @@ Yes::
No:: No::
contract A { contract A {
// External functions // External functions
// ... // ...
@ -206,16 +206,16 @@ No::
// Public functions // Public functions
// ... // ...
function A() { function A() public {
... ...
} }
function() { function() public {
... ...
} }
// Internal functions // Internal functions
// ... // ...
} }
Whitespace in Expressions Whitespace in Expressions
@ -235,17 +235,17 @@ No::
Exception:: Exception::
function singleLine() { spam(); } function singleLine() public { spam(); }
Immediately before a comma, semicolon: Immediately before a comma, semicolon:
Yes:: Yes::
function spam(uint i, Coin coin); function spam(uint i, Coin coin) public;
No:: No::
function spam(uint i , Coin coin) ; function spam(uint i , Coin coin) public ;
More than one space around an assignment or other operator to align with More than one space around an assignment or other operator to align with
another: another:
@ -266,13 +266,13 @@ Don't include a whitespace in the fallback function:
Yes:: Yes::
function() { function() public {
... ...
} }
No:: No::
function () { function () public {
... ...
} }
@ -395,30 +395,30 @@ The opening brace should be preceeded by a single space.
Yes:: Yes::
function increment(uint x) returns (uint) { function increment(uint x) public pure returns (uint) {
return x + 1; return x + 1;
} }
function increment(uint x) public onlyowner returns (uint) { function increment(uint x) public pure onlyowner returns (uint) {
return x + 1; return x + 1;
} }
No:: No::
function increment(uint x) returns (uint) function increment(uint x) public pure returns (uint)
{ {
return x + 1; return x + 1;
} }
function increment(uint x) returns (uint){ function increment(uint x) public pure returns (uint){
return x + 1; return x + 1;
} }
function increment(uint x) returns (uint) { function increment(uint x) public pure returns (uint) {
return x + 1; return x + 1;
} }
function increment(uint x) returns (uint) { function increment(uint x) public pure returns (uint) {
return x + 1;} return x + 1;}
The visibility modifiers for a function should come before any custom The visibility modifiers for a function should come before any custom
@ -450,14 +450,16 @@ Yes::
address d, address d,
address e, address e,
address f address f
) { )
public
{
doSomething(); doSomething();
} }
No:: No::
function thisFunctionHasLotsOfArguments(address a, address b, address c, function thisFunctionHasLotsOfArguments(address a, address b, address c,
address d, address e, address f) { address d, address e, address f) public {
doSomething(); doSomething();
} }
@ -466,7 +468,7 @@ No::
address c, address c,
address d, address d,
address e, address e,
address f) { address f) public {
doSomething(); doSomething();
} }
@ -476,12 +478,12 @@ No::
address c, address c,
address d, address d,
address e, address e,
address f) { address f) public {
doSomething(); doSomething();
} }
If a long function declaration has modifiers, then each modifier should be If a long function declaration has modifiers, then each modifier should be
dropped to it's own line. dropped to its own line.
Yes:: Yes::
@ -542,6 +544,7 @@ Yes::
B(param1) B(param1)
C(param2, param3) C(param2, param3)
D(param4) D(param4)
public
{ {
// do something with param5 // do something with param5
} }
@ -554,6 +557,7 @@ No::
B(param1) B(param1)
C(param2, param3) C(param2, param3)
D(param4) D(param4)
public
{ {
// do something with param5 // do something with param5
} }
@ -563,7 +567,8 @@ No::
function A(uint param1, uint param2, uint param3, uint param4, uint param5) function A(uint param1, uint param2, uint param3, uint param4, uint param5)
B(param1) B(param1)
C(param2, param3) C(param2, param3)
D(param4) { D(param4)
public {
// do something with param5 // do something with param5
} }
} }
@ -572,7 +577,7 @@ When declaring short functions with a single statement, it is permissible to do
Permissible:: Permissible::
function shortFunction() { doSomething(); } function shortFunction() public { doSomething(); }
These guidelines for function declarations are intended to improve readability. These guidelines for function declarations are intended to improve readability.
Authors should use their best judgement as this guide does not try to cover all Authors should use their best judgement as this guide does not try to cover all

View File

@ -79,8 +79,8 @@ Fixed Point Numbers
Fixed point numbers are not fully supported by Solidity yet. They can be declared, but Fixed point numbers are not fully supported by Solidity yet. They can be declared, but
cannot be assigned to or from. cannot be assigned to or from.
``fixed`` / ``ufixed``: Signed and unsigned fixed point number of various sizes. Keywords ``ufixedMxN`` and ``fixedMxN``, where ``M`` represent the number of bits taken by ``fixed`` / ``ufixed``: Signed and unsigned fixed point number of various sizes. Keywords ``ufixedMxN`` and ``fixedMxN``, where ``M`` represents the number of bits taken by
the type and ``N`` represent how many decimal points are available. ``M`` must be divisible by 8 and goes from 8 to 256 bits. ``N`` must be between 0 and 80, inclusive. the type and ``N`` represents how many decimal points are available. ``M`` must be divisible by 8 and goes from 8 to 256 bits. ``N`` must be between 0 and 80, inclusive.
``ufixed`` and ``fixed`` are aliases for ``ufixed128x19`` and ``fixed128x19``, respectively. ``ufixed`` and ``fixed`` are aliases for ``ufixed128x19`` and ``fixed128x19``, respectively.
Operators: Operators:
@ -331,14 +331,14 @@ check the value ranges at runtime and a failure causes an exception. Enums need
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract test { contract test {
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() public {
choice = ActionChoices.GoStraight; choice = ActionChoices.GoStraight;
} }
@ -347,11 +347,11 @@ check the value ranges at runtime and a failure causes an exception. Enums need
// 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() public view returns (ActionChoices) {
return choice; return choice;
} }
function getDefaultChoice() returns (uint) { function getDefaultChoice() public pure returns (uint) {
return uint(defaultChoice); return uint(defaultChoice);
} }
} }
@ -409,23 +409,24 @@ just use ``f``, if you want to use its external form, use ``this.f``.
Additionally, public (or external) functions also have a special member called ``selector``, Additionally, public (or external) functions also have a special member called ``selector``,
which returns the :ref:`ABI function selector <abi_function_selector>`:: which returns the :ref:`ABI function selector <abi_function_selector>`::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract Selector { contract Selector {
function f() returns (bytes4) { function f() public view returns (bytes4) {
return this.f.selector; return this.f.selector;
} }
} }
Example that shows how to use internal function types:: Example that shows how to use internal function types::
pragma solidity ^0.4.5; pragma solidity ^0.4.16;
library ArrayUtils { library ArrayUtils {
// internal functions can be used in internal library functions because // internal functions can be used in internal library functions because
// they will be part of the same code context // they will be part of the same code context
function map(uint[] memory self, function (uint) returns (uint) f) function map(uint[] memory self, function (uint) pure returns (uint) f)
internal internal
pure
returns (uint[] memory r) returns (uint[] memory r)
{ {
r = new uint[](self.length); r = new uint[](self.length);
@ -435,9 +436,10 @@ Example that shows how to use internal function types::
} }
function reduce( function reduce(
uint[] memory self, uint[] memory self,
function (uint, uint) returns (uint) f function (uint, uint) pure returns (uint) f
) )
internal internal
pure
returns (uint r) returns (uint r)
{ {
r = self[0]; r = self[0];
@ -445,23 +447,23 @@ Example that shows how to use internal function types::
r = f(r, self[i]); r = f(r, self[i]);
} }
} }
function range(uint length) internal returns (uint[] memory r) { function range(uint length) internal pure returns (uint[] memory r) {
r = new uint[](length); r = new uint[](length);
for (uint i = 0; i < r.length; i++) { for (uint i = 0; i < r.length; i++) {
r[i] = i; r[i] = i;
} }
} }
} }
contract Pyramid { contract Pyramid {
using ArrayUtils for *; using ArrayUtils for *;
function pyramid(uint l) returns (uint) { function pyramid(uint l) public pure returns (uint) {
return ArrayUtils.range(l).map(square).reduce(sum); return ArrayUtils.range(l).map(square).reduce(sum);
} }
function square(uint x) internal returns (uint) { function square(uint x) internal pure returns (uint) {
return x * x; return x * x;
} }
function sum(uint x, uint y) internal returns (uint) { function sum(uint x, uint y) internal pure returns (uint) {
return x + y; return x + y;
} }
} }
@ -477,11 +479,11 @@ Another example that uses external function types::
} }
Request[] requests; Request[] requests;
event NewRequest(uint); event NewRequest(uint);
function query(bytes data, function(bytes memory) external callback) { function query(bytes data, function(bytes memory) external callback) public {
requests.push(Request(data, callback)); requests.push(Request(data, callback));
NewRequest(requests.length - 1); NewRequest(requests.length - 1);
} }
function reply(uint requestID, bytes response) { function reply(uint requestID, bytes response) public {
// Here goes the check that the reply comes from a trusted source // Here goes the check that the reply comes from a trusted source
requests[requestID].callback(response); requests[requestID].callback(response);
} }
@ -492,7 +494,7 @@ Another example that uses external function types::
function buySomething() { function buySomething() {
oracle.query("USD", this.oracleResponse); oracle.query("USD", this.oracleResponse);
} }
function oracleResponse(bytes response) { function oracleResponse(bytes response) public {
require(msg.sender == address(oracle)); require(msg.sender == address(oracle));
// Use the data // Use the data
} }
@ -543,7 +545,7 @@ memory-stored reference type do not create a copy.
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 // the data location of memoryArray is memory
function f(uint[] memoryArray) { function f(uint[] memoryArray) public {
x = memoryArray; // works, copies the whole array to storage x = memoryArray; // works, copies the whole array to storage
var y = x; // works, assigns a pointer, data location of y is storage var y = x; // works, assigns a pointer, data location of y is storage
y[7]; // fine, returns the 8th element y[7]; // fine, returns the 8th element
@ -560,7 +562,7 @@ memory-stored reference type do not create a copy.
} }
function g(uint[] storage storageArray) internal {} function g(uint[] storage storageArray) internal {}
function h(uint[] memoryArray) {} function h(uint[] memoryArray) public {}
} }
Summary Summary
@ -620,10 +622,10 @@ the ``.length`` member.
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract C { contract C {
function f(uint len) { function f(uint len) public pure {
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
@ -641,13 +643,13 @@ assigned to a variable right away.
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract C { contract C {
function f() { function f() public pure {
g([uint(1), 2, 3]); g([uint(1), 2, 3]);
} }
function g(uint[3] _data) { function g(uint[3] _data) public {
// ... // ...
} }
} }
@ -667,7 +669,7 @@ possible:
pragma solidity ^0.4.0; pragma solidity ^0.4.0;
contract C { contract C {
function f() { function f() public {
// The next line creates a type error because uint[3] memory // The next line creates a type error because uint[3] memory
// cannot be converted to uint[] memory. // cannot be converted to uint[] memory.
uint[] x = [uint(1), 3, 4]; uint[] x = [uint(1), 3, 4];
@ -703,7 +705,7 @@ Members
:: ::
pragma solidity ^0.4.0; pragma solidity ^0.4.16;
contract ArrayContract { contract ArrayContract {
uint[2**20] m_aLotOfIntegers; uint[2**20] m_aLotOfIntegers;
@ -712,23 +714,23 @@ Members
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) { function setAllFlagPairs(bool[2][] newPairs) public {
// assignment to a storage array replaces the complete array // assignment to a storage array replaces the complete array
m_pairsOfFlags = newPairs; m_pairsOfFlags = newPairs;
} }
function setFlagPair(uint index, bool flagA, bool flagB) { function setFlagPair(uint index, bool flagA, bool flagB) public {
// access to a non-existing index will throw an exception // access to a non-existing index will throw an exception
m_pairsOfFlags[index][0] = flagA; m_pairsOfFlags[index][0] = flagA;
m_pairsOfFlags[index][1] = flagB; m_pairsOfFlags[index][1] = flagB;
} }
function changeFlagArraySize(uint newSize) { function changeFlagArraySize(uint newSize) public {
// if the new size is smaller, removed array elements will be cleared // if the new size is smaller, removed array elements will be cleared
m_pairsOfFlags.length = newSize; m_pairsOfFlags.length = newSize;
} }
function clear() { function clear() public {
// these clear the arrays completely // these clear the arrays completely
delete m_pairsOfFlags; delete m_pairsOfFlags;
delete m_aLotOfIntegers; delete m_aLotOfIntegers;
@ -738,20 +740,20 @@ Members
bytes m_byteData; bytes m_byteData;
function byteArrays(bytes data) { function byteArrays(bytes data) public {
// byte arrays ("bytes") are different as they are stored without padding, // byte arrays ("bytes") are different as they are stored without padding,
// but can be treated identical to "uint8[]" // but can be treated identical to "uint8[]"
m_byteData = data; m_byteData = data;
m_byteData.length += 7; m_byteData.length += 7;
m_byteData[3] = 8; m_byteData[3] = byte(8);
delete m_byteData[2]; delete m_byteData[2];
} }
function addFlag(bool[2] flag) returns (uint) { function addFlag(bool[2] flag) public returns (uint) {
return m_pairsOfFlags.push(flag); return m_pairsOfFlags.push(flag);
} }
function createMemoryArray(uint size) returns (bytes) { function createMemoryArray(uint size) public pure returns (bytes) {
// Dynamic memory arrays are created using `new`: // Dynamic memory arrays are created using `new`:
uint[2][] memory arrayOfPairs = new uint[2][](size); uint[2][] memory arrayOfPairs = new uint[2][](size);
// Create a dynamic byte array: // Create a dynamic byte array:
@ -795,13 +797,13 @@ shown in the following example:
uint numCampaigns; uint numCampaigns;
mapping (uint => Campaign) campaigns; mapping (uint => Campaign) campaigns;
function newCampaign(address beneficiary, uint goal) returns (uint campaignID) { function newCampaign(address beneficiary, uint goal) public returns (uint campaignID) {
campaignID = numCampaigns++; // campaignID is return variable campaignID = numCampaigns++; // campaignID is return variable
// Creates new struct and saves in storage. We leave out the mapping type. // Creates new struct and saves in storage. We leave out the mapping type.
campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0); campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0);
} }
function contribute(uint campaignID) payable { function contribute(uint campaignID) public payable {
Campaign storage c = campaigns[campaignID]; Campaign storage 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.
@ -810,7 +812,7 @@ shown in the following example:
c.amount += msg.value; c.amount += msg.value;
} }
function checkGoalReached(uint campaignID) returns (bool reached) { function checkGoalReached(uint campaignID) public returns (bool reached) {
Campaign storage c = campaigns[campaignID]; Campaign storage c = campaigns[campaignID];
if (c.amount < c.fundingGoal) if (c.amount < c.fundingGoal)
return false; return false;
@ -872,13 +874,13 @@ for each ``_KeyType``, recursively.
contract MappingExample { contract MappingExample {
mapping(address => uint) public balances; mapping(address => uint) public balances;
function update(uint newBalance) { function update(uint newBalance) public {
balances[msg.sender] = newBalance; balances[msg.sender] = newBalance;
} }
} }
contract MappingUser { contract MappingUser {
function f() returns (uint) { function f() public returns (uint) {
MappingExample m = new MappingExample(); MappingExample m = new MappingExample();
m.update(100); m.update(100);
return m.balances(this); return m.balances(this);
@ -916,11 +918,11 @@ It is important to note that ``delete a`` really behaves like an assignment to `
uint data; uint data;
uint[] dataArray; uint[] dataArray;
function f() { function f() public {
uint x = data; uint x = data;
delete x; // sets x to 0, does not affect 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 delete data; // sets data to 0, does not affect x which still holds a copy
uint[] y = dataArray; uint[] storage y = dataArray;
delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also 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 // 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 // On the other hand: "delete y" is not valid, as assignments to local variables

View File

@ -34,7 +34,7 @@ library has to be updated by an external oracle.
These suffixes cannot be applied to variables. If you want to 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) public {
if (now >= start + daysAfter * 1 days) { if (now >= start + daysAfter * 1 days) {
// ... // ...
} }