-
-
Save gluk64/fdea559472d957f1138ed93bcbc6f78a to your computer and use it in GitHub Desktop.
// 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 |
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?
const a = await provider.getTransaction('0xdc6506137b443a6ad6734b0047a6d00d31748110589b379d72461bc57e510e94');
try {
let code = await provider.call(a, a.blockNumber)
} catch (err) {
const code = err.data.replace('Reverted ','');
console.log({err});
let reason = ethers.utils.toUtf8String('0x' + code.substr(138));
console.log('revert reason:', reason);
}
I had to catch one more level for it to work "ethers": "5.0.3",
The bash script gives an error
-bash: ./revert-reason.sh: line 9: syntax error near unexpected token `fi'
-bash: ./revert-reason.sh: line 9: `fi'
Should this snippet work also with latest 5.4 ethers.js please?
I'm trying it together with typescript and there is type issue between getTransaction()
returning TransactionResponse
and call()
method requesting TransactionRequest
.
When I tried to re-type it then I'm still receiving only:
code:'CALL_EXCEPTION'
data:'0x'
reason:'missing revert data in call exception'
Though you can use
ethers.utils.toUtf8String('0x' + code.substr(138));
on L27 and not needhex_to_ascii
at all
Wow it works!! But is this really all I need?
Should this snippet work also with latest 5.4 ethers.js please?
I'm trying it together with typescript and there is type issue between
getTransaction()
returningTransactionResponse
andcall()
method requestingTransactionRequest
.When I tried to re-type it then I'm still receiving only:
code:'CALL_EXCEPTION' data:'0x' reason:'missing revert data in call exception'
same with me
This works for me:
const tx = await provider.getTransaction(txHash)
const response = await provider.call(
{
to: tx.to,
from: tx.from,
nonce: tx.nonce,
gasLimit: tx.gasLimit,
gasPrice: tx.gasPrice,
data: tx.data,
value: tx.value,
chainId: tx.chainId,
type: tx.type ?? undefined,
accessList: tx.accessList,
},
tx.blockNumber,
)
// This should be your error code
const firstFourBytes = response.slice(0, 10)
const tx = await provider.getTransaction(txHash)
const response = await provider.call(
{
to: tx.to,
from: tx.from,
nonce: tx.nonce,
gasLimit: tx.gasLimit,
gasPrice: tx.gasPrice,
data: tx.data,
value: tx.value,
chainId: tx.chainId,
type: tx.type ?? undefined,
accessList: tx.accessList,
},
tx.blockNumber,
)
const reason = ethers.utils.toUtf8String('0x' + response.substring(138))
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?