I've been trying to make a random number generator that doesn't need to be outsourced like Oraclize or break down at scale like RanDAO where n deposits gives 2^n possible manipulations for the random number.
What I was thinking is that you could use the same concept that gives the blockchain value to generate a random number.
So if you take amount of block confirmations needed for a transaction to be secure and use that many blocks to create a portion of a random number (based on the blockhash), you could effectively create a random number equal to that of even odds with enough sets.
As an example, let's say it's 6 confirmations for a transaction to be secure. This means that a miner can't mine 6 blocks in succession (otherwise there would be double spend attacks and no assurance in the blockchain, right?)
For example:
6 confirmation length
Base of 2
Targeted random number range of >1000
With 6 consecutive blocks, a miner would be able to manipulate the hash of the first 5 but not the 6th, giving them a 1/2 chance of getting their desire output.
Block 1: 0 (Manipulated by Miner)
Block 2: 0 (Manipulated by Miner)
Block 3: 0 (Manipulated by Miner)
Block 4: 0 (Manipulated by Miner)
Block 5: 0 (Manipulated by Miner)
Block 6: 1/2 Chance of the Miner's desired output
So for a random number range of >1000, you would need 10 6-blockhash sets (60 total hashes) to give a miner trying to manipulate the block a 1 / (2 ^ 10) or 1/1024 chance.
What I'm trying to achieve is to have a random number in a certain range, and using the number of block confirmations considered secure to give the same or better odds to a miner trying to manipulate said number.
Is my rationale right here or am I missing something critical?
Sorry if my explanation isn't great, but here's an example in solidity I've made called the Blockchain Assured Random Number Generator (BARN Generator) where you basically have to give it the base, ending block, confirmation length, and number of sets (base^number of sets should be >= the desired random number range).
contract BARNGenerator {
function BARNGenerator() {
}
function getRandomNumber(
uint _base,
uint _endBlock,
uint _confirmationLength,
uint _blockSets) returns(uint) {
uint[] numberArray;
uint totalBlocks = _blockSets * _confirmationLength;
if (_endBlock - totalBlocks < block.number) {revert();}
for (uint i; i < totalBlocks; i++) {
numberArray.push(uint(block.blockhash(_endBlock - i)) % _base);
}
return convertToDecimal(numberArray, _base);
}
function convertToDecimal(uint[] bitArray, uint _base) returns(uint) {
uint decimalSum = 0;
for (uint i=0; i< bitArray.length; i++) {
decimalSum += bitArray[i] * _base ** (i + 1);
}
return decimalSum;
}
}