ABI全稱Application Binary Interface, 是調用智能合約函數以及合約之間函數調用的消息編碼格式定義,也可以理解為智能合約函數調用的接口說明. 類似Webservice裏的SOAP協議壹樣;也就是定義操作函數簽名,參數編碼,返回結果編碼等。
使用ABI協議時必須要求在編譯時知道類型,即強類型相關.
當壹個智能合約編譯出來後, 他的abi接口定義就確定了. 比如下面的智能合約:
生成的字節碼:
生成的abi定義:
可以看出, 生成abi包含了2個定義: 函數 lotus , 事件 Log_lotus , 各個字段含義見上. 根據該abi定義,就可以生成調用該智能合約函數的abi格式的數據了.
格式簡單的可以表示為: 函數選擇器+參數編碼
壹個函數調用的前四個字節數據指定了要調用的函數簽名。計算方式是使用函數簽名的 keccak256 的哈希,取4個字節。
函數名如果有多個參數使用,隔開,要去掉表達式中的所有空格。在geth客戶端,通過命令可以得到hash:
由於前面的函數簽名使用了四個字節,參數的數據將從第五個字節開始。
根據參數類型,編碼規則有所區別:
除了bytes,和string, 其他類型的數據不足32字節長度的需要加0補足32字節. 動態長度的編碼在例子中介紹.
函數: function baz(uint32 x, bool y) :
調用: baz(69, true)
生成的數據如下:
返回結果是壹個bool值,在這裏,返回的是false:
函數: f(uint,uint32[],bytes10,bytes)
調用: (0x123, [0x456, 0x789], "1234567890", "Hello, world!")
函數選擇器: bytes4(sha3("f(uint256,uint32[],bytes10,bytes)"))
對於 固定大小的類型 值 uint256 和 bytes10 ,直接編碼值。
對於 動態內容類型 值 uint32[] 和 bytes ,我們先 編碼偏移值 ,偏移值是整個值編碼的開始到真正存這個數據的偏移值(這裏不計算頭四個用於表示函數簽名的字節)。
所以參數編碼數據依次為:
尾部部分的第壹個動態參數, [0x456, 0x789] 編碼拆解如下:
最後我們來看看第二個動態參數的的編碼, Hello, world! 。
所以最終結果是: