Solidity
為什麼這個隨機算法不夠好?
乙太坊上的許多彩票使用隨機算法來確定“贏家”。例如,這個函式很糟糕,因為它有一些漏洞(在這裡閱讀一些):
function random() private view returns (uint){ /// players is an array of lottery participants return uint(keccak256(abi.encodePacked(block.difficulty, now, players))); }
對於這個問題,我有三種可能的解決方案,我想知道它們是否容易受到攻擊。
解決方案1)
我們可以使用 SecretKey,而不是使用參與者數組嗎?
基本上,彩票入口函式將暫停,SecretKey 將由伺服器端隨機算法確定,該算法將傳遞給智能合約並呼叫隨機函式。我們的函式變成:
function random() private view returns (uint){ return uint(keccak256(abi.encodePacked(block.difficulty, now, SecretKey))); }
解決方案2)
我們可以使用 now 或 block.difficulty 和兩個密鑰來代替嗎?這會進一步改善嗎?
解決方案 3)
我可以使用Oraclize API並使用集中式服務生成隨機數。
如果您將包含它的交易發送到智能合約,則密鑰不能保持秘密。從第一個瞬間開始,它應該在交易中很容易閱讀,即使在它處於未決狀態時,礦工也可以閱讀。
這種隨機數生成器(即基於區塊鏈上存在的數據)的問題在於,礦工可以讀取用於傳輸私鑰的交易並使用此資訊來預測或修改彩票結果。
例如,他可以發起一個更高優先級的交易(為它推大量的gas),該交易將在您的交易之前執行,在礦工的特殊交易執行後仍處於未決狀態,並將稍後執行。
不可能將某人(這裡的礦工)能夠預測的東西稱為“隨機”。
如果您在使用之前從礦工讀取外部數據(待計算)可讀(鏈下),也會存在同樣的問題。他可以閱讀、計算、預測。
至少你不能排除它。