Update documentation.

This commit is contained in:
chriseth 2018-01-03 15:30:01 +01:00
parent aa715f8759
commit 344a388d44
8 changed files with 92 additions and 35 deletions

View File

@ -147,7 +147,10 @@ restrictions highly readable.
// a certain address.
modifier onlyBy(address _account)
{
require(msg.sender == _account);
require(
msg.sender == _account,
"Sender not authorized."
);
// Do not forget the "_;"! It will
// be replaced by the actual function
// body when the modifier is used.
@ -164,7 +167,10 @@ restrictions highly readable.
}
modifier onlyAfter(uint _time) {
require(now >= _time);
require(
now >= _time,
"Function called too early."
);
_;
}
@ -186,7 +192,10 @@ restrictions highly readable.
// This was dangerous before Solidity version 0.4.0,
// where it was possible to skip the part after `_;`.
modifier costs(uint _amount) {
require(msg.value >= _amount);
require(
msg.value >= _amount,
"Not enough Ether provided."
);
_;
if (msg.value > _amount)
msg.sender.send(msg.value - _amount);
@ -290,7 +299,10 @@ function finishes.
uint public creationTime = now;
modifier atStage(Stages _stage) {
require(stage == _stage);
require(
stage == _stage,
"Function cannot be called at this time."
);
_;
}

View File

@ -315,7 +315,10 @@ inheritable properties of contracts and may be overridden by derived contracts.
// function is executed and otherwise, an exception is
// thrown.
modifier onlyOwner {
require(msg.sender == owner);
require(
msg.sender == owner,
"Only owner can call this function."
);
_;
}
}
@ -360,7 +363,10 @@ inheritable properties of contracts and may be overridden by derived contracts.
contract Mutex {
bool locked;
modifier noReentrancy() {
require(!locked);
require(
!locked,
"Reentrant call."
);
locked = true;
_;
locked = false;

View File

@ -472,13 +472,16 @@ of an exception instead of "bubbling up".
Catching exceptions is not yet possible.
In the following example, you can see how ``require`` can be used to easily check conditions on inputs
and how ``assert`` can be used for internal error checking::
and how ``assert`` can be used for internal error checking. Note that you can optionally provide
a message string for require, but not for assert.
::
pragma solidity ^0.4.0;
contract Sharer {
function sendHalf(address addr) public payable returns (uint balance) {
require(msg.value % 2 == 0); // Only allow even numbers
require(msg.value % 2 == 0, "Even value required.");
uint balanceBeforeTransfer = this.balance;
addr.transfer(msg.value / 2);
// Since transfer throws an exception on failure and
@ -517,7 +520,7 @@ did not occur. Because we want to retain the atomicity of transactions, the safe
(or at least call) without effect. Note that ``assert``-style exceptions consume all gas available to the call, while
``require``-style exceptions will not consume any gas starting from the Metropolis release.
The following example shows how an error string can be used together with revert:
The following example shows how an error string can be used together with revert and require:
::
@ -527,13 +530,18 @@ The following example shows how an error string can be used together with revert
function buy(uint amount) payable {
if (amount > msg.value / 2 ether)
revert("Not enough Ether provided.");
// Alternative way to do it:
require(
amount <= msg.value / 2 ether,
"Not enough Ether provided."
);
// Perform the purchase.
}
}
The provided string will be abi-encoded together with a uint value that will always be zero.
This means that if a string ``x`` is provided, ``(0, x)`` will be encoded as if a function with arguments
``(uint256, string)`` would be called. This zero is used as a version identifier. Future extensions
``(uint256, string)`` was called. This zero is used as a version identifier. Future extensions
of this feature might provide actual exception payload of dynamic type and this number could be used
to encode the type or also as a simple numeric error code. Until this is specified, a zero will
be used in all cases.

View File

@ -333,8 +333,9 @@ Global Variables
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error)
- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component)
- ``require(bool condition, string message)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component). Also provide error message.
- ``revert()``: abort execution and revert state changes
- ``revert(string)``: abort execution and revert state changes providing an explanatory string
- ``revert(string message)``: abort execution and revert state changes providing an explanatory string
- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks
- ``keccak256(...) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the :ref:`(tightly packed) arguments <abi_packed_mode>`
- ``sha3(...) returns (bytes32)``: an alias to ``keccak256``

View File

