Solidity
throw
會阻止這種遞歸攻擊嗎?
我正在編寫一個基本合約,以在兩個地址之間平均分配乙太坊。
在我的
withdraw()
函式中,我有以下程式碼:function withdraw() { uint256 amount = this.balance / 2; addressOne.transfer(amount); addressTwo.transfer(amount); }
問題是,像這樣進行後續傳輸會導致遞歸攻擊。的所有者
addressOne
可以在餘額的另一半發送到 之前呼叫該函式並溢出堆棧addressTwo
。反复執行,owner
addressOne
可以根據序列耗盡合約(假設餘額相等,即沒有餘數):我提出的解決方案如下:
if(!addressOne.send(amount)) throw; if(!addressTwo.send(amount)) throw;
但是這樣的投擲會阻止同樣的攻擊嗎?
這份契約有幾個問題。
- 無論是否
throw
恢復交易,這都不會阻止重入攻擊。如果addressOne
是以下契約:contract AddressOne { function() payable { OriginalContract.withdraw(); // some case to stop recursion to prevent exhausting gas } }
addressOne``withdraw
可以在被呼叫時耗盡合約。您可以通過以下兩種方式之一來防止這種情況:使用提款流程,每個地址都可以隨意提取自己的資金份額,或者在合約全域狀態上放置互斥鎖。如果您想做前者,請查看我的splitter-contract範例。 2. 任何人都可以呼叫該withdraw
函式。我不認為這是故意的。如果我不正確,請糾正我。