1

I am doing a Lottery smart contract in solidity but sometimes when I execute the setWinner function I get an error. Can someone tell me why? I starting to program so I know my code isn't the best, I accept some recommendations. For exemple, for pick a random number, I took the hash of the timestamp and then I divided in 8 parts, each one for one number of the lottery game. Is there a better way to do it, instead of dividing it by two each time to get a random number?

function setWinner() public {

    bytes32 hash = keccak256(abi.encode(block.timestamp));


    bytes4[2] memory x0 = [bytes4(0), 0];
    assembly {
        mstore(x0, hash)
        mstore(add(x0, 4), hash)
    }
    bytes4[2] memory x1 = [bytes4(0), 0];
    assembly {
        mstore(x1, hash)
        mstore(add(x1, 8), hash)
    }
    bytes4[2] memory x2 = [bytes4(0), 0];
    assembly {
        mstore(x2, hash)
        mstore(add(x2, 12), hash)
    }
    bytes4[2] memory x3 = [bytes4(0), 0];
    assembly {
        mstore(x3, hash)
        mstore(add(x3, 16), hash)
    }
    bytes4[2] memory x4 = [bytes4(0), 0];
    assembly {
        mstore(x4, hash)
        mstore(add(x4, 20), hash)
    }
    bytes4[2] memory x5 = [bytes4(0), 0];
    assembly {
        mstore(x5, hash)
        mstore(add(x5, 24), hash)
    }
    bytes4[2] memory x6 = [bytes4(0), 0];
    assembly {
        mstore(x6, hash)
        mstore(add(x6, 28), hash)
    }
    bytes4[2] memory x7 = [bytes4(0), 0];
    assembly {
        mstore(x7, hash)
        mstore(add(x7, 32), hash)
    }

    uint n0 = uint32 (x0[1]); 
    n0 = n0%numberMax;
    uint n1 = uint32 (x1[1]); 
    n1 = n1%numberMax;
    uint n2 = uint32 (x2[1]); 
    n2 = n2%numberMax;
    uint n3 = uint32 (x3[1]); 
    n3 = n3%numberMax;
    uint n4 = uint32 (x4[1]); 
    n4 = n4%numberMax;
    uint n5 = uint32 (x5[1]); 
    n5 = n5%numberMax;
    uint n6 = uint32 (x6[1]); 
    n6 = n6%numberMax;
    uint n7 = uint32 (x7[1]); 
    n7 = n7%numberMax;

    //emit numbersCheck(n0,n1,n2,n3,n4,n5,n6,n7);

    uint[qntNumbers] memory tabNumbers = [n0,n1,n2,n3,n4,n5,n6,n7];

    quickSort(tabNumbers,0,tabNumbers.length -1);
    //emit tabCheck(tabNumbers);

    /*for (uint i=0;i<tabNumbers.length;i++){

        if (tabNumbers[i]==0){
                tabNumbers[i]= 60;                
            }
        if ( (i <= tabNumbers.length)&& (tabNumbers[i]==tabNumbers[i+1])){

            tabNumbers[i+1]= tabNumbers[i+1] + 1;

        }
    }
    quickSort(tabNumbers,0,tabNumbers.length -1);*/
    //emit tabCheck(tabNumbers);
    removeDoubles(tabNumbers);

    winnerGame = tabNumbers;

}
user94559
  • 59,196
  • 6
  • 103
  • 103
sthiagolg
  • 21
  • 2
  • What exact are you getting? – Khaja Mohammed Jan 23 '19 at 03:35
  • It says that the transaction was mined but failed. In etherscan it tells me it run out of gas, take a look: https://rinkeby.etherscan.io/tx/0x9b8bcc9568248b7785b66f51440505b11abb813fa596cbac5be6c40cb5b5a2e0 – sthiagolg Jan 23 '19 at 09:46
  • It says that the transaction was mined but failed. In etherscan it tells me [invalid opcode Oxfe] https://rinkeby.etherscan.io/tx/0x03e23da1ed05f8f709dfbb413674af9d8e2d9e1199fda24efeed29db850b6aa8 – sthiagolg Jan 23 '19 at 10:26
  • There are these two erros, but sometimes it works. So I'm a little lost – sthiagolg Jan 23 '19 at 10:27
  • All these transactions failed https://rinkeby.etherscan.io/tx/0x214e7b3ba7bd8c7afd2ec06f93a1f7b3c2f489531137239a1923f8c4f595966d – sthiagolg Jan 23 '19 at 10:40

1 Answers1

1

block.timestamp is a bad source of entropy. You should avoid it to keep your contract safe from malicious participants.

When submitting blocks, miners determine the value of block.timestamp and so could trivially affect the outcome of your lottery.

You might refer to these similar SO questions: