How to get the state of a transaction using Ethers JS and JavaScript

In this tutorial, we are going to learn how to get the state of a transaction using Ethers JS and JavaScript.

In this tutorial, we are going to learn how to get the state of a transaction using Ethers JS and JavaScript. We'll see how to check if the transaction failed, succeeded or if it's still pending.

In Ethers.JS, there is 2 methods to get a transaction. You can either use getTransaction or getTransactionReceipt.

The difference between the 2 methods is that getTransactionReceipt will only return something if the transaction is not pending, otherwise it just returns null as if the transaction didn't exist.

That means getTransactionReceipt returns more information about the transaction than getTransaction.

So there are multiple scenarios:

  • If you need information about a transaction that might be pending
    => use getTransaction
  • If you need to know the status of the transaction (successful, failed or pending)
    => you can use getTransaction, it will return an object with some properties set to null if the transaction is pending (see the details about the returned object below)
    => you can also use getTransactionReceipt, it will return null if the transaction is pending, but the problem is that you don't know if it's null because the transaction hash is wrong and doesn't exist of if it's just still pending.
  • If you need information about a transaction that is not pending or need information about the transaction that is only available when it's not pending anymore
    => use getTransactionReceipt

Get data about a transaction using getTransaction in Ethers JS

As explained above, getTransaction will have less information than getTransactionReceipt because the transaction might still be pending.

The getTransaction function takes in parameter the hash of the transaction you want to get and returns null if it doesn't exist, otherwise it returns the transaction information.

Example:

const ethers = require('ethers');

const provider = new ethers.providers.Web3Provider(YOUR_PROVIDER_HERE);

provider.getTransaction("0x331cd2ded0f91e6391786fc6aacd78a355e07bf5bcd099012e4016a48b09c5f7")
.then((transaction) => {
    console.log(transaction)
})

The getTransaction function returns an object that has the following properties if that transaction exists:

  • blockNumber: The block number this transaction will be mined in. It will be null if the transaction is still pending
  • blockHash: The hash of the block this transaction will be mined in. It will be null if the transaction is still pending
  • timestamp: The timestamp of the block this transaction will be mined in. It will be null if the transaction is still pending
  • confirmations: The number of block confirmations the transaction received. In other words, it's the number of blocks that have been mined (including the initial block) since this transaction was first included in a mined block.
  • raw: Information about the transaction in a raw hexadecimal string.
  • wait: A function that allows you to wait for the transaction to be completed.
  • type: A number that represents the EIP-2718 type of this transaction.
  • accessList: The AccessList array included in the transaction or null if the transaction type doesn't support access lists.

Note that sometimes, if you try to get a transaction that has just been created, the transaction is not in the transaction pool of your node provider so it will return null event if the transaction exists. All you have to do in that case is wait a little bit and try again.

The wait function

Now, we need to discuss more about that wait function that is in the transaction object.

The wait function allows you to wait for a transaction to be completed.

It takes in parameters the number of confirmations you want to wait for, it will be set to 1 by default.

It returns a promise that will be fulfilled and resolve with the transaction receipt if the transaction is successful.
Otherwise, if the transaction fails for some reason, the promise rejects and gives you an error that has information about the transaction and why it failed.

The error object will have the following properties:

  • transaction - the transaction data
  • transactionHash - the hash of the transaction
  • receipt - the receipt of the transaction (more information about that object below)

If the transaction failed because it was replaced by another transaction (a transaction with a higher nonce), the error will have these properties:

  • hash - the hash of the transaction
  • reason - the reason why it was replaced. Either "repriced", "cancelled" or "replaced"
  • cancelled - a boolean indicating if the transaction was cancelled or not (if the reason is "repriced", it will be false
  • replacement - the replacement transaction (same object as described above)
  • receipt - the receipt of the transaction that replaced this transaction (more information about transaction receipts below)

Get data about a transaction using getTransactionReceipt in Ethers JS

The getTransactionReceipt function can be used for a transaction that is not pending, otherwise it returns null.

Like getTransaction, getTransactionReceipt takes in parameter the hash of the transaction you want to get.

It returns a promise and when that promise resolves, you get the receipt of that transaction. If the transaction doesn't exist, it returns null.

Example:

const ethers = require('ethers');

const provider = new ethers.providers.Web3Provider(YOUR_PROVIDER_HERE);

provider.getTransactionReceipt("0x331cd2ded0f91e6391786fc6aacd78a355e07bf5bcd099012e4016a48b09c5f7")
.then((receipt) => {
    console.log(receipt)
})

If the transaction exists and is not pending, the receipt object will have the following properties:

  • to: A string containing the destination address of the transaction. It will be null if it's a transaction that deploys a smart contract
  • from: A string containing the address of the wallet that sent the transaction
  • contractAddress: If it's a transaction that deploys a smart contract, it will be a string that contains the address of the created smart contract, otherwise it's null
  • transactionIndex: The index of the transaction in the block in which the transaction was mined
  • gasUsed: The amount of gas used by this transaction.
  • effectiveGasPrice: The price of the gas the transaction was charged at
  • blockHash: The hash of the first block the transaction was included in
  • transactionHash: The hash of the transaction
  • logs: The logs emitted by this transaction (if it called a smart contract function)
  • blockNumber: The number of the block that this transaction was included in
  • confirmations: The number of block confirmations the transaction received. In other words, it's the number of blocks that have been mined (including the initial block) since this transaction was first included in a mined block.
  • status: 1 if the transaction was successful, 0 if it failed.

Then there are a few other properties which are only useful in very edge cases so it's not worth mentioning them here.

The problem now is that when you get a transaction that called a smart contract function and that the transaction failed because the smart contract reverted, you can't know why just like that.

It's quite complex to get the reason why a transaction reverted, so we will make a full article about it.

And that's it 🎉

Thank you for reading this article