Skip to content

Ethereum的合约ABI拓展

owen05 edited this page Jan 19, 2018 · 3 revisions

ABI是Ethereum的一种合约间调用时或消息发送时的一个消息格式。来定义操作函数签名,参数编码,返回结果编码等。

JSON定义

合约ABI的JSON是由函数(function)以及事件(event)的描述数组组成,函数的JSON描述对象包括如下字段:

其中type默认缺省“function”,构造函数以及回调函数没有name以及outputs,回调函数同时没有inputs,并且不能向payable为false的函数发送ether,否则会抛出异常。

事件的JSON描述对象包括如下字段:

事件(event)是Ethereum提供的一种日志基础设施以及是合约与前端UI交互的纽带。其有三种主要的用途:

1.为sendTransaction会改变合约状态(需要Ethereum挖矿)的方法,提供向前端UI返回参数的功能
2.异步向前端UI触发数据变化事件
3.廉价的sotrage存储机制

其中event可以定义带有indexed定义的参数(最多定义三个),如event Transfer(address indexed from, address indexed to, uint256 value)这样,前端可以仅仅监控特定from,特定to的事件变化。

事件相关的扩展阅读:

https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e

http://me.tryblockchain.org/blockchain-solidity-event.html

ABI的JSON定义参考阅读:

https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#json

ABI的函数调用

直接使用ABI的二进制接口,是对智能合约函数调用的底层实现,如下为eth_sendTransaction截图:

参考阅读

https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction

其中data,如果是对函数调用,即是对函数签名以及参数编码的二进制字段。

一个函数调用data的前四个字节数据指定了要调用的函数签名。计算方式是使用函数签名的keccak256(即sha3)的哈希,并取4个字节。写法bytes4(keccak256("foo()"))需要注意的是,如果有多个参数使用,隔开,要去掉表达式中的所有空格。

由于前面的函数签名使用了四个字节,参数的数据将从第五个字节开始。参数的编码方式与返回值,事件的编码方式一致。对于参数的编码,区分了固定大小类型以及动态类型:

bytes
string
T[] 某个类型的不定长数组
T[k] 某个类型的定长数组

所有其他类型为固定大小类型,固定大小类型的参数在原位置编码数据,动态类型编码的数据则独立于当前位置,存储在其它地方。

具体编码方式参考阅读

https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#argument-encoding

ABI的函数调用举例(参数包括固定大小类型&&动态类型),参考阅读

https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#examples

最后,对于Solidity或是Web3.js的函数调用都是遵守ABI之上实现的,对于开发者来说使用封装好的方式会更加简单友好。