Contract-Design
如何在我的智能合約中安全地生成隨機數?
如果我正在為某種(賭博)遊戲編寫智能合約,如何安全地生成隨機數?需要注意哪些最佳實踐和安全權衡?
在這方面有一些權衡和關鍵點需要牢記。
- 使用者做出的任何影響結果的決定都會給該使用者帶來不公平的優勢。範例包括:
- 使用區塊雜湊、時間戳或其他礦工定義的值。請記住,礦工可以選擇是否發佈區塊,因此他們可以想像他們開采的每個區塊都有機會獲得獎勵。
- 任何使用者送出的隨機數。即使使用者預先承諾了一個號碼,他們也可以選擇是否透露該號碼。
- 契約看到的一切,公眾都看到了。
- 這意味著在進入彩票關閉之前不應生成號碼。
- EVM 不會超越物理電腦。
- 合約生成的任何數字都可能在該區塊結束之前已知。在號碼的生成和使用之間留出時間。
現在來說技術:
完全去中心化的彩票式不可延展承諾:
- 賭場為隨機數預留獎勵
- 每個使用者生成自己的秘密隨機數
N
N
使用者通過使用他們的地址進行散列來創建他們的承諾:bytes32 hash = sha3(N,msg.sender)
1
- 注意:步驟 2 和 3 應在本地秘密執行
- 使用者將他們的雜湊值連同大於或等於隨機數值的乙太幣一起發送給合約。2
- 送出會持續一定數量的區塊,或者直到有足夠的參與者加入。
送出回合結束後,揭示回合開始。
N
每個使用者向合約送出他們的隨機數- 契約驗證
sha3(N,msg.sender)
與原始送出的匹配如果使用者沒有及時送出有效
N
的,他的押金將被沒收。
N
s 全部XOR
一起生成隨機數。- 此數字用於確定哪些參與者獲得獎勵。(
N % numUsers
) 3注意事項和替代方案:
1.
N
使用者必須在雜湊之前將他們的地址連接到他們的地址。否則,另一個使用者可以簡單地送出一個相同的雜湊,然後等待N
顯示,然後送出。N XOR N
等於 0,所以這可以用來取消除攻擊者之外的所有送出。
- 這就是權衡取捨的地方。最後一個透露他們的人可以
N
選擇是否透露。這基本上給了他們獲勝的雙重機會。輸入足夠多的次數,您就會為每個條目獲得一個新的選擇。*提示:礦工選擇一個區塊中的交易順序。*為了阻止這種情況,使用者必須支付大量保證金,等於他們通過操縱隨機數獲得的價值。對於許多使用者來說,這可能是一個問題,尤其是對於大額累積獎金,即使有博弈論優化也是如此。
- 一種常用的替代方案是半集中式系統。這要求“房子”送出第一個雜湊和最後一個顯示。如果房子不履行職責,每個人的乙太幣都會被退回。這存在一些問題,例如如果頭獎支付迫在眉睫,房子會選擇剝落。這個想法是房子的聲譽受到威脅。
- 請注意,這基本上集中了整個系統。一個人只需要拆掉房子就可以關閉整個操作。可以通過僱用多個受信任的非參與者作為第一個/最後一個送出者來降低這種風險。
- 另一個技巧是使用聘請的專業第三方為你“探勘”隨機性,這樣玩家就不必為這個過程而煩惱。
3.獎勵是必要的,以促進參與者之間的競爭。它導致了典型的公地悲劇/囚徒困境。參與者之間的勾結可以讓他們贏得一個大底池並在他們之間瓜分,但如果每個人都知道其他人會送出什麼,他們就知道自己應該送出什麼來贏得獎勵。因此,如果獎勵大於隨機數除以玩家人數的值,那麼每個人都會被激勵將自己的號碼保密,以便更好地獲得獎勵。請注意,只有一個參與者需要送出一個好的隨機數,結果將是不可預測的。