Solidity语言不提供随机数的相关函数,如果要使用随机数,要么使用第三方服务,要么自己生成伪随机数。我们在编写智能合约的适合,必须考虑使用场景:
场景一:批量创建随机数
function generateRandoms(uint256 count, uint256 maxValue) public view returns (uint256[] memory result) {
result = new uint256[](count);
uint256 randomHash = uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.coinbase, gasleft())));
for (uint256 i = 0; i < count; i++) {
result[i] = randomHash % maxValue;
randomHash = (randomHash > block.number) ? (randomHash - block.number) : (block.number - randomHash);
}
}
场景二:每次获取一个不同ID
uint256 constant MAX_POPULATION = 10;
uint256[] ids = new uint256[](MAX_POPULATION);
function pickId() public returns (uint256 id) {
require(ids.length > 0, "no id left");
// generate random hash and use it to pick a number between 0 and ids.length
uint256 randomIndex = uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.coinbase, gasleft()))) % ids.length;
// use current index or grab an old one
id = (ids[randomIndex] != 0) ? ids[randomIndex] : randomIndex;
// fill array position with value
uint256 lastPos = ids.length - 1;
ids[randomIndex] = (ids[lastPos] == 0) ? lastPos : ids[lastPos];
// shrink ids array
ids.pop();
}