solidity 生成伪随机数

solidity 生成伪随机数

据说在以太坊上不可能生成真正的随机数,那我们就暂且叫这个是伪随机数吧。
曾经的Fomo3D就因为随机数的问题,被薅了不少羊毛,有兴趣的可以去查一下,我们这个合约规避了Fomo3D的漏洞,但是会引入其它问题,具体以后再谈。

随机数合约

pragma solidity ^0.5.0;

contract Random {

    uint256 private _seed = 0;

    /* constructor
     * */
    constructor() public {
    }   

    /* create random number
     * */
    function random(uint256 seed) public returns(uint256 ret) {
        require(msg.sender == tx.origin, "MUST_ORIDINARY_ACCOUNT");
        _seed += seed;
        ret = uint256(blockhash(block.number - 1));
        ret = uint256(keccak256(abi.encodePacked(ret, _seed)));
    }   

}

要点

  1. require判断调用者必须是普通账户。
  2. 中间可以添加其它因素或进行多次keccak256来生成随机数。我只是觉得太多的计算没什么必要,所以就简单实现了。

部署调用

$ python test_random.py 
random number: 0x70f00fce0faf1e32c16344fe2b465bd0cbb3106399d3e736f4e9afcfac431c0a
$ python test_random.py 
random number: 0xe77d252064f3b32401942bb2a1c5d1429f4a995a28224ac1f12fa0977d29b32b
$ python test_random.py 
random number: 0x4af5d7063e0160656802526c268c70b98e773fe75847a88069e1d0d4617e38ee

可以看到多次调用生成的随机数不一样。

总结

其实在以太坊上生成随机数是个很有意思的问题,欢迎有兴趣的小伙伴联系博主一起讨论研究。

你可能感兴趣的:(solidity 生成伪随机数)