最近在对接ETH TOKEN合约的时候,需要做我们相应的自动脚本调用,里面涉及到一个很有意思的概念叫ABI。
这个ABI不止ETH上有,很多三方追求高效率的调用也有相应的使用场景,例如Thrift(斐哥推荐,Facebook开发Apache软件基金开源)。多了解为以后技术的一个储备做基础。
ABI故名思意,应用程序二进制接口。看起来效率就很高的样子。对于以太坊来说,ABI实现更多的是多点对多点的调用。
我们要理解一个合约是怎么被执行的。
合约其实相当于一段程序代码,ETH合约以solidity为语言基础,规范了合约的语法与调用逻辑。
我们上传一份合约事实上是上传了一份被编译好的程序到以太坊网络的区块上。这份代码以静态数据的形式保存在P2P的区中心化网络中。
举个token转币的例子:
例如:
eth_sendTransaction
params: [{
“from”: “0x1111”,
“to”: “0xdee35d7ee9e60b6db6446114367ac52d09d3dc50”,
“gas”: “0x76c0”, // 30400,
“gasPrice”: “0x9184e72a000”, // 10000000000000
“value”: “0x0”, // 2441406250
“data”: “0xa9059cbb000000000000000000000000629e80e27c2d3a5000d125d97a78550cf02950830000000000000000000000000000000000000000000069e10de76676d0800000”
}]
调用上面伪代码,我们可以从地址0x1111发起调用地址0xdee35d7ee9e60b6db6446114367ac52d09d3dc50的合约,调用内容为:0xa9059cbb000000000000000000000000629e80e27c2d3a5000d125d97a78550cf02950830000000000000000000000000000000000000000000069e10de76676d0800000
目前不需要管调用内容是啥, 你只管是调用了这个合约的某些东西就行了。有兴趣可以查看这个合约的代码:
https://etherscan.io/address/0xdee35d7ee9e60b6db6446114367ac52d09d3dc50#code
当我们要调用一份合约的接口的时候,我们事实上是我们先找到这份合约地址0xdee35d7ee9e60b6db6446114367ac52d09d3dc50,这个地址上有个“程序”,当你发起一份transaction的时候,如果手续费足够调用这份合约,挖到下一个区块的矿工会根据你的起调内容信息来执行这份合约的代码。
起调内容是根据合约接口(Contract Interface)来定义的,每份合约应该都有自己的Interface,简单查看方式就是将代码贴到下面地址然后进行查看interface栏目:
https://ethereum.github.io/browser-solidity
可以发现,我们上面那份合约代码生存的interface是这样的:
[
…省略…
{“constant”:false,”inputs”:[{“name”:”dst”,”type”:”address”},{“name”:”wad”,”type”:”uint256″}],”name”:”transfer”,”outputs”:[{“name”:””,”type”:”bool”}],”payable”:false,”type”:”function”},
…省略…
]
我们只看transfer这行,“transfer”是token erc 2.0(https://github.com/ethereum/EIPs/issues/20)的标准交易接口,意思是将一个你地址上的token币转多少到另一个地址。
ABI调用接口其实就是函数与参数的加密编码,
transfer这个函数接受两个参数,一个是地址,一个是数量。
我们假定地址是:0xdee35d7ee9e60b6db6446114367ac52d09d3dc50
数量是:500000000000000000000000
那么我们得到的对应调用编码是:
0xa9059cbb: 函数ID.transfer的ASCII Keccak hash 的前4 bytes
0000000000000000000000003329e13d57b742ecfab680c0b83d5e8627fca803:地址的16进制编码
0000000000000000000000000000000000000000000069e10de76676d0800000:数量的16进制编码
合起来:
0xa9059cbb0000000000000000000000003329e13d57b742ecfab680c0b83d5e8627fca8030000000000000000000000000000000000000000000069e10de76676d0800000
那么,这段就是调用了tranfer函数,向地址0xdee35d7ee9e60b6db6446114367ac52d09d3dc50,转500000000000000000000000个token币。
ABI具体的生成原理:
https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
建议实践方式:
1.使用别人的源码,例如以太坊源码的ABI相关源码。
2.调用别人三方库,GITHUB上有不少
不建议新手自己去实现,如果实现了GITHUB上没有的版本,请开源供大家使用,嘻嘻。