關於EVM智能合約上的隨機種子產生, 因為ETH是非同步的系統,最後敲定結果的那個人對結果有很大的控制權。 來看個例子: 一個智能合約有個bid()函數,呼叫者要傳1 WETH過去,根據呼叫Tx的前一個區塊Blockhash (註: EVM不能取得目前區塊的Blockhash,因為合約都執行完後礦工才有辦法算出Blockhash),做一些運算後對6取餘數,如果餘0則呼叫者拿到6 WETH (=賺5 WETH),其他情況不給WETH (=賠1 WETH)。 這種合約很容易破解,首先礦工可以自己先算過後,在會中的情況才把自己下注的Tx包進候選區塊(不一定能進鏈),其他不中的情況就不包下注Tx進去。 非礦工的使用者雖然沒辦法在這個層級做手腳,但可以自己寫一個智能合約,同樣在會中的時候才去呼叫下注合約。如果不好事前計算擲骰結果,也有比較泛用一點的寫法是下注合約執行完畢後檢查帳戶的WETH是否增加,如果WETH沒增加就發個revert翻桌,整個Tx不算,等於沒賠下注金只賠gas fee;WETH有增加就正常結束。在沒有其他事前資訊的情況,可以看成平均發6筆Tx可以賺1筆,其他5筆不會賠下注金。 那如果把下注合約分成bid()和execute(),在bid()的時候下注,execute()的時候才計算結果呢?那只是把操控權移到了execute()的呼叫者上,同樣可以用合約控制在有利情況時才呼叫execute()函數。 再看另一種設計,bid()時下注並記錄下注資訊,然後以bid()之後的第16個區塊的Blockhash來計算擲骰結果 (例如在# 2000區塊的下注,便以# 2016區塊的Blockhash計算結果),之後呼叫execute()執行獎金分配 (基本上中了才需要領,沒中就可以不用發Tx了)。 實作上的問題是,EVM目前只能取得最近的256個區塊的Blockhash,也就是比方在# 2300呼叫execute()就取不到# 2016的Blockhash了。 這種設計某種程度上減少了可操縱性,結果敲定是在# 2016,execute的Tx其實不影響結果。而在# 2000 bid時很難確定# 2016是由誰挖出 (除非礦工可以挖出一條長度16區塊的攻擊鏈),所以頂多是礦工在挖# 2016的時候挖到Blockhash沒中的區塊可以扣下不發,但沒辦法阻止別的礦工挖出區塊,整體來說可能不如把區塊丟出去拿礦工費來得實際。
Log in to join in Reading is open to everyone. Replying needs an account.
No comments yet