Debugging Tx Revert Reasons in Ethereum with ZMOK: A Practical Guide

Debugging Tx Revert Reasons in Ethereum with ZMOK: A Practical Guide

In the complex world of Ethereum development, transactions don't always go as planned. When a transaction gets reverted, it's essential to understand the reason behind it. Debugging revert reasons is a crucial part of the process, and this tutorial provides you with two useful scripts for just that purpose. This tutorial is partially inspired by a useful Stack Exchange discussion.

Setup and Requirements

Before we start, you'll need the ethers.js library. If you haven't already installed it, you can do so with the following npm command:

npm install --save ethers

Set your environment variable ZMOK_MAINNET_ENDPOINT to point to the ZMOK endpoint URL. You can do this in your terminal or add it to a .env file in your project root:

export ZMOK_MAINNET_ENDPOINT='https://api.zmok.io/mainnet/YOUR_APP_ID'

Using ethers.js and ZMOK

Here, we'll use ethers.js, a complete Ethereum JavaScript library that allows you to interact with the Ethereum blockchain easily. We've modified the original script to use ZMOK as the Ethereum JSON-RPC provider.

Create a file called reason.js and add the following code:

const ethers = require('ethers')
const provider = new ethers.providers.JsonRpcProvider(process.env.ZMOK_MAINNET_ENDPOINT)

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.ZMOK_MAINNET_ENDPOINT)

    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 script allows you to input a transaction hash, and it outputs the revert reason:

node reason.js 0x9111550d7d87c2d5f0f88c99e0b53056631d5b597d3aeb4112faa68f1080fa0f

Using geth

If you're using geth, an implementation of the Ethereum protocol, we've got you covered. Save the following script as revert-reason:

#!/bin/bash

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 script fetches the revert reason for a given transaction hash.

About ZMOK

ZMOK is a high-speed JSON-RPC provider. It's built for developers who require reliable, fast interactions with the Ethereum blockchain. Consider switching to ZMOK if speed and reliability are critical to your Ethereum development. For more information, please visit our website at ZMOK.

Happy coding!