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 such as web3 to read revert output, same as it's not possible to read the output in case of a normal transaction completion. Revert uses output data o
as defined in the yellow paper which can be used for message calls but is ignored for transactions.
message calls also have an extra component—the output data denoted by the byte array o. This is ignored when executing transactions, however message calls can be initiated due to VM-code execution and in this case this information is used.
The effect of the REVERT opcode is given by the formula 140 which references output o
.
Remix, however, shows the output when using JavaScript VM, because it executes transactions synchronously:
pragma solidity^0.4.11;
contract C {
function testRevert() pure public returns (uint result) {
uint memOffset;
assembly {
memOffset := msize() // Get the highest available block of memory
mstore(add(memOffset, 0x00), 6) // Set value
mstore(0x40, add(memOffset, 0x20)) // Update the msize offset to be our memory reference plus the amount of bytes we're using
revert(memOffset, 0x20) // revert returning 1 byte
}
}
}
Decoded output:
{
"0": "uint256: result 6"
}
When executing on testnets or mainnet, there is no output.
It should be possible to read the revert output when using low-level assembly call
, delegatecall
, callcode
(I'm going to update this answer whenever I have a working code example).
I expect a try-catch
-like feature will be added in Solidity when using its call
, delegatecall
, callcode
and calling contracts via their interface (will update the answer whenever I have references).
@henkiedoodle's comment is correct, it would be much simpler and easier to compare hashes of the strings.
You are unable to directly compare strings, (ie return(s1 == s1)
will give the error
TypeError: Operator == not compatible with types string memory and string memory
), but if the strings are identical then so will their hashes be.
The full function could then be simplified to
function compareStringsbyBytes(string s1, string s2) public pure returns(bool){
return keccak256(s1) == keccak256(s2);
}
However, in future if you receive the out of gas error, you may also want to try increasing the gas limit of your transaction.
Update: the above answer (and the question) were both circa Solidity 0.4.X. For 0.5.X, the following would be a valid compare function
function compareStringsbyBytes(string memory s1, string memory s2) public pure returns(bool){
return keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2));
}
Best Answer
offset
is the starting position of the desired return data in memory andsize
is the size of the desired return data in memory.Offset
andsize
are used to designate where the return data starts (offset) and ends (offset + size) in memory.See: https://medium.com/@jtriley15/yul-vs-solidity-contract-comparison-2b6d9e9dc833