1. Fallback

本節作為第一關,所需要的基礎知識還是挺多的。不得不說,這個Ethernaut的內容本來就不是設計給初學Solidity的新手的。如果對Solidity及智能合約的認識不足,建議還是先看完Solidity的官方文檔再來挑戰吧。

先看通關要求:

  1. you claim ownership of the contract
  2. you reduce its balance to 0

再看合約代碼,明顯看到最下方有一段跟其他function不一樣的代碼,前方沒有function關鍵字,而是以fallback()開頭。這裏就來到第一個知識點,觀看fallback function的官方文檔:

The fallback function is executed on a call to the contract if none of the other functions match the given function signature, or if no data was supplied at all and there is no receive Ether function.

也就是說,如果我們呼叫一個合約時不提供呼叫的函数,又或是函数名稱不正稱,就會直接運行這個fallback function。觀看fallback function裏的代碼:

fallback() external payable {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }

只要達成msg.value > 0 及contributions[msg.sender] > 0 兩個條件,msg.sender 就會被設定成owner,msg 是solidity的特殊字,觀看官方文檔:

  • msg.value (uint): number of wei sent with the message
  • msg.sender (address): sender of the message (current call)

這msg.value是可以在呼叫合約時控制的,而另一條件則需要以msg.value少於0.001 ether 呼叫contribute函数,可令contributions[msg.sender]大於零。打開Console(F12),輸入:

> contract.contribute({value: toWei("0.00001")})

由於1 ether= 10^18 wei,這裏使用了預設的toWei函数把0.00001 ether 轉換成wei單位後傳送。

待交易確認後,傳送以太幣呼叫fallback:

> contract.sendTransaction({value: toWei("0.00001")})

此時owner已經轉為msg.sender,即呼叫者錢包地址了,呼叫withdraw函数把balance歸零:

> contract.withdraw()

最後按提交,本關完成。

發表留言

%d 位部落客按了讚: