Randomness
鏈上隨機數生成器
我一直在對 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 。我認為雖然鏈上沒有真正的隨機性,但隨機性的類型可以不僅僅是統一的。
高斯隨機性可以提供獨特的集中趨勢,從而開闢新的可能性。