1

I have a smart contract which generates a random number and compares it with the user's input to check if both are equals, and based on that it updates a mapping. But anyhow the same transaction is getting mined twice. Not able to understand what is going wrong.

//function to store the guess in the mapping when a guess is made.
function guessIt(uint _guess) public returns (bool) {
  //Need to check if the guess number is less than or equal tp range
  require(_guess <= range);
  uint random = generateRandomNumber(range);
  // uint random = 10;
  if (random == _guess) {
    Guess storage correctGuess = guesses[msg.sender];

    correctGuess.lastGuess = _guess;
    correctGuess.lastCorrectGuess = _guess;
    correctGuess.correctGuessCount = correctGuess.correctGuessCount + 1;
    correctGuess.lastGuessAt = now;
    totalNoOfGuesses = totalNoOfGuesses + 1;

    Guessed(msg.sender,random, _guess);

    return true;

   } else {
     Guess storage wrongGuess = guesses[msg.sender];

     wrongGuess.lastGuess = _guess;
     wrongGuess.wrongGuessCount = wrongGuess.wrongGuessCount + 1;
     wrongGuess.lastGuessAt = now;
     totalNoOfGuesses = totalNoOfGuesses + 1;

     Guessed(msg.sender,random, _guess);
   }
   return false;
}

This is how I am calling the function in my aap.js file.

checkMyGuess: function() {
    var guessInstance;
    var guessedNumber = parseInt($('#myGuess').val());
    console.log($('#myGuess').val());
    console.log($('#myGuess').val());
    var account = web3.eth.coinbase;
    App.contracts.GuessNumber.deployed().then(function(instance){
      guessInstance = instance;
      return guessInstance.guessIt(guessedNumber, {from: account});
    }).then(function(receipt){
      var guessResult;
      if (receipt.logs.length == 1) {
      guessResult = receipt.logs[0].args._randomNumber.toNumber() === receipt.logs[0].args._guess.toNumber() ? "Congrats!! You Guessed it correct" 
                      : "Sorry!! I thought it was " + receipt.logs[0].args._randomNumber.toNumber() + ".<br/> Better luck next time.";
      }
      $("#guessResult").html(guessResult);
    });
  }
Arindam
  • 121
  • 2
  • 1
    Hint: There is no such thing as randomnes in ethereum, except you're using oraclize.it – n1cK Jun 16 '18 at 12:55
  • How do you call your function? If you have two transactions then the problem is in the generation of transactions or on your node. – Ismael Jun 16 '18 at 13:08
  • @Ismael I have edited my post to include how I am calling the function. Thanks! – Arindam Jun 17 '18 at 04:38
  • I am not using oracles.
    My Random number function looks like.
    function generateRandomNumber(uint _range) public returns (uint) { return uint(sha3(block.timestamp)) % _range; } Is this not the way I am supposed to do it? I am not facing the problem always, its sporadic. @Ismael
    – Arindam Jun 17 '18 at 04:40
  • Using block info like timestamp as source of randomness is not recommended because it is easy to manipulate by miners. On your problem if checkMyGuess is called twice then it will generate two transactions. – Ismael Jun 18 '18 at 03:52
  • checkMyGuess is called only once. But What I am suspecting is, for multiple miners the random number would be different for different miners while they are mining and hence resulting in creating multiple blocks(though I am not very much sure about it) ? What do you think @Ismael ? – Arindam Jun 18 '18 at 05:38
  • See this question https://ethereum.stackexchange.com/questions/191/how-can-i-securely-generate-a-random-number-in-my-smart-contract that still is relevant. – Ismael Jun 18 '18 at 13:20

0 Answers0