Randomness

區塊雜湊對於寶藏生成功能是否足夠?

  • August 23, 2016

假設你的合約有一個生成隨機寶藏的功能,如下圖所示:

function generateTreasure() returns (Treasure) {
   if (msg.value < 1 ether) return; // cost of calling the message
   uint8 rnd = randomUint8();
   if (rnd ==  0) return rareTreasure;
   if (rnd <=  4) return averageTreasure;
   if (rnd <= 16) return commonTreasure;
   return garbage;
};

我想保證呼叫的使用者generateTreasure將無法通過任何外部手段欺騙結果 - 即,我希望平均而言,256 ether任何使用者獲得rareTreasure. rareTreasure如果攻擊者找到一種方法來獲得超過1/256平均每次generateTreasure呼叫次數的次數,那就不是真的了。

我知道礦工可以通過丟棄開采的區塊來欺騙它 - 但是,在這種情況下,情況有所不同。單個使用者可以generateTreasure在一個塊中多次呼叫,多個使用者可以呼叫它。當然,我不想為所有使用者提供相同的寶藏,因此,這需要某種形式的狀態隨機數 ( lastRandom),以便每個呼叫者獲得不同的號碼。但是,這意味著使用者可以創建一個讀取該隨機數的合約,並且僅generateTreasure在它提供具有所述塊雜湊的好寶藏時才呼叫!那是對的嗎?

那麼,考慮到所有因素,該函式最合適的隨機化是什麼?

但是,這意味著使用者可以創建一個讀取該隨機數的合約,並且僅在它提供具有所述塊雜湊的好寶藏時才呼叫 generateTreasure!那是對的嗎?

正確的。創建隨機數所需的變數可以直接用於惡意合約(例如,您的合約可以讀取區塊雜湊,但我的惡意合約也可以讀取它)或在發送交易之前已知(例如,如果您有隨機數)在你的契約中,我的邪惡契約無法讀取它,但我可以直接從儲存中讀取並將其發送到我的邪惡契約)。

有關如何執行此操作的詳細資訊,請參閱Martin Swende 的部落格。

稍微不那麼糟糕的是將其分為兩個步驟,因此玩家首先為契約提供資金,然後在獲得資金後根據雜湊 x 塊在另一筆交易中支付。這仍然可以玩,但我想不出沒有礦工幫助的方法。

如果你是這個合約中的房子(即參與者是在對你而不是彼此對賭),你可能想考慮一個送出和顯示方案,你首先提供一個雜湊並承諾顯示它的隨機數,然後玩家如果你沒有透露它會得到報酬。

或者,RandomDAO 對多個綁定參與者執行相同的操作。我不確定它在實踐中是否可用。

最後,您可以使用外部數據源,但您會信任某人。

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