訪問不可預測的數字
我看到這在過去一直是一個廣泛討論的話題,但我仍然不明白為什麼未來的區塊雜湊不應該用於彩票類游戲。只要礦工不發布給定區塊(以改變遊戲結果)的動機小於叔塊獎勵與主塊獎勵的差異,這應該有效。假設如果在遊戲中輸了,礦工可以選擇以叔叔的身份發布,這樣區塊雜湊就不會決定遊戲的結果。
誠然,遊戲不會完全不受礦工影響,但考慮到區塊鏈一般都是基於讓每個人都誠實的激勵措施,這似乎是一個不錯的解決方案。有什麼我想念的嗎?
這很好地解釋了它:https ://hackernoon.com/building-a-raffle-contract-using-oraclize-e746e5edff6b?gi=8ca2440bbace
基本上,乙太坊網路上的所有計算都必須是確定性的,因此它們可以由網路上的不同節點驗證,如果它們都提出不同的數字,這將不起作用
你的說法
considering that blockchains, in general, are based on incentives to keep everyone honest
是錯誤的——區塊鍊是不可信的——它不需要依賴任何誠實的人,這就是為什麼每筆交易都在網路中的所有節點上得到驗證,這就是為什麼你需要對每筆交易進行確認。
無法猜測未來塊雜湊的概念忽略了攻擊者可能是專門建構的智能合約,將呼叫受害者合約的可能性。攻擊者不需要知道“未來”的塊雜湊,或者任何其他可能是變數的東西,因為它可以知道目前的塊雜湊。
考慮一下我為關於“隨機(ish)”數字的不同問題創建的這個小例子。
pragma solidity 0.5.1; contract Guess { function guessMe(uint guess) public returns(bool success) { return uint(blockhash(block.number)) == guess; } }
因此,看起來有人必鬚髮送 a
guess
,而他們能夠正確猜測(返回 true)的唯一方法是他們是否以某種方式知道未來。認真思考如何用對未來的神奇知識來玩這個小契約可能是有啟發性的。這樣做的方法如下。
劇透警報
現在,如果攻擊者是呼叫此函式的合約(或受人類攻擊者控制的合約),那麼知道目前塊的塊雜湊(無論何時恰好被探勘)都是微不足道的。這是:
uint(blockhash(block.number))
可以從合約中復製到攻擊。瑣碎的。
請記住,合約呼叫鏈總是在與單個原子交易相同的塊中完成。因此,攻擊者知道它將在與受害者完全相同的上下文中執行,並且可以訪問相同的變數。所以……它可以執行相同的計算。
contract Attack { Guess g; event LogSuccess(address sender, bool success); constructor(address guessIt) public { g = Guess(guessIt); } function nostrodamus() public { if(g.guessMe(uint(blockhash(block.number)))) { emit LogSuccess(msg.sender, true); } } }
該攻擊者每次都能夠產生正確的猜測。作者只需從要攻擊的合約中複製/粘貼表達式即可。
TL; 博士;
智能合約是確定性的,根據定義,生成其他人無法確認的東西比看起來更難。對此類假設要格外小心,並尋求同行評審和正式審計以避免悲傷。
我會爭辯說,依靠區塊雜湊對於這類事情是不夠的,除非你知道自己在做什麼,否則依靠它可能會導致悲傷,但這並不是不相容的事情。換句話說,不要在表達式中註意到它並假設該過程自動出錯。
探索的一種方法是送出/顯示過程,其中競爭者必須在一個塊中做出選擇,然後添加更多隨機性(額外的塊經過)。在許多情況下,真正的隨機數並不是嚴格的要求。無法猜測的數字(包括礦工勾結)可能就足夠了。
無論如何,不要低估難度級別。
希望能幫助到你。