Randomness

鏈上隨機數生成器

  • April 9, 2022

我一直在對 gasleft() (曾經是 msg.gas 但現在已棄用)進行一些研究,但無法找到有關如何或在何處定義此值的任何細節。我能夠找到另一個詳細的乙太坊堆棧交換文章,討論在函式呼叫的每一步之後 gasleft 遞減。

如果 gasleft 僅在 EVM 指令執行期間計算並可用,這是否意味著它是不確定的並且可以用於隨機數生成?如果不是,那麼在用於生成隨機數的場景中,如何計算一條指令嘗試利用它的成本?任何人都可以在發送交易時更改 gasLimit,這在我的理解中會導致不確定性。

src:msg.gas 是如何計算的?

//gasLimit => 1000000

Random Instructions Costing GAS
gasleft(); => 870000
Random Instructions Costing GAS
gasleft(); => 820000
uint256 randomNumber = random();
Do Something With randomNumber

function random() internal returns (uint256) {
   return uint256(keccak256(abi.encodePacked(gasleft())));
}

除此之外,我編寫了一個簡單的腳本,這意味著 gas 成本會根據決定在一波中“鑄造”的人數而變化。

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.0;

contract TimebasedRNG {
   mapping (address => uint256) addressToTimestamp;
   address[] currentWaveMinters;
   uint256 currentWaveTime;
   uint256[] public randoms;

   function mint() external {
       require(addressToTimestamp[msg.sender] == 0, "already minted within a minute");
       if (currentWaveTime == 0) {
           currentWaveTime = block.timestamp;
           delete randoms;
       }
       currentWaveMinters.push(msg.sender);
       addressToTimestamp[msg.sender] = block.timestamp;

       if (hasBeenOneMinute()) {
           uint256 seed = 0;
           uint256 random;
           for (uint i = 0; i < currentWaveMinters.length; i++) {
               seed = uint256(keccak256(abi.encodePacked(
                   seed,
                   currentWaveMinters[i],
                   addressToTimestamp[currentWaveMinters[i]],
                   currentWaveTime,
                   gasleft()
               )));
           }

           for (uint i = 0; i < currentWaveMinters.length; i++) {
               random = uint256(keccak256(abi.encodePacked(
                   seed,
                   currentWaveMinters[i],
                   addressToTimestamp[currentWaveMinters[i]],
                   currentWaveTime
               )));
               randoms.push(random);
               delete addressToTimestamp[currentWaveMinters[i]];
           }
           delete currentWaveMinters;
           delete currentWaveTime;
       }
   }

   function hasBeenOneMinute() public view returns (bool) {
       return (block.timestamp - currentWaveTime) > 20 seconds;
   }
}

這是否足以成為一個難以利用的偽隨機數生成器?

這是否意味著它是不確定的

區塊鏈上的一切都是確定性的。否則它們將無法執行。因此,您的想法沒有意義。

在此處查看此鏈上高斯 RNG 。我認為雖然鏈上沒有真正的隨機性,但隨機性的類型可以不僅僅是統一的。

高斯隨機性可以提供獨特的集中趨勢,從而開闢新的可能性。

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