diff --git a/contracts/pandora/lottery/RandomEngine.sol b/contracts/pandora/lottery/RandomEngine.sol index ec183ed..0529509 100644 --- a/contracts/pandora/lottery/RandomEngine.sol +++ b/contracts/pandora/lottery/RandomEngine.sol @@ -3,16 +3,24 @@ pragma solidity ^0.4.23; import "./ILotteryEngine.sol"; contract RandomEngine is ILotteryEngine { + bytes32 baseHash; + uint256 lastBlockNumber; constructor() public { + lastBlockNumber = block.number; } // Current implementation able to return one unique value per block - //todo add request count dependency function getRandom(uint256 _max) public returns (uint256 o_result) { - o_result = (uint(blockhash(block.number)) + uint(blockhash(block.number - 10))) % _max; + if (block.number > lastBlockNumber) { + lastBlockNumber = block.number; + baseHash = keccak256((uint256(blockhash(block.number)) + uint256(blockhash(block.number - 10)))); + } else { + baseHash = keccak256(baseHash); + } + o_result = uint256(baseHash) % _max; } } diff --git a/test/test_pandora_lottery_random_engine.js b/test/test_pandora_lottery_random_engine.js new file mode 100644 index 0000000..e51e538 --- /dev/null +++ b/test/test_pandora_lottery_random_engine.js @@ -0,0 +1,19 @@ +const RandomEngine = artifacts.require('RandomEngine'); + +contract('RandomEngine', accounts => { + + let max = 9999; + let engine; + + before('setup test random engine', async () => { + engine = await RandomEngine.new(); + }); + + it('should return different numbers each call', async () => { + const [r1, r2] = await Promise.all([ + engine.getRandom.call(max), + engine.getRandom.call(max), + ]); + assert.isOk(r1 !== r2, 'random is the same as previous'); + }); +});