Solidity
任何可以在同一塊中生成不同數字的偽隨機數生成器?
所有依賴於塊雜湊或塊時間的偽隨機數生成器似乎為同一個塊生成相同的“隨機”數。有沒有辦法在同一個塊中生成不同的數字?
案例是這樣的,我有一個遊戲合約,人們每次可以向這個合約發送 1 個 Ether,並且有 1% 的機會,發送者可能會收到儲存在合約中的所有 Ether。通常我使用帶有塊雜湊和東西的 PRNG,生成一個 uint256 數字,用 100 修改它,並在結果為 0 時獎勵發送者。
但是,存在一個問題,因為一個人(地址)可能同時向合約發送多筆交易(隨機數遞增)並且這些交易可能在單個區塊內被探勘,那麼“隨機”數字最終會成為所有這些交易都是一樣的。這意味著如果此人在第一筆交易中沒有中獎,他/她將無法在同一個區塊中開采的所有交易中中獎。這似乎對這個人不公平,因為我想設計遊戲,使一個人平均發送 100 筆交易,他/她將能夠贏一次。但是現在如果這個人連續發送了 100 筆交易,這些交易是在 10 個區塊中挖出來的(比如說每個區塊包含來自這個人的 10 筆交易),這意味著他/她只有 1/10 的機會贏得獎品。
自然地,我希望人們更多地參與到遊戲中,而不是在發送下一個交易之前等待探勘交易。那麼有沒有辦法讓 PRNG 為同一個區塊內的不同交易生成隨機數呢?
我查看了solidity docs,似乎有可能成為PRNG一部分的可用變數要麼與塊相關,要麼與msg.sender、msg.value、msg.data、tx.gasprice等類似. 在同一個區塊中開採時,這對於我的案例來說都是一樣的。不幸的是,nonce 在solidity 中不可用?我是否被迫為我的案例依賴一些鏈下集中式隨機數生成器?
每次生成數字時,您都可以使用遞增的隨機數。這將對雜湊輸出產生很大影響。
隨機 0-100 範例:
contract Random { uint nonce; function random() internal returns (uint) { uint random = uint(keccak256(now, msg.sender, nonce)) % 100; nonce++; return random; } function getRandom() external view returns (uint) { return random(); } }