什麼是 ABI,為什麼需要它與合約互動?
許多地方都引用了 ABI,包括乙太坊官方網站。什麼是 ABI,為什麼需要使用?
ABI 代表應用程序二進制介面。
一般來說,ABI 是兩個程序模組之間的介面,其中一個模組通常處於機器程式碼級別。該介面是將數據編碼/解碼到機器程式碼中/從機器程式碼中取出的事實上的方法。
在乙太坊中,這基本上是您如何編碼 EVM 的 Solidity 合約呼叫,以及如何從交易中讀取數據。
ABI(應用程序二進制介面)基本上是您在合約中呼叫函式並取回數據的方式。
ABI 確定諸如如何呼叫函式以及應以何種二進制格式資訊從一個程序組件傳遞到下一個程序組件等細節……
乙太坊智能合約是部署在乙太坊區塊鏈上的字節碼。契約中可能有幾個功能。ABI 是必需的,以便您可以指定呼叫合約中的哪個函式,並保證該函式將以您期望的格式返回數據。
來自乙太坊的 ABI 規範,一個例子:
contract Foo { function bar(real[2] xy) {} function baz(uint32 x, bool y) returns (bool r) { r = x > 32 || y; } function sam(bytes name, bool z, uint[] data) {} }
如果我們想用參數 69 和 true 呼叫 baz,我們將總共傳遞 68 個字節,可以分解為:
0xcdcd77c0:方法 ID。這是作為簽名 baz(uint32,bool) 的 ASCII 形式的 Keccak-256 散列的前 4 個字節導出的。0x0000000000000000000000000000000000000000000000000000000000000045:第一個參數,填充為32 UINT32值69字節0x0000000000000000000000000000000000000000000000000000000000000001:第二個參數 - 布爾真,填充到32字節
這 68 個字節是在
data
交易欄位中指定的:關於它的安全說明是here。(總而言之,要小心你在 data 欄位中輸入的內容,因為在將其傳遞給呼叫合約時,它可能會產生意想不到的、可能是惡意的副作用。)為了避免在派生方法 ID 時出現常見的陷阱,必須使用規範類型,例如,
uint256
而不是uint
.這是計算上述方法 ID 的 Solidity 範例
sam
:bytes4(keccak256("sam(bytes,bool,uint256[])")
使用 web3.js 等更高級的庫可以抽像出大部分這些細節,但是JSON 格式的 ABI仍然需要提供給 web3.js。
注意:ABI 是一種抽象,不屬於乙太坊核心協議的一部分。任何人都可以為他們的合約定義自己的 ABI(起始範例),並且此類合約的任何呼叫者都必須遵守該 ABI 才能獲得有意義的結果。但是,對於所有開發人員來說,使用都符合上述 ABI 的目前編譯器(例如 Solidity)和庫(例如 web3.js、ethers.js)會更簡單。