Suppose I would like to organize a honest lottery and prevent cheating when we need to find a winner. I known problem of random number in the known network arises.
I would like to try the following algorithm to prevent cheating.
The idea is to use hash of a block but the block number is not known for miners/participants and organizers to prevent cheating.
- On start organizer defines a random uint64 – key number to be used in the winner random number calculation. The uint number is big enough and known to organizer only on start.
- Organizer fixes the key number by providing hash of sum – the number plus current block hash (as a salt).
The key hash is stored in the Lottery contract and available for all the participants. Then key hash is used to prevent organizers cheating and fixes the key number. - Participants buy tickets and the Lottery contract stores all the participant addresses. The addresses are used on winner calculation as well.
- When conditions are fulfilled (e.g. all the tickets are sold or necessary amount of blocks are generated or just after some time) organizer starts winner calculations.
- Organizer provides the stored key number and confirms the number is exactly the same by calculating the key hash (entered on init).
- The key number is added to the sum of addresses and we got mod 255 of the sum to detect number of block which hash is used to detect winner.
Key number + address1 + address2 … + addressN % 255 = number of winner block (the block hash is used to get winner number)
To person who want to guess winning number it is not possible to get the number – in the contract we have just hash of the number. The number is rather big uint64 (or could be even bigger) to prevent "unhashing" the number.
For organizers the number is fixed and is futile because all the tickets owners addresses must be known to calculate the winner.
Opinions? Any holes in the logic?
UPDATE:
After discussing the suggested algorithm there is an improvement.
- When a participant buys a ticket it is allowed to pass additional has for participant key number which is also used in the winner calculation.
- Suppose ticket price is 100%.
- When participant want to provide own participant key number he pays more e.g. 300%.
- When the participant key number is provided during the winner detection round 210% of ticket price is returned.
- If the participant key number is not provided the sum is added to the lottery prize.
Thus everybody who has doubts about organizer honesty can add own random part. Not providing the key means such a person lost the deposit.
Such honesty providers can have cheaper (in fact) tickets.
Best Answer
The organizer can cheat the system by attempting many different addresses, which, when added to your formula
Key number + address1 + address2 ... + addressN % 255
as the last address and getting the hash of the block, make this address the winner.You can think about it this way:
Key number + address1 + address2 ... + addressN % 255
is as secure as this oneaddress1 + address2 ... + addressN % 255
.As a result we came to a contradiction - we made the assumption that our system is secure in the beginning and at the end concluded that it's insecure. Thus our assumption is not correct.
What you should do instead is split the lottery into 2 phases:
When buying a ticket participants must include with the transaction:
When all tickets are sold (or after some expiration) everyone who bought a ticket in the 1st phase must reveal the secret number.
In a similar way RANDAO is implemented. Check out the section Additional Rules and Incentives for other things you need to make sure to prevent the possibility of cheating.
In particular, the deposit size summed with the ticket price has to be not lesser than the maximum reward (normally, total amount in the lottery). Any deposit smaller than this will give an opportunity for cheating as explained by lungj here