智能合約開發
應用程式二進位介面
ABI 是與合約對話的約定線路格式:它精確規範一個函數名稱與其引數如何變成 calldata 的原始位元組,以及回傳的位元組如何變回有型別的值。EVM 本身只看到位元組;ABI 就是讓錢包、函式庫或另一個合約能正確說出這些位元組的約定。
一次呼叫的 calldata 是一個 4 位元組的函數選擇器,後接 ABI 編碼的引數。選擇器是規範簽章之 keccak-256 雜湊的前四個位元組——例如 keccak256("transfer(address,uint256)") 以 0xa9059cbb 開頭,所以每次 transfer 呼叫都是這樣開頭的。引數被打包進 32 位元組的字組:靜態大小的型別(uint256、address、bool)就地內嵌,而動態大小的型別(bytes、string、T[])使用一個「頭」字組存放偏移量,指向一個「尾」存放長度後接資料。結構體被編碼為其欄位依序排列的元組。
在二進位編碼之外還有 JSON ABI:一份機器可讀的清單,列出合約的函數、其輸入與輸出、狀態可變性與事件。各種工具(ethers.js、web3.py、viem、區塊鏈瀏覽器)讀取這份 JSON 來編碼呼叫並解碼日誌。關鍵在於 ABI 是鏈下的產物——鏈從不檢查它。若你的 ABI 與已部署的位元組碼不一致,呼叫與回傳值會被默默地誤解碼而非被拒絕,這是令人困惑的整合錯誤常見的來源。
selector = keccak256("transfer(address,uint256)")[0:4] = 0xa9059cbb
四個位元組指出函數;其餘是打包好的引數。
鏈不儲存任何 ABI。函數選擇器只是雜湊的前 4 位元組,因此兩個不同的函數可能在同一個選擇器上碰撞——這是代理與鑽石模式必須防範的事實。
又稱
另見