Solidity

我是否以不可變形的方式生成隨機數?

  • August 31, 2019

這是為我的特定案例生成數字的不可延展的方式嗎?

讓我解釋一下:
我允許人們註冊彩票類型的活動。

如果獲勝種子屬於他們的票組,他們將贏得選擇以參加未來的活動。

OBS:我知道多個獲勝種子可以與同一個註冊人相關聯,但這超出了這個問題的範圍。

這是一個例子。

   pragma solidity ^0.5.0;

   contract ExampleRNG {

       //@seedTrigger: number which triggers generation of a winning seed.
       uint public seedTrigger; 

       //@registrantCounter: counter which resets everytime a winning seed is generated.
       uint public registrantCounter;

       //@winningSeeds: array which stores the generated winning seeds. 
       //let's assume that this is a low number to avoid infinite loop discussions.
       uint[] internal winningSeeds;

       //@winningThreshold: number which if reached, restricts further seeding/registration activity. 
       uint public winningThreshold; 

       //@latestSeed: the latest seed generated from a new registration.
       bytes32 public latestSeed;

       //@stakes: total amount of stakes from registrations.
       uint public stakes;

       //@Tickets: struct to keep track of each registrant's ticket set (interval).
       struct Tickets {
           uint lower;
           uint upper;
       }

       //@ticketsets: storage of each registrant's ticket sets.
       mapping(address => Tickets) public ticketsets;


       constructor(uint _seedTrigger, uint _winningThreshold) public {
           seedTrigger = _seedTrigger;
           winningThreshold = _winningThreshold;
       }

       //@dev register to a lottery-type event.
       //@param stake: think of this as a weighted interest/probability for being selected as a winning seed. 
       function register(uint stake) external {
           require(winningSeeds.length <= winningThreshold, "[!] the registration activity has been closed");

           ticketsets[msg.sender].lower = stakes;
           ticketsets[msg.sender].upper = stakes + stake;

           latestSeed = keccak256(abi.encodePacked(latestSeed, stake));

           stakes = stakes + stake;

           registrantCounter++;

           if (registrantCounter == seedTrigger) {
               uint winningSeed = uint(latestSeed) % stakes;
               winningSeeds.push(winningSeed); 
               registrantCounter = 0;
           }
       }

       function revealWinningSeeds() external view returns(uint[] memory) {
           return(winningSeeds);
       }
   }

基本上,任何在合約中產生隨機性的方式都容易被濫用並且不安全。確定性合約在生成隨機數方面非常糟糕。

在您的情況下,很容易檢查最新的內容latestSeed,然後計算stake觸發獲勝的權利以使自己獲勝(或者如果目前不可能,則等待下一個latestSeed)。

要製作真正的隨機數,您需要外部幫助。Oracles 是一種選擇,但其中包括受信任的第三方。另一種選擇是 Randao ( https://github.com/randao/randao )

引用自:https://ethereum.stackexchange.com/questions/74432