aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-01-03 22:30:01 +0800
committerchriseth <chris@ethereum.org>2018-04-12 19:09:38 +0800
commit344a388d4461abd7369ea44b123f5afe549dc8f7 (patch)
tree46af2bf9ec5fa6aee5a0fafff3c01a50f79ffd51
parentaa715f8759934ac68b76a2bef84c460b68be636a (diff)
downloaddexon-solidity-344a388d4461abd7369ea44b123f5afe549dc8f7.tar
dexon-solidity-344a388d4461abd7369ea44b123f5afe549dc8f7.tar.gz
dexon-solidity-344a388d4461abd7369ea44b123f5afe549dc8f7.tar.bz2
dexon-solidity-344a388d4461abd7369ea44b123f5afe549dc8f7.tar.lz
dexon-solidity-344a388d4461abd7369ea44b123f5afe549dc8f7.tar.xz
dexon-solidity-344a388d4461abd7369ea44b123f5afe549dc8f7.tar.zst
dexon-solidity-344a388d4461abd7369ea44b123f5afe549dc8f7.zip
Update documentation.
-rw-r--r--docs/common-patterns.rst20
-rw-r--r--docs/contracts.rst10
-rw-r--r--docs/control-structures.rst16
-rw-r--r--docs/miscellaneous.rst3
-rw-r--r--docs/solidity-by-example.rst66
-rw-r--r--docs/structure-of-a-contract.rst5
-rw-r--r--docs/types.rst5
-rw-r--r--docs/units-and-global-variables.rst2
8 files changed, 92 insertions, 35 deletions
diff --git a/docs/common-patterns.rst b/docs/common-patterns.rst
index c62b5aca..233bdc4e 100644
--- a/docs/common-patterns.rst
+++ b/docs/common-patterns.rst
@@ -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."
+ );
_;
}
diff --git a/docs/contracts.rst b/docs/contracts.rst
index 0dd9845c..0c697dd6 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -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;
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index 18a02572..7e3027a0 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -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. \ No newline at end of file
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index c5178b51..8270727f 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -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``
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index 3636a332..3cbfcd66 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -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."
+ );
_;
}
diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst
index df40b1d0..9e5eacbb 100644
--- a/docs/structure-of-a-contract.rst
+++ b/docs/structure-of-a-contract.rst
@@ -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."
+ );
_;
}
diff --git a/docs/types.rst b/docs/types.rst
index 5de6d07e..07421bdf 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -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
}
}
diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst
index aad00ba2..9d5821d5 100644
--- a/docs/units-and-global-variables.rst
+++ b/docs/units-and-global-variables.rst
@@ -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)``: