Skip to content

Instantly share code, notes, and snippets.

// This is universal, works with Infura -- set provider accordingly
const ethers = require('ethers')
//const provider = ethers.getDefaultProvider('rinkeby')
const provider = new ethers.providers.JsonRpcProvider(process.env.WEB3_URL)
function hex_to_ascii(str1) {
var hex = str1.toString();
var str = '';
for (var n = 0; n < hex.length; n += 2) {
str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
}
return str;
}
async function reason() {
var args = process.argv.slice(2)
let hash = args[0]
console.log('tx hash:', hash)
console.log('provider:', process.env.WEB3_URL)
let tx = await provider.getTransaction(hash)
if (!tx) {
console.log('tx not found')
} else {
let code = await provider.call(tx, tx.blockNumber)
let reason = hex_to_ascii(code.substr(138))
console.log('revert reason:', reason)
}
}
reason()
#!/bin/bash
# This is for geth
# Fetching revert reason -- https://ethereum.stackexchange.com/questions/48383/how-to-receive-revert-reason-for-past-transactions
if [ -z "$1" ]
then
echo "Usage: revert-reason <TX_HASH>"
exit
fi
TX=$1
SCRIPT=" tx = eth.getTransaction( \"$TX\" ); tx.data = tx.input; eth.call(tx, tx.blockNumber)"
geth --exec "$SCRIPT" attach http://localhost:8545 | cut -d '"' -f 2 | cut -c139- | xxd -r -p
echo
@justinjmoses

Awesome - just what I was looking for!

@justinjmoses

Though you can use ethers.utils.toUtf8String('0x' + code.substr(138)); on L27 and not need hex_to_ascii at all

@amaurer

Thanks for putting this together. I forked and made a few mods including the above recommendation.

@justinjmoses

Nice. I bundled this up with some other features into https://github.com/justinjmoses/eth-reveal/

@msigwart

msigwart commented on Jul 16, 2019

Thanks, this is quite useful! I also forked and added a Go version of the script: https://gist.github.com/msigwart/d3e374a64c8718f8ac5ec04b5093597f

@shanefontaine

I added an NPM package, eth-revert-reason that will return the reason in any case (any network, Geth or Parity).

@EvilJordan

Please excuse the ignorance, but this does not work with ganache, correct?
provider.call() is not working for me after successfully retrieving the transaction, so maybe I'm doing something wrong?

@EvilJordan

Apologies for the multiple questions.

I tested this on Rinkeby (https://rinkeby.etherscan.io/tx/0x512b05c7fadf8c30fc62fb9400bbeb47169174d908648ac531f5db9dd1aeaa96) and, as you can see, it failed (on purpose by me setting the gas too low).

When this transaction was first called, and failed, my try/catch block output as part of the return in my console logs:

reason: 'transaction failed',
code: 'CALL_EXCEPTION',

However, when reason runs, no code is returned for the provider.call(), which I believe is somehow equivalent to provider.getTransaction(). Likewise, if I run provider.getTransactionReceipt(hash), the output contains no mention of a failure (unless one looks at status: 0):

{
  to: '0xaa4041ca5d6d14e566DCE4A70d3b9ad585F0Da64',
  from: '0xA0b5B95617a5c6Bf0116d47C2a4c93164aaE3328',
  contractAddress: null,
  transactionIndex: 3,
  gasUsed: BigNumber { _hex: '0x01823e', _isBigNumber: true },
  logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
  blockHash: '0x07c16e6922a64606c31bb742621eb1a93a57724c7cda771522315ef1d3bcc580',
  transactionHash: '0x512b05c7fadf8c30fc62fb9400bbeb47169174d908648ac531f5db9dd1aeaa96',
  logs: [],
  blockNumber: 6825108,
  confirmations: 64,
  cumulativeGasUsed: BigNumber { _hex: '0x034d77', _isBigNumber: true },
  status: 0,
  byzantium: true
}

Am I misunderstanding something here about how this is supposed to work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment