Solidity極簡入門|第二十九講:函數選擇器Selector

律动

我最近在重新學 solidity,鞏固一下細節,也寫一個「Solidity 極簡入門」,供小白們使用(程式設計大佬可以另找教程),每周更新 1-3 講。

所有代碼和教程開源在 github:github.com/AmazingAng/WTFSolidity

selector

當我們調用智慧合約的函數時,發送的位元組碼的前4個字節是 selector(函數選擇器)。 這一講,我們將介紹 selector 是什麼,以及如何使用。

msg.data

msg.data 是 solidity 中的一個全域變數,值為完整的 calldata(調用函數的位元組碼)。

在下面的代碼中,我們可以通過Log事件來輸出調用mint函數的 calldata:

當參數為 0x2c44b726ADF1963cA47Af88B284C06f30380fC78 時,輸出的 calldata 為

這段很亂的位元組碼可以分成兩部分:

其實 calldata 就是告訴智慧合約,我要調用哪個函數,以及參數是什麼。

函數簽名和 selector

selector 定義為函數簽名的哈希的前 4 個字節,那麼函數簽名是什麼?

其實在第 21 講中,我們簡單介紹了函數簽名,為“函數名(逗號分隔的參數類型)”。 舉個例子,上面代碼中mint的函數簽名為“mint(address)”。 在智慧合約中,不同的函數有不同的函數簽名,因此我們可以通過函數簽名來確定要調用哪個函數。

注意,在函數簽名中,uint 和 int 要寫為 uint256 和 int256。

我們寫一個函數,來驗證mint函數的 selector 是否為 0x6a627842。 大家可以運行下面的函數,看看結果。

使用 selector

我們可以利用 selector 來調用目標函數。 例如我想調用 mint 函數,我只需要利用 abi.encodeWithSelector 將 mint 函數的 selector 和參數打包編碼,傳給 call 函數:

在日誌中,我們可以看到mint函數被成功調用,並輸出Log事件。

總結

這一講,我們介紹了什麼是函數選擇器(selector),它和 msg.data、函數簽名的關係,以及如何使用它調用目標函數。

查看原文
免責聲明:本頁面資訊可能來自第三方,不代表 Gate 的觀點或意見。頁面顯示的內容僅供參考,不構成任何財務、投資或法律建議。Gate 對資訊的準確性、完整性不作保證,對因使用本資訊而產生的任何損失不承擔責任。虛擬資產投資屬高風險行為,價格波動劇烈,您可能損失全部投資本金。請充分了解相關風險,並根據自身財務狀況和風險承受能力謹慎決策。具體內容詳見聲明
留言
0/400
暫無留言