111

There are two aspects to consider when choosing between assert() and require() Gas efficiency Bytecode analysis 1. Gas efficiency assert(false) compiles to 0xfe, which is an invalid opcode, using up all remaining gas, and reverting all changes. require(false) compiles to 0xfd which is the REVERT opcode, meaning it will refund the remaining gas. The ...


47

Answer by example: Suppose you have a function that can be invoked only by the owner (deployer) of the contract. If it's invoked by anyone other than the owner, then it reverts (require with a false condition). File exceptions.js: module.exports.errTypes = { revert : "revert", outOfGas : "out of gas", invalidJump : "...


46

Summary After the Byzantium fork, eth.getTransactionReceipt(...) will return a status field. The status field has a value of 0 when a transaction has failed with the REVERT opcode and 1 when the transaction has succeeded. Update Oct 10 2017 Responding to the comment by @thomas-jay-rush, when a transaction fails for a reason other than REVERT (i.e. THROW), ...


26

Most of these answers are straightforward enough, but the ones that do an inline try catch make for quite a bit of boilerplate, and the creation of the utility functions is not really something you want to do yourself. This is exactly why I added revert and other failure testing as a feature to my truffle-assertions library. This allows you to assert ...


21

I'm using require for input validation as it's a little more efficient that if/throw. function foo(uint amount) { require(amount < totalAmount); ... } Where as assert should be used more for runtime error catching: function foo(uint amount) { ... __check = myAmount; myAmount -= amount; assert(myAmount < __check); ... }...


15

I'll leave the precise interpretation of the OpCodes to someone else and just point out that they are different instructions so different implementations are to be expected. According to this: http://solidity.readthedocs.io/en/develop/control-structures.html#error-handling-assert-require-revert-and-exceptions Starting with Metropolis, revert; will return ...


12

Solidity 0.6.0 and Greater (Updated 2020) As of Solidity 0.6.0, there is try-catch functionality built into the language. The syntax is similar to existing languages, however functionality is limited at this time to try expressions representing an external function call or a contract creation. The try part of the try-catch functionality is only able to the ...


9

I believe this pattern is not needed in versions of Solidity as old as 0.4.0 (released in September 2016). From https://github.com/ethereum/solidity/blob/develop/Changelog.md#040-2016-09-08 (my emphasis): Contracts that want to receive Ether with a plain "send" have to implement a fallback function with the payable modifier. Contracts now throw if no ...


9

Just the remaining gas. revert will keep unused gas: meaning the caller will have the unused gas to perform further computations. refund is different and you're correct that if revert gave back gas to the caller, that would allow DoS attacks (a caller could loop many times, then revert, loop, and revert infinitely).


8

It is simpler than you think: require(success, string (returndata)); See documentation for details. You may also forward raw bytes, but you will need to use assembly.


7

I think none of the answers is correct. assert is reserved for conditions for with it is expected that static code analysis tools (maybe Solidity compiler in future versions) will be able to detect the error warning the developer at compile time. require is reserved for error-conditions of incorrect input data to functions (when compared to expected/valid ...


7

In solidity 0.4.22 the require and revert reason were added. As can be seen here, they are abi-encoded as if it were a call to a function "Error(string)". This blog post gives an example: an eth_call to a function function myFunction(uint256 input) public view returns (uint256) { require(input >= 5, "myFunction only accepts arguments which are ...


6

Using eth_Call to execute function: Example.test(0x0000000000000000000000000000000000000000000000000000000000000002) of Example contract we will receive following reply from geth node: ...


6

As discussed in the comments, there is no easy way to get the revert reason in the Dapp. This feature might be supported in the future though. Here is the initial EIP and its discussion: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-658.md https://github.com/ethereum/EIPs/pull/658 Previous answer As I understand, it's not possible for a client ...


6

I modified shanes answer: function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) { // If the _res length is less than 68, then the transaction failed silently (without a revert message) if (_returnData.length < 68) return 'Transaction reverted silently'; assembly { // Slice the sighash. ...


6

The brownie.reverts context manager handles exactly this use case. The syntax is very similar to pytest.raises: import brownie def test_greet(example): with brownie.reverts("Hello World"): example.greet() Including the error string is optional, if you omit it you can catch any revert regardless of the message returned. Source: Brownie ...


5

The revert is often referred to as cheap throw as it refunds unused gas to the sender. If you are interested in the detailed design of this feature please look at the original EIP-140 discussion.


5

Fallback payable function was missing function() payable{ }


5

In solidity 0.4.22 the require and revert reason were added. As can be seen here, they are abi-encoded as if it were a call to a function "Error(string)". You'll need to make an eth_call to your contract. This blog post gives an example: an eth_call to a function function myFunction(uint256 input) public view returns (uint256) { require(input >= 5, ...


4

The function without a name: function () is called the fallback function. It is executed when the contract receives some ETH without a function being explicitly called. Putting revert(); in it means that you cannot send ETH to the contract without explicitly calling a payable function.


4

After being really annoyed for a long time I wrote a bash script to fetch the revert reason from geth by a tx hash: https://gist.github.com/gluk64/fdea559472d957f1138ed93bcbc6f78a


4

You can do something like this: it("test1.....", async() => { let instant = await myContract.deployed(); try{ await instant.doRevert(); } catch(e){ myHandleException(e); } . . . myHandleException being whatever function you want. If you're using callbacks instead of async(if you do something after your call) you can plug the catch ...


4

This code performs a delegate call and if the delegate call reverts, the transaction is reverted with the reason given by the delegate call. (bool success, bytes memory result) = address(_impl).delegatecall(signature); if (success == false) { assembly { let ptr := mload(0x40) let size := returndatasize returndatacopy(ptr, 0, size) ...


4

An interesting question! I could not find anything in the docs about this, but I also couldn't find anything about selfdestruct's gas refund (until I noticed this How do gas refunds work? ). I did some experimenting with the following contracts: pragma solidity ^0.7.0; contract A { function die() public { selfdestruct(msg.sender); } } ...


4

No, not all Ethereum networks return the revert reason in the message field. Kovan is an exception. As per the Infura documentation: On Mainnet, Rinkeby, Ropsten and Goerli, if this call causes the EVM to execute a REVERT operation, an error response of the following form is returned, with the revert reason pre-decoded as a string: { "jsonrpc": &...


3

A two-part answer. First, what we should be trying to do. Don't worry about trapping errors. This is the opposite of other platforms and styles where it is considered bad form to allow a hard stop to bubble up uncaught. Here, immutable software means expelling unnecessary complexity. Communicating the reason always introduces unnecessary complexity. A ...


3

The best option to fix your broken tests is to cast following code from the _deliverTokens function in Zeppelin's new "MintedCrowdsale.sol"(Zeppelin version 1.8) file in the following way: MintableToken(token).mint(beneficiary, amount); This allows for a compile, passing tests, and casting your token.


3

Revert, require, assert; they will all undo all changes to state, including events. If you wanted to halt execution of the function while still being able to log an event you would have to use if-else with a return. For example: contract test { function a(uint someNumber) public returns(bool) { if(someNumber > 5){ L(someNumber); ...


3

STOP is a valid stop to the contract. State changes are kept and unsued gas is refunded. INVALID will throw the transaction, its state changes and cause the consumption of all gas sent with it. As of Solidity 0.4.10 there is now a revert() call which enacts the REVERT opcode introduced in EIP140. This opcode, halts the contract, throws state changes but ...


3

You'll need to use a proper 20-byte address. In this case, you want the quoted string: "0x0000000000000000000000000000000000000000".


Only top voted, non community-wiki answers of a minimum length are eligible