Contract-Design
Solidity - 隨機地址指數
你好世界 !
我正在嘗試找到一種方法來洗牌 Solidity 中的一系列地址!
查看Underscore / Lodash原始碼
_.shuffle()
指出了一些事情。_.shuffle([1, 2, 3, 4]); * // => [4, 1, 3, 2]
就像是:
address[] public players; // Players addresses -> 0x00001, 0x00001, 0x00002 // _.shuffle(players[]); -> 0x00002, 0x00001, 0x00001 // _.shuffle(players[]); -> 0x00001, 0x00002, 0x00001
編輯範例:
address[] public players; function enter() public payable { require( msg.value >= .01 ether && msg.value % .01 ether == 0 ); uint ticketCount = msg.value / .01 ether; for(uint i = 0; i < ticketCount; i++){ players.push(msg.sender); } } function getPlayers() public view returns (address[]) { return players; } // Take this scenario, each ticket is worth 0.01 ether. // Two players decide to play. One buys 3 tickets and the other 2 tickets. // We push the first player address 3 times and 2 times into our players array. // Player 1 address is duplicated 3 times, players 2 address is duplicated twice. // In our players array there are a total of 5 addresses stored.
當我們在玩家存入乙太幣後呼叫 getPlayers() 函式時,我們得到:
0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C, 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C, 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C, 0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB, 0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB,
我很確定這是一種不好的方法,並且可能需要花費額外的氣體。在遊戲結束時,我們的玩家數組將重置,但我確信記錄玩家存款的數量可能是解決此問題的更好方法。我仍然希望找到一種更好的方法,而不是僅僅將大部分隨機邏輯移動到鏈外和鬆散的信任和安全性……
希望有人已經有更好的方法!
厭倦在鏈上做你不需要的事情是很重要的,並且洗牌可能是你需要考慮的事情,因為它可能會變得昂貴,而且很難在鏈上獲得真正的隨機性。
如果您想要一個打亂的數組,但不關心真正隨機(並假設基於您的程式碼玩家地址是通過玩家的某些操作添加的),那麼隨機插入可能更有意義,而不是洗牌一個完整的數組。
基本上如果你有一個數組
address[] public players; // 0xAAA, 0xCCC, 0xBBB
玩家
0xDDD
想玩,那麼你就有uint newPos = somePsuedoRandomFunction(); //newPos returns a number between 0 and players.length
如果
newPos == 4
,那麼你就players.push(`0xDDD`);
但是,例如
newPos == 1
,你會去players.push(players[1]); players[1] = 0xDDD;
這樣一來,您最終會得到一個改組的數組,並且 gas 成本將平均分配給每個玩家。