@ -87,17 +87,25 @@ of votes.
// Give `voter` the right to vote on this ballot.
// May only be called by `chairperson`.
function giveRightToVote(address voter) public {
// If the argument of `require` evaluates to `false`,
// it terminates and reverts all changes to
// the state and to Ether balances.
// This consumes all gas in old EVM versions, but not anymore.
// It is often a good idea to use this if functions are
// called incorrectly.
// If the first argument of `require` evaluates
// to `false`, execution terminates and all
// changes to the state and to Ether balances
// are reverted.
// This used to consume all gas in old EVM versions, but
// not anymore.
// It is often a good idea to use `require` to check if
// functions are called correctly.
// As a second argument, you can also provide an
// explanation about what went wrong.
require(
(msg.sender == chairperson) &&
!voters[voter].voted &&
(voters[voter].weight == 0)
msg.sender == chairperson,
"Only chairperson can give right to vote."
);
require(
!voters[voter].voted,
"The voter already voted."
);
require(voters[voter].weight == 0);
voters[voter].weight = 1;
}
@ -105,10 +113,9 @@ of votes.
function delegate(address to) public {
// assigns reference
Voter storage sender = voters[msg.sender];
require(!sender.voted);
require(!sender.voted, "You already voted.");
// Self-delegation is not allowed.
require(to != msg.sender);
require(to != msg.sender, "Self-delegation is disallowed.");
// Forward the delegation as long as
// `to` also delegated.
@ -122,7 +129,7 @@ of votes.
to = voters[to].delegate;
// We found a loop in the delegation, not allowed.
require(to != msg.sender);
require(to != msg.sender, "Found loop in delegation.");
}
// Since `sender` is a reference, this
@ -145,7 +152,7 @@ of votes.
/// to proposal `proposals[proposal].name`.
function vote(uint proposal) public {
Voter storage sender = voters[msg.sender];
require(!sender.voted);
require(!sender.voted, "Already voted.");
sender.voted = true;
sender.vote = proposal;
@ -270,11 +277,17 @@ activate themselves.
// Revert the call if the bidding
// period is over.
require(now <= auctionEnd);
require(
now <= auctionEnd,
"Auction already ended."
);
// If the bid is not higher, send the
// money back.
require(msg.value > highestBid);
require(
msg.value > highestBid,
"There already is a higher bid."
);
if (highestBid != 0) {
// Sending back the money by simply using
@ -324,8 +337,8 @@ activate themselves.
// external contracts.
// 1. Conditions
require(now >= auctionEnd); // auction did not yet end
require(!ended); // this function has already been called
require(now >= auctionEnd, "Auction not yet ended.");
require(!ended, "auctionEnd has already been called.");
// 2. Effects
ended = true;
@ -543,7 +556,7 @@ Safe Remote Purchase
function Purchase() public payable {
seller = msg.sender;
value = msg.value / 2;
require((2 * value) == msg.value);
require((2 * value) == msg.value, "Value has to be even.");
}
modifier condition(bool _condition) {
@ -552,17 +565,26 @@ Safe Remote Purchase
}
modifier onlyBuyer() {
require(msg.sender == buyer);
require(
msg.sender == buyer,
"Only buyer can call this."
);
_;
}
modifier onlySeller() {
require(msg.sender == seller);
require(
msg.sender == seller,
"Only seller can call this."
);
_;
}
modifier inState(State _state) {
require(state == _state);
require(
state == _state,
"Invalid state."
);
_;
}

View File

@ -68,7 +68,10 @@ Function modifiers can be used to amend the semantics of functions in a declarat
address public seller;
modifier onlySeller() { // Modifier
require(msg.sender == seller);
require(
msg.sender == seller,
"Only seller can call this."
);
_;
}

View File

@ -495,7 +495,10 @@ Another example that uses external function types::
oracle.query("USD", this.oracleResponse);
}
function oracleResponse(bytes response) public {
require(msg.sender == address(oracle));
require(
msg.sender == address(oracle),
"Only oracle can call this."
);
// Use the data
}
}

View File

@ -99,6 +99,8 @@ Error Handling
throws if the condition is not met - to be used for internal errors.
``require(bool condition)``:
throws if the condition is not met - to be used for errors in inputs or external components.
``require(bool condition, string message)``:
throws if the condition is not met - to be used for errors in inputs or external components. Also provides an error message.
``revert()``:
abort execution and revert state changes
``revert(string reason)``: