ABI 是什么

ABI 全称是 Application Binary Interface,翻译过来就是:应用程序二进制接口,简单来说就是以太坊的调用合约时的接口。

调用合约函数发生了什么

从外部施加给以太坊的行为都称之为向以太坊网络提交了一个交易, 调用合约函数其实是向合约地址(账户)提交了一个交易,这个交易有一个附加数据,这个附加的数据就是ABI的编码数据。

演示调用函数

以下面以个最简单的合约为例,我们看看用参数 1 调用set(uint x),这个交易附带的数据是什么。

pragma solidity ^0.4.0;

contract SimpleStorage {
    
    uint storedData;
    
    function set(uint x) public {
        storedData = x;
    }

    function get() public constant returns (uint) {
        return storedData;
    }
}

然后我们打开etherscan查看交易详情数据, 可以看到其附加的ABI编码数据:

0x60fe47b10000000000000000000000000000000000000000000000000000000000000001

ABI 编码分析

我把上面交易的附加数据拷贝出来分析一下,这个数据可以分成两个子部分: - 函数选择器(4字节)
0x60fe47b1 - 第一个参数(32字节)

    
函数选择器值实际是对函数签名字符串进行`sha3(keccak256)`哈希运算之后,取前4个字节,用代码表示就是:

```js
    bytes4(sha3("set(uint256)")) == 0x60fe47b1

参数部分则是使用对应的16进制数。

ABI 编码函数

那么怎么获得函数对应的ABI 数据呢, 有两种方法:

Solidity ABI 编码函数

一个是 solidity 提供了ABI的相关API, 用来直接得到ABI编码信息,这些函数有:

- abi.encode(...) returns (bytes):计算参数的ABI编码。
- abi.encodePacked(...) returns (bytes):计算参数的紧密打包编码
- abi. encodeWithSelector(bytes4 selector, ...) returns (bytes): 计算函数选择器和参数的ABI编码
- abi.encodeWithSignature(string signature, ...) returns (bytes): 等价于* abi.encodeWithSelector(bytes4(keccak256(signature), ...)

原文地址:如何理解以太坊ABI - 应用程序二进制接口 - Tiny熊 - 博客园 (cnblogs.com)