The Nonce (EVM)

What is the Nonce and its "optional" use - with Tatum

In blockchain technology, the nonce is a transaction counter that helps to prevent double-spending and replay attacks on a blockchain network. This value is attached to each Ethereum and EVM-compatible (Account Model) chain sender address.

Ethereum and other EVM-compatible blockchains require the nonce value for each transaction to ensure that the same transaction is not executed twice and that no one can replay a previously sent transaction.

With Tatum, when the nonce is not specified when making a transaction on Ethereum and other EVM-compatible chains, our Engine automatically adds it based on the sender's address.

🚧

The Tatum engine has a delay when automatically calculating the nonce. Users with a high transaction broadcast volume should use a manual nonce value. Otherwise, errors about "replacement transaction" will be common.

Finding the nonce value

v3 REST API

You can get the current nonce value for an EVM-compatible blockchain address by making an API call:

Example request:

curl --location 'https://api.tatum.io/v3/ethereum/transaction/count/0x271ebc3C939Db4d0######' \
--header 'x-api-key: {Mainnet_API_KEY}'
//response:
4887 // Current nonce value in decimals

RPC node request

You can also get the current nonce value using an Ethereum node's RPC call.

Example:

curl --location 'https://api.tatum.io/v3/blockchain/node/ETH/' \
--header 'x-api-key: {Mainnet_API_KEY}' \
--header 'Content-Type: application/json' \
--data '{
    "jsonrpc":"2.0",
    "method":"eth_getTransactionCount",
    "params":[
        "0x271ebc3C939Db4d0######'",
        "latest"
        ],
    "id":1
    }'
//response:
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": "0x1316" //needs conversion to decimal
}

Nonce value and dropped transactions

Single transaction

If a transaction with nonce value X is dropped or does not get included in a block, the nonce value from the sender's account does not increase. The nonce is only increased once a transaction is successfully included in a block.

Multiple transactions

If you try to send multiple transactions at the same time, each transaction must have nonce+1, nonce+2, nonce+3, nonce+4, etc. If for some reason the transaction with nonce+2 gets dropped (low gas price, network congestion, etc.), the transactions with values nonce+3 and nonce+4 will be stuck in the mempool and won't be mined until the transaction with nonce+2 is mined.

To solve this, you would need to re-send the transaction with nonce+2 with enough gas for it to be mined. Once the transaction with nonce+2 would be mined, any subsequent transactions with higher nonce value should be able to be mined too.

Implementing a Rapid-Fire Transaction Broadcast System

When building a production environment for EVM chains, it’s required to build a robust transaction queue system to efficiently manage the nonce and verify the status of transactions - once they're included in a block.

Nonce tracker

Every transaction from an account requires a unique nonce. Find more about it in the sections above.

📘

The nonce is only incremented when a transaction is included in a block.

Verifying Transaction Status

Transaction verification is a required step to ensure that your queue system operates correctly, particularly when dealing with failed transactions.

  • Native Asset Transactions: If a transaction involving native assets fails, it will not be included in a block, meaning the nonce remains unused. In this case, you must reuse the same nonce for a new transaction attempt.
  • Smart Contract Transactions: These are more complex. If a transaction fails during a Smart Contract Execution, it may still be included in a block, but with a status indicating a failed execution. In such cases, the nonce is spent, even though the transaction technically failed.
  • Dropped transactions from the Mempool: If a transaction is dropped from the mempool, it will not be included in a block, meaning the nonce remains unused. The transaction hash won't return a result in an explorer after a while either. In this case, you must reuse the same nonce for a new transaction attempt. Find additional information about dropped transactions in this article.

Key Points to Consider:

  • Webhook notifications typically return the transaction hash but do not include the transaction’s status.
  • To retrieve the status of a transaction, use an RPC call like eth_getTransactionReceipt or a REST API endpoint such as GetTransaction.

Building the Transaction Queue

To implement a reliable transaction queue system, consider the following high-level approach:

  1. Check the Current Nonce:
    • Before submitting a transaction, retrieve the current nonce from the sender's account.
  2. Submit the First Transaction "tx_#1":
    • Broadcast the transaction using the retrieved nonce.
  3. Verify the Transaction:
    • After submission, verify the status of "tx_#1":
      • If the status is "Success": Proceed to the next transaction with the incremented nonce.
      • If the status is "Failed":
        • Native Asset Transactions, the nonce remains available since the transaction was not included in a block. Resubmit the transaction using the same nonce.
        • Smart Contract Transactions, the nonce may be consumed even though the transaction failed. Proceed with the next nonce for subsequent transactions.
        • Dropped Transactions from the Mempool, the nonce remains available since the transaction was not included in a block. Resubmit the transaction using the same nonce.