One nonce at a time: Ethereum blockchain transactions

Valdi Kamenarov
4 min readOct 23, 2018

--

Blockchain is great and all, but just as any great new technology it still has a long way to go until it reaches that level of maturity we all want in terms of infrastructure, development and accessibility.

The Ethereum Transaction & Nonce

Before going into the details, we need to know how transactions work in Ethereum. A transaction is simply a signed data package sent from an externally owned account to another account on the ethereum network. The transaction consists of a set of values (which you can find here) and a nonce which is what we are mainly interested in.

Keep in mind that we are talking about the transaction nonce here and not the
proof-of-work nonce:

Transaction nonceThe number of transactions made by the sender

Proof-of-work nonce​ — A meaningless value in a block which can be
adjusted in order to try to satisfy the proof of work condition.

When an account sends a new transaction, then the transaction nonce is
incremented. That does not sound very useful however, the transaction nonce is what stops people doing replay attacks on your account (e.g. re-running your transactions and draining your crypto, the DAO hack being a famous example). When two transactions with the same nonce enter the system, one of them is processed while the other is discarded which means there is no way of a transaction being processed multiple times. Another thing to consider is that future nonces that have a “gap” between the actual nonce and the new transaction nonce will not be fulfilled until that “gap” is filled.

A set of transactions with their nonces.

If you sent multiple transactions with your account and your 3rd transaction failed, then all subsequent transactions will be stuck and won’t process until a 3rd transaction has been processed.

Transaction Signing: Node vs Offline

In order for a transaction to be processed by the network, it needs to be packaged and signed with a private key of an externally owned account. Usually the blockchain node handles everything, however this could be a security risk because you’re sending your private key over the network to the blockchain node.

Another way of doing this is to sign your transaction outside the blockchain node and deliver the signed package to the node for processing. This method is used by hardware wallets and ensures that your private key is never sent in a public place, only the signed transaction. The complexity here arises from the fact that you need to build and sign the transaction yourself.

The Problem regarding the nonce

This is where the tricky part comes in. Let’s consider that an application needs to do transactions in bulk for a customer, you will have to make sure that the nonces are correctly set for each transaction.

There are ways of getting the transaction count through Ethereum’s JSON RPC API calls such as eth_getTransactionCount or a library such as web3. Unfortunately, this will not work most of the time; this functionality retrieves the transaction count for transactions in the current blocks and potentially pending block. What it does not take into consideration is the possibility of having additional​ transactions residing in the transaction pool (txpool). This would then return you the wrong nonce which has already been used by a transaction in the txpool.

Potential Solutions

Resolve the nonce in your application using the txpool

Even if eth_getTransactionCount does not return all transactions, you
can still retrieve the txpool, check for additional transactions there and
increment the nonce accordingly.

Pro:​ Ensures you have the correct nonce almost always (exception is node
being out of sync) and is node agnostic.

Con: ​Inefficient because you will need to fetch and iterate for every
transaction you create.

Use a Parity node implementation

The Parity node offers richer functionality compared to Geth and one of it is being able to get the nonce value using nextNonce(address).

Pro:​ More efficient nonce handling done on the blockchain node compared to the first solution.

Con: ​Limits the nodes your application can connect to, which is not ideal.

Completely handle the nonce within your application

A potential solution would be to create a custom transaction manager which is responsible for sequencing your transactions and allocating the nonces without the need to constantly query the nodes.

Pro:​ Likely to be faster than the other two potential solutions

Con:​ More isolated from the overall state of the blockchain which brings its own set of issues.

In summary, there are multiple potential solutions each with their pros and cons, as well as multiple additions and improvements such as transaction retrying, cancelling, etc. What is important to remember is that the whole blockchain ecosystem is still new, with many challenges and it’s up to us as Software Engineers to share our knowledge and help improve it.

--

--

Valdi Kamenarov

Software Engineer | Blockchain Developer | DeFi & Cryptocurrency Enthusiast