Contract-Design

Solidity - 隨機地址指數

  • July 11, 2018

你好世界 !

我正在嘗試找到一種方法來洗牌 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 成本將平均分配給每個玩家。

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