From 3da16b3e8af41a1d743a94d2e19822e82440a63d Mon Sep 17 00:00:00 2001 From: chriseth Date: Sat, 30 Dec 2017 13:46:02 +0100 Subject: Documentation for revert with reason string. --- Changelog.md | 1 + docs/control-structures.rst | 26 ++++++++++++++++++++++++-- docs/miscellaneous.rst | 1 + docs/units-and-global-variables.rst | 2 ++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 6288e848..60f28db4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Features: * Code Generator: More specialized and thus optimized implementation for ``x.push(...)`` * Commandline interface: Error when missing or inaccessible file detected. Suppress it with the ``--ignore-missing`` flag. * Constant Evaluator: Fix evaluation of single element tuples. + * General: Allow providing reason string for ``revert()``. * General: Limit the number of errors output in a single run to 256. * General: Support accessing dynamic return data in post-byzantium EVMs. * Interfaces: Allow overriding external functions in interfaces with public in an implementing contract. diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 40070a20..18a02572 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -455,8 +455,9 @@ The ``require`` function should be used to ensure valid conditions, such as inpu If used properly, analysis tools can evaluate your contract to identify the conditions and function calls which will reach a failing ``assert``. Properly functioning code should never reach a failing assert statement; if this happens there is a bug in your contract which you should fix. There are two other ways to trigger exceptions: The ``revert`` function can be used to flag an error and -revert the current call. In the future it might be possible to also include details about the error -in a call to ``revert``. The ``throw`` keyword can also be used as an alternative to ``revert()``. +revert the current call. It is possible to provide a string message containing details about the error +that will be passed back to the caller. +The ``throw`` keyword can also be used as an alternative to ``revert()``, but is deprecated. .. note:: From version 0.4.13 the ``throw`` keyword is deprecated and will be phased out in the future. @@ -515,3 +516,24 @@ the EVM to revert all changes made to the state. The reason for reverting is tha did not occur. Because we want to retain the atomicity of transactions, the safest thing to do is to revert all changes and make the whole transaction (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: + +:: + + pragma solidity ^0.4.0; + + contract VendingMachine { + function buy(uint amount) payable { + if (amount > msg.value / 2 ether) + revert("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 +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 20400aa2..c5178b51 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -334,6 +334,7 @@ Global Variables - ``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) - ``revert()``: abort execution and revert state changes +- ``revert(string)``: 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 ` - ``sha3(...) returns (bytes32)``: an alias to ``keccak256`` diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index e7f41ed1..aad00ba2 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -101,6 +101,8 @@ Error Handling throws if the condition is not met - to be used for errors in inputs or external components. ``revert()``: abort execution and revert state changes +``revert(string reason)``: + abort execution and revert state changes, providing an explanatory string .. index:: keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, -- cgit v1.2.3