智能合約開發
介面
介面是「如何與某合約對話」的純粹描述:一串沒有任何程式碼支撐的函數簽章。它是合約對合約版本的插頭形狀——它告訴你的程式碼有哪些函數存在、各自接收與回傳什麼,讓你無需匯入完整原始碼就能呼叫一個已部署的合約。我們熟悉的 IERC20 就是一個介面。
以 interface 關鍵字宣告,它只能包含外部函數簽章,外加事件、自訂錯誤、結構體與列舉。它不能有實作的函數、建構子或狀態變數,而且它所有的函數都隱含為 virtual 與 external。介面定義了一個型別,你可以把一個地址轉型成它:寫 IERC20(token).transfer(to, amount) 是告訴編譯器以 transfer 的選擇器 ABI 編碼一個呼叫並送往該地址。介面可以繼承其他介面,但絕不能繼承一般合約。
透過介面呼叫只是一次以 4 位元組函數選擇器分派的普通外部訊息呼叫——介面是編譯期的便利,而非執行期的保證。若目標地址其實並未實作那個選擇器,呼叫可能回滾,或觸及目標的 fallback 函數而默默做出意料之外的事。編譯器直接從合約的介面推導其 ABI,這就是為何介面是「用獨立部署的合約組合協議」的通用語言。
interface IERC20 {
function transfer(address to, uint256 amount) external returns (bool);
function balanceOf(address who) external view returns (uint256);
}
IERC20(token).transfer(to, amount);一個可供呼叫的形狀,不含任何實作。
介面是你對編譯器許下的承諾,而非目標會遵守的承諾。把任意地址轉型成 IERC20 並不能驗證它真的是代幣——呼叫可能觸及 fallback 而悄悄成功。
另见