This is the sixth in a series of posts where we discuss the core concepts behind the Blockchain, Bitcoin and Ethereum. At Verify, we’re building a reputation protocol on the Ethereum blockchain and are sharing these posts in an effort to share our knowledge with the wider crypto community.
In Ethereum ABC, we introduced the account’s fields. We mentioned the nonce field, but never explained it. This post will dive into that.
Every transaction in Ethereum has what is called a nonce. We first saw the word nonce in our talk about Bitcoins mining, used to find proof of work; is it the same nonce in Ethereum transactions? Let us look into this question.
In Ethereum there is a nonce for the block, which is similar to what we have been introduced to in Bitcoin. There is also a noncefor every transaction (in external accounts). It is the number of transactions made or sent from a given address. Whenever you send a transaction the nonce is incremented by one. The reason for a nonce in a transaction is to ensure:
That transactions are executed in order.
You may have already guessed why this is important. Well, you guessed right: it is to prevent double-spends. Consider an example where:
- you send out a transaction with normal GASPRICE, when it is waiting to be added by some miner
- you send out another transaction with high GASPRICE to have the second mined before the first, making the first transaction invalid.
That is why you have a nonce in Ethereum transactions, double-spends can never happen. A transaction of nonce 2 can never be mined before a transaction of nonce 1. Also note that a nonce can’t be skipped. Meaning if you sent out a transaction with nonce 3 without sending nonce 2 that can’t work. Nonces need to be sequential and in order, no skips.
What about contracts? They are a type of account so they too have a nonce right?
Yes they do and It basically does the same thing; it is a counter. In contracts, the nonce is the number of contracts created by the said contract. The nonce is only incremented when one contract creates another contract. When a contract calls a method in an existing contract the nonce will not be incremented.
The nonce number can be obtained as:
eth.getTransactionCount(accountAddress) //this returns a number.
Examine the above line for a second. “getTransactionCount”, does this mean this can only be used to get the transactions nonce? Unfortunately yes. There is no built-in method/function where a contract can access its nonce nor the external account’s nonce. Your way about it would be to store a counter in the contract and read/write as needed.
Now let us talk about the nonce in the Ethereum block.
Like Bitcoin, Ethereum requires proof of work (plans to move to proof of stake are already in motion). We have seen that in Bitcoin, the proof of work should conform to a target that should start with a number of zeros. That target keeps adjusting as difficulty increases or decreases. You can keep track of bitcoins difficulty here.
To generate a proof of work (PoW) the nonce is required as we have seen in the previous post of mining in bitcoin. We’ve also seen that the block generation difficulty calibrates every 2016 blocks, to keep the block generation within average of a single block every 10 minutes. The difficulty is correlated to block generation time. Meaning it will adjust either increase or decrease according to how fast block generation is. We basically want a block every 10 minutes (2016 blocks in 2 weeks).
Difficulty is calculated using the formula:
difficulty = difficulty_1_target / current_target
difficulty_1_target is the maximum target used by SHA256 mining devices, which is the highest possible target and is the first difficulty used when bitcoin was in genesis (i.e. the lowest possible difficulty of 1, since at genesis current_target is difficulty_1_target). Bitcoin stores it as a floating-point type:
From the representation:
Assuming the current block target is:
So the difficulty is (notice the division /):
0x00000000FFFF0000000000000000000000000000000000000000000000000000 / 0x00000000000404CB000000000000000000000000000000000000000000000000 = 16307.420938523983 (bdiff)
Bdiff means that we calculated difficulty using the floating-point format; which basically means that that block is 16307.4 times more difficult than when it was genesis. Assuming the current difficulty is equal to the highest possible target than the difficulty would be one and that is the minimum possible difficulty. So the lower the target the difficulty increases.
Let us quickly take a look at Block #488262 its hash is
- btw you can access latest block details at blockexplorer:
00c5 eace 6e24 0148 0149 9e99 3f07 bdd0 e36a 396f 6e9b 6588
One hex represents a nibble (4 bits), so each 4 zeros (4 hex digits) represent 16 bits (4 * 4 = 16 bits). We have 4 groups of 4 zeros. So 16 * 4 = 64 bits.
Now we still have 2 more zeros (8 bits)
0000 0000 0000 0000 c5 eace 6e24 0148 0149 9e99 3f07 bdd0 e36a 396f 6e9b 6588
64 + 8 = 72 bits leading 0s
Go back to blockexplorer and examine the bits fields; you will realize that the value in there is 1800fa73; it is in compact form. Let us see what we can get out of it.
The compact form is essentially a combination of two critical parts and are: the number of bytes and the other part is the prefix.
In 1800fa73 we have 18 in hex and converting to decimal it will result in 24; so this means there are 24 bytes (a byte is 8 bits, so 2 HEX numbers equates 1 byte).
The other part in 1800fa73 is the prefix. Putting it all together we will result in:
00fa73 000000000000000000000000000000000000000000 (total of 24 bytes).
Recall the hash is a 256 bit number, so a 32 byte number. For our number to be 32 bytes it needs an extra 8 bytes of zeros so we add 16 zeros in front (in hex):
Now to get the difficulty we do (difficulty_1_target / current_target):
0x00000000FFFF0000000000000000000000000000000000000000000000000000 / 0x000000000000000000FA73000000000000000000000000000000000000000000
We get 1.1238633e+12 which basically = 1123863285132 the difficulty obtained So we want the block to be hashed/ proof of work with a number lower than the target which we obtained from the bits field 1800fa73; using that we can calculate difficulty of hash. Remember difficulty keeps adjusting to conform with 10 minutes/block rule. In Bitcoin, you change the nonce to get a proof of work that conforms with the target.
In Ethereum it is a little different. First of all it is still going through release stages. It was at a stage called Frontier and now it is at Homestead. So expect things to change as things progress. Proof of work in Ethereum still uses the nonce to generate the proof of work however instead of bits in bitcoin there is difficulty field in Ethereum.
The ethereum block itself has more fields than that in Bitcoin. An Ethereum block, aside from the transactions, also has a hash of the most recent state, difficulty and block number. The purpose of the nonce here is to find a proof of work in relation with the difficulty threshold.
The difficulty in the Ethereum block is used to calculate the target for proof of work. It is used to control how difficult proof of work is. It is set to keep the network at a block every 15 seconds (it used to be 12 seconds in the original frontier version of Ethereum). A block every 15 seconds would make it hard to create a fork that is longer than the network unless you have more power than the network.
So we see that for blocks, nonces basically do the same thing. In Ethereum things differ a little from Bitcoin (aside from the proof of work algorithm), the difficulty is considered in deciding which block to include in the blockchain.
Verify is a Reputation Protocol for buying and selling things using
cryptocurrencies → https://verify.as/