Great thanks @Achal Singh for your answer - https://ethereum.stackexchange.com/a/82318/93117.
Here is a variation:
- for
Hardhat dev environments
- generalised console.log outputs (rather than looking for specific fields),
- made it for
Ethers 6
- print out the function that was called (if any and if none ... well then I've left it as a reader exercise to fix).
- Loops over list of ABIs you have created in your artifacts folder (you need to create list ... reader exercise to automate this!)
I use a separate calling script parseTransactionCall.sh so i can pass a transaction as an arg.
NOTE my use of a separate tsconfig.hardhat.json so i can have contracts and front-end typescript in same project.
parseTransactionCall.sh:
#!/usr/bin/env sh
npx hardhat --tsconfig tsconfig.hardhat.json vars set TX $1
npx hardhat --tsconfig tsconfig.hardhat.json run scripts/parseTransaction.ts
parseTransaction.ts:
/*
* Decode information from transaction. Usage:
* - CALL THIS USING parseTransactionCall.sh as it allows passing in TX as argument
* > parseTransactionCall.sh <TX>
* - Add any ABIs to the list at top of script.
*/
import * as JSONbig from "json-bigint";
import {vars} from "hardhat/config";
const { ethers } = require('hardhat');
const abiEvent = require("../src/artifacts/contracts/FunEvent.sol/FunEvent.json");
const abiFun = require("../src/artifacts/contracts/FunTShirts.sol/FunTShirts.json");
const abiNFT = require("../src/artifacts/contracts/FunNFT.sol/FunNFT.json");
type ABIENTRY = {
name: string,
abi: any
}
const abis: ABIENTRY[] = [
{name: "Event", abi: abiEvent},
{name: "Fun", abi: abiFun},
{name: "NFT", abi: abiNFT},
]
const provider = ethers.provider;
const transaction = vars.get("TX") || "0x9c17159774507a669ce1f8a9453998db98bc366555baa62e5b89909c6c8bb582";
console.log(transaction: ${transaction});
(async() => {
const tx = await provider.getTransaction(transaction);
console.log(transaction tx: ${JSONbig.stringify(tx, null, 2)})
if (tx == null) {
return;
}
for (const abiEntry of abis) {
console.log(TRY ABI: ${abiEntry.name})
const interfaceX:any = new ethers.Interface(abiEntry.abi.abi);
const decodedInput = interfaceX.parseTransaction(tx);
if (decodedInput == null) {
console.log(`decodedInput is null so try next`)
continue;
}
console.log(` decodedInput: ${JSONbig.stringify(decodedInput, null, 2)}`);
const abiFn = abiEntry.abi.abi.filter(a => a.name == decodedInput.name);
// Decoded Transaction
console.log(`Decoded Transaction`, {
transaction: transaction,
function_name: decodedInput.name,
fragment: decodedInput.fragment,
from: tx.from,
to: tx.to,
args: decodedInput.args,
erc20Value: Number(decodedInput.value)
});
console.log(`Function from ABI: ${JSONbig.stringify(abiFn, null, 2)}`);
}
})();
contract.addBalance.sendTransaction(contractAddress, {from: senderAddress, to: contractAddress, gas:1000000, value: web3.toWei(7, "ether"),data:web3.toHex("http://localhost:8545")})if I try to get web3.toAscii(transaction.input) it returns some random symbolic values – SwapnilKumbhar May 19 '17 at 12:04hexToAscii(), try usingweb3.hexToString()! Worked for me when neithertoAsciiortoUtf8were behaving properly. – ohsully Jun 07 '19 at 21:10web3.toAscii is not a function. To fix this issue, useweb3.utils.toAscii()instead – adamc May 04 '20 at 14:26