Solidity

fallback 函式的函式選擇器是什麼?

  • March 8, 2022

函式選擇器是函式簽名的 keccak256 散列的前四個字節。回退函式的簽名是什麼?它既沒有名稱也沒有任何輸入。

如果沒有真正的簽名,則必須至少有一個自定義函式選擇器(為備份函式保留一些固定的 4 個字節)。

沒有選擇器。如果合約無法辨識選擇器,或者沒有提供選擇器,則會呼叫回退函式。

如果您需要將數據傳遞給備份,您應該填寫一個虛擬選擇器值。這個問題的很多答案都沒有完全說明不需要提供選擇器。但是,被呼叫方合約將消息 calldata 的前四個字節定義為函式簽名。此外,回退實現通常假設(在某種程度上編譯器實現也是如此,即用 暗示msg.sig)在處理字節數據之前要丟棄前 4 個字節。

考慮一下如果你在沒有選擇器的情況下編碼和發送數據會發生什麼:被呼叫者合約使用 calldata 的前四個字節——msg.data比如說0x12345678...——作為函式選擇器來嘗試匹配任何現有的命名函式。如果合約未能找到匹配項,則如果存在,它將預設使用回退。此時,大多數回退邏輯將刪除前 4 個字節並將其餘數據解碼為值 ( abi.decode(bytes[4:],...<value types>))。如果回退不是您自己編寫的,請檢查實現以查看它是否刪除了前 4 個字節。

為什麼要始終包含一個虛擬選擇器?因為在沒有選擇器的情況下發送的數據可能會與合約中的一個指定函式匹配,並且最好的情況是失敗,最壞的情況是由於意外更改儲存而損失大量金錢。這種可能性大約是十億分之一,所以只有在處理一個預計會處理數百萬甚至數十億美元的大項目時才有意義。但是,這仍然是一種很好的編碼習慣。找到一個固定的虛擬選擇器值 - 任何事情都可以,例如- 並將0x00000000其添加到為備份呼叫編碼的所有數據中,並且您每次都將擁有可靠的函式選擇。

引用自:https://ethereum.stackexchange.com/questions/49996