The nonce parameter seems to be optional for transactions. Its goal is to protect from replay attacks. In that case, why is it optional, and what happens if it's not provided? It leaves the particular transaction prone to replay attacks?
3 Answers
If not provided then the nonce will be read from account's state on the blockchain (it is part of the blockchain state).
However, it can sometimes be useful to specify it explicitly. It might be useful, for example, if you need to re-send a transaction with a higher gas price if the first one is not being mined. If you send it again with the same nonce it will (may) over-write the first one.
So, the nonce does appear in all transactions whether you specify it or not, and it does protect against replay.
-
But if someone captures the raw singed transaction message that is sent to the network, they can re-send the same message? For example if I use etherescan.io/pushTx with a raw message, it will pass without a nonce. What stops Etherscan (or a MITM) to get the raw transaction and push it again?– BozhoAug 9, 2017 at 11:59
-
The transaction nonce from the sending account is included (always - but see Edmund Edgar's note about future plans) within the signed data when the transaction is generated. It is not possible to change it or replace it. I.e. the raw transaction includes the nonce. (Also sending the same message twice (with the same nonce) is not an error - it happens constantly within the network.) Aug 9, 2017 at 12:05
-
Hm,, I'll double check. I'm pretty sure I generated a raw transaction with no nonce and it got accepted :) (and nobody could have included it, as I didn't have a connected peer, it was just local RLP serialization)– BozhoAug 9, 2017 at 12:14
-
It's section 4.3 in the Yellow Paper for reference. The nonce is within the signed data of a transaction. If it isn't present the transaction will be invalid. Aug 9, 2017 at 12:20
-
maybe because it was my first transaction, it encodes null and that's the same as 0.. Thanks.– BozhoAug 9, 2017 at 12:26
The nonce is not optional. To be valid, a transaction must provide a nonce.
The nonce that you need to supply for the next transaction can usually be calculated by looking at the blockchain. Most wallets and other software that makes transactions will do this for you behind the scenes, so you don't need to supply the nonce yourself manually, unless you have unconfirmed transactions that the software you are using does not know about.
There is a plan to allow users to define their own schemes for signing transactions. If and when this is implemented, it will be possible to dispense with the nonce altogether if you don't need replay protection, or use a different system that better fits your needs.
-
But if someone captures the raw singed transaction message that is sent to the network, they can re-send the same message? For example if I use etherescan.io/pushTx with a raw message, it will pass without a nonce. What stops Etherscan (or a MITM) to get the raw transaction and push it again?– BozhoAug 9, 2017 at 12:00
-
No, the raw message is a signed transaction that includes a nonce. Aug 9, 2017 at 12:06
-
The ethereumj transaction seems to support getEncoded() (raw RLP) with null nonce: github.com/ethereum/ethereumj/blob/develop/ethereumj-core/src/… I think I used that and pushed the result to pushTx and it passed (in ropsten), but I'll double-check, maybe I missed something– BozhoAug 9, 2017 at 12:16
-
maybe because it was my first transaction, it encodes null and that's the same as 0..– BozhoAug 9, 2017 at 12:26
-
Yup, that's what I was going to suggest it could be. BTW the code you link looks like it also lets you encode a transaction without a signature, so it's conceivable that it lets you encode one without a nonce to then come back and decode and reencode it later, this time with the nonce and signature. Aug 9, 2017 at 12:30
what happens if it's not provided?
The nonce parameter gets incremented every time((Like an Identity column in SQL) when transaction happens and its not mandatory for you to set.
Optionally you can also set nonce for a transaction and there is a bonus answer below from reddit.
To proactively answer your next question.
What happens if I submit a transaction with a nonce that has already been transacted?
It will be rejected by the network What happens if I submit a nonce that's higher than the correct next nonce to use?
The transaction will get stored in the mempool of the nodes in a pending state. It will remain in the mempool of the node until transactions with all nonces between the last valid incremental nonce for the account and the transaction stored in the mempool have been transacted to the network, and then the transaction will be executed as normal. It's possible that the nodes eventually drop your transaction out of the mempool if it's been waiting there for too long