-
-
Save msigwart/d3e374a64c8718f8ac5ec04b5093597f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"github.com/ethereum/go-ethereum" | |
"github.com/ethereum/go-ethereum/common" | |
"github.com/ethereum/go-ethereum/core/types" | |
"github.com/ethereum/go-ethereum/ethclient" | |
"log" | |
"math/big" | |
"os" | |
) | |
// Usage: | |
// go run revert-reason.go [transactionHash] | |
// | |
// Example: | |
// go run revert-reason.go 0xa6b112eedaa032be06cb73cb9dc70994ea7eb33d8cec9a4de7e28dcb26210969 | |
func main() { | |
if len(os.Args) != 2 { | |
log.Fatal("Usage: go run revert-reason.go [txHash]") | |
} | |
txHash := common.HexToHash(os.Args[1]) | |
// Connect to chain | |
client, err := ethclient.Dial("https://mainnet.infura.io") // --> change network here | |
if err != nil { | |
log.Fatal("Connection failed: " + err.Error()) | |
} | |
// Get transaction object | |
tx, isPending, err := client.TransactionByHash(context.Background(), txHash) | |
if err != nil { | |
log.Fatal("Transaction not found") | |
} | |
if isPending { | |
log.Fatal("Transaction is still pending") | |
} | |
chainID, err := client.NetworkID(context.Background()) | |
if err != nil { | |
log.Fatal(err) | |
} | |
msg, err := tx.AsMessage(types.NewEIP155Signer(chainID)) | |
if err != nil { | |
log.Fatal(err) | |
} | |
// Get transaction receipt | |
receipt, err := client.TransactionReceipt(context.Background(), tx.Hash()) | |
if err != nil { | |
log.Fatal("Failed to retrieve receipt: " + err.Error()) | |
} | |
if receipt.Status == 1 { | |
fmt.Println("Transaction was successful") | |
return | |
} | |
// Get failure reason | |
reason := getFailureReason(client, msg.From(), tx, receipt.BlockNumber) | |
fmt.Println("Revert reason: " + reason) | |
} | |
func getFailureReason(client *ethclient.Client, from common.Address, tx *types.Transaction, blockNumber *big.Int) string { | |
code, err := client.CallContract(context.Background(), createCallMsgFromTransaction(from, tx), blockNumber) | |
if err != nil { | |
log.Fatal("Cannot not get revert reason: " + err.Error()) | |
} | |
if len(code) == 0 { | |
return "no error message or out of gas" | |
} | |
return fmt.Sprintf(string(code[4:])) | |
} | |
func createCallMsgFromTransaction(from common.Address, tx *types.Transaction) ethereum.CallMsg { | |
return ethereum.CallMsg{ | |
From: from, | |
To: tx.To(), | |
Gas: tx.Gas(), | |
GasPrice: tx.GasPrice(), | |
Value: tx.Value(), | |
Data: tx.Data(), | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment