the scenario: a user has a privatekey and wants to sign something to send to the contract ex: the user send his (message,signature,publickey) to the contract and the contract can verify it with the arguments user provided and recorded it. But in this situation, when the record on the contract is (message,signature,publickey) an attacker can write arguments previous send by the user to overwrite present data, cause is signed by the user before the contract will verify it and record it on the contract

My question is that are there any chances that without adding another data structure like a counter (record on the contract and be part of the signature, i.e make the data to (msg,sig,pub,counter)) to avoid this kind of replay attack?


2 Answers 2


The signature only signs a specific message, so attackers can't use the same signature for a different message.

There is a class of attacks called replay attacks which apply to resending the same message when the user did not intend it. This can be discussed with regard to signing Ethereum transactions, or with regard to custom signing schemes created by contracts with the signed data passed as data.

For Ethereum transactions there is already a counter included in the signed data to handle exactly this problem, called the nonce.

If you're designing a custom signing scheme for a contract, you may well need to include some data to prevent transactions being replayed. The obvious solution is to add a nonce and keep track of each account's last nonce in contract storage. Alternatively you could store the actual hash of the signed message and refuse to accept the same message twice. However, this is not necessary in all cases, as for some contracts the message would only be applicable to a particular contract state, and would result in a revert if applied to an old contract state in any case, in which case the transaction could not be successfully replayed.

PS. In Ethereum it is not normally necessary to pass an argument for the pubkey, as this can be recovered from the signature.

  • Thanks is it possible to get some unique time or something instead using nonce? or are there anyway without the contract need to memorize the nonce?
    – js wang
    Nov 6, 2018 at 3:42
  • You could give messages a timestamp and have it expire, but that wouldn't stop someone replaying the message before it does. So you almost definitely need to store something to prevent replays, although like I say you may already be making a storage change that will do the job. Nov 6, 2018 at 4:30
  • Thanks, so it is necessary to add a data column to it.
    – js wang
    Nov 7, 2018 at 14:07

One a user makes a transaction to a contract the transaction is signed. Just checking msg.sender verify that whoever sent the transaction is in control of the private key.

Yet assuming that for some reason the user has to sign a message and send it, the attack can be avoided by requiring that the sender of the message is the one signing it, that is you check that msg.sender equals to the output of the verification of the signature (ecrecover).

Hope this helps

  • Thanks it seems a easy way to use msg.sender but are there alternatives way to do so(without msg.sender)?
    – js wang
    Nov 6, 2018 at 3:41
  • msg.sender is a globally available variable, why do you need a solution without using it? are there special restrictions in your application?
    – Jaime
    Nov 6, 2018 at 9:56
  • I'm thinking about(just thinking) maybe not to used only in ethereum(sorry, maybe this question shouldn't be here).
    – js wang
    Nov 7, 2018 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.