Solidity

在 Solidity 中隨機打亂映射

  • June 2, 2022

我正在嘗試隨機打亂 Solidity 中的映射。據我了解,這個問題有兩個部分:

  1. 使用安全的方式在智能合約中生成隨機數
  2. 改組映射 -我對這部分更感興趣

為了給你一個清晰的場景,我有一個狗的映射,從 0 開始按 ID 組織。我有一個名為 的函式feedDog,它使用 dogID 呼叫。在一個人通過呼叫該函式餵狗之後feedDog,我想以某種方式洗牌狗的ID,所以沒人知道誰餵了哪隻狗。

struct Dog{
           string dogName;
           uint256 foodReceived; 
           uint256 dogID;
       }
   
   mapping(uint256 => Dog) private mappingOfDogs;
   
   function giveFood(uint256 dogID) public {
           mappingOfDogs[dogID].foodReceived++;  
           // random shuffling the mappingOfDogs occurs here, most likely
   
     
       }

輸出:

  1. 在第一次呼叫giveFood函式之前 - 狗的映射:| 0.查理 | 1.銅 | 2.最大 |
  2. 在第一次呼叫giveFood函式後 - 狗的映射:| 0.銅 | 1.最大 | 2.查理|
  3. 在第二次呼叫giveFood函式後 - 狗的映射:| 0.查理 | 1.最大 | 2. 銅 |

我知道映射不像數組,但是如果我們將 ID 保留在單獨的數組中呢?有沒有辦法以某種方式做到這一點?

假設您可以使用數組,則您的響應是一個非常直接的解決方案!

您可以使用 Fisher-Yates 洗牌!

它的要點是您將遍歷整個數組,在數組範圍內生成一個隨機數,並將循環的目前 i 的位置與您生成的隨機數的位置交換。

這是一個未經測試的虛擬碼實現

function shuffleArray(uint256[] memory array) {
 let curId = array.length;
 // There remain elements to shuffle
 while (0 !== curId) {
   // Pick a remaining element
   uint256 randId = randomNumber() % array.length; //Assuming you already have your randomNumber function
   curId -= 1;
   // Swap it with the current element.
   uint256 tmp = array[curId];
   array[curId] = array[randId];
   array[randId] = tmp;
 }
 return array;
}

作為旁注,這種類型的操作需要大量的氣體,因此在鏈上進行操作並不理想。

同樣正如您在評論中所說,這並沒有隱藏誰發送了交易。如果您在另一個問題中解釋您想要實現的目標,還有其他方法可以潛在地隱藏哪個人做了什麼會消耗更少的氣體。

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