Solidity
在 Solidity 中隨機打亂映射
我正在嘗試隨機打亂 Solidity 中的映射。據我了解,這個問題有兩個部分:
- 使用安全的方式在智能合約中生成隨機數
- 改組映射 -我對這部分更感興趣
為了給你一個清晰的場景,我有一個狗的映射,從 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 }
輸出:
- 在第一次呼叫
giveFood
函式之前 - 狗的映射:| 0.查理 | 1.銅 | 2.最大 |- 在第一次呼叫
giveFood
函式後 - 狗的映射:| 0.銅 | 1.最大 | 2.查理|- 在第二次呼叫
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; }
作為旁注,這種類型的操作需要大量的氣體,因此在鏈上進行操作並不理想。
同樣正如您在評論中所說,這並沒有隱藏誰發送了交易。如果您在另一個問題中解釋您想要實現的目標,還有其他方法可以潛在地隱藏哪個人做了什麼會消耗更少的氣體。