1

I have a smart contract with required message and pretend to use the required/validation message in front end.

require(bytes(hashAlreadyRegistered[hash]).length  == 0, "Hash already registered");

I'm trying to get the reason of revert using web3.eth.call.

By my understanding reading the doc if i pass the object generated by sendTransaction it will work. I think it is what i'm trying to do but didn't work so far.

My codes

sendTransaction method:

await canManipuleContract.methods.setDocumentHash('#_' + request.body.hash)
    .send({
      from: fromAddress,
      gas: 400000,
      gasPrice: 21000000000
    })
    .then(function(txRaw) {
      console.log(txRaw)
      return response.json( txRaw.transactionHash );
    })
    .catch(function(error) {
      handleRevert(error);
      console.log("Error: \n" + error);
      return response.json( 'error' )
    })
  }

web3.eth.call method:

function handleRevert( transactionObject ) {
    web3.eth.call( transactionObject, function( err, result ) {
      if ( ! err ) {
        console.log( 'result ' + result )
      }
      console.log( 'err ' +  err)
      //return response.json( 'Error: Returned error: execution reverted' )
    })
  }

The return value of handleRevert is always err 0x. In geth console i clearly see the value err and errdata returning the correct messages.

If i pass the contract address instead transactionObject in web3.eth.call method it always return Error: Returned error: execution reverted, but never the required message it self.

Version:

Geth: 1.9.15-stable

web3.js: ^1.2.8

What am i missing here? Any others methods to get the message required of smart contract will help here.

1

Try this,

async function getRevertReason(txHash){

  const tx = await web3.eth.getTransaction(txHash)

  var result = await web3.eth.call(tx, tx.blockNumber)

  result = result.startsWith('0x') ? result : `0x${result}`

  if (result && result.substr(138)) {

    const reason = web3.utils.toAscii(result.substr(138))
    console.log('Revert reason:', reason)
    return reason

  } else {

    console.log('Cannot get reason - No return value')

  }

}
| improve this answer | |
  • Oh yes, it works. But i'm not been able to get the txHash of the var error of catch block to pass into getRevertReason function. With e.g. console.log( "Error: \n" + errorTransaction ) it prints the entire object of reverted transaction. If i for example console.log( "Error: \n" + errorTransaction.transactionHash ) or any other property it throws undefined. any tip here? – RAFAEL DA SILVA Jun 27 at 1:19
  • i already tried to transform the object error to json and then parse or split it, but didn't sucessed. – RAFAEL DA SILVA Jun 27 at 1:27
  • also tried to change the send method to use callback but error callback always return null instead the reverted transaction. – RAFAEL DA SILVA Jun 27 at 1:56
  • remove await or write code inside try, catch block – Meet Siraja Jun 29 at 9:33
0

Web3 supports revert strings now: https://web3js.readthedocs.io/en/v1.2.8/web3-eth.html#handlerevert.

You can activate it easily by setting web3.eth.handleRevert = true. Now when you use call or send functions, precisely one of the following:

  • web3.eth.call()
  • web3.eth.sendTransaction()
  • contract.methods.myMethod(…).send(…)
  • contract.methods.myMethod(…).call(…)

you will see a new message like

Error: Your request got reverted with the following reason string: This is the revert reason!
| improve this answer | |
  • didn't work. I put web3.eth.handleRevert = true after beside the provider. e.g. const canManipuleContract = createContract(contractAddress), web3.eth.handleRevert = true; – RAFAEL DA SILVA Jun 27 at 1:22
  • @RAFAELDASILVA It seems there is a Web3 bug for geth 1.9.5. It's already fixed: github.com/ethereum/web3.js/pull/3571 but you'll have to wait for the next Web3 version to be released. – Markus - soliditydeveloper.com Jun 27 at 3:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.