獲得這個合約的所有權,把合約的餘額歸零。
help()
指令)先根據提示提到的問題去做了解
當合約的 function 帶有 payable
時,就代表這支函式可以接受 ETH。當想透過 function 轉錢進去時,ETH 須使用 {}
存放參數。
假設想向 exampleContract
的 deposit()
存入 ETH 時,必須要這樣呼叫 function:
帶有payable
的 function 寫法可以參考:Solidity by Example - Payable
當你不打算透過合約裡的 function 發送 ETH,想直接將 ETH 發送至特定地址時,就需要透過這三個 function 進行轉帳
接受地址.transfer(金額)
接受地址.send(金額)
接受地址.call{value: 金額}("")
對於發送 ETH 的方法和說明可以參考以下幾篇:
Solidity 有內建單位,可以對數字直接換算:
當有人呼叫合約中不存在的 function 的時候fallback()
會被觸發,也可以用於收款。
直接向地址轉帳時,地址合約要有fallback()
或是receive()
才可以交易成功。
對於收款的流程和實作可以參考以下文章:
釐清提示後,這關的目標是成為合約的 owner 和將所有款項提出,開始閱讀關卡的合約。
要提款就是說要合約轉帳給你,所以要從合約中找到 call{value:}(), transfer(), send()
其中一個才有可能提款。在合約 30 行的 withdraw()
可以找到,這個函式會將合約中的所有資產轉給 owner
但是呼叫 withdraw()
要先處理 modifier onlyOwner()
Tip
modifier 是 Solidity 中特有的用法,簡單來說就是執行 A 函數前要先呼叫 B 函數的功能
詳細說明可以看 WTF Solidity极简入门: 11. 构造函数和修饰器
onlyOwner()
會判斷你是不是 owner,所以還是要先成為 owner 才有辦法提款,尋找可以給 owner 賦值的地方:
22 行雖然可以讓我們變成 owner,但是首先要通過 19 行的每次只能傳入 0.001 ether,又要通過 21 行的總資產大於 owner(第 10 行可以看到 owner 有 1000 ether),太難實現,不考慮這個 function
34 行的 receive()
也有更換 owner 的功能,而且只會判斷轉進去的 ether 大於 0 和發送者的資產大於 0 而已
這樣我們就可以成功取代 owner,開始實作攻擊合約
contribute()
先轉一點錢進去,讓 35 行的判斷會通過receive()
,得到 owner 資格withdraw()
,順利取得所有資產