如何理解以太坊ABI - 应用程序二进制接口

很多同学不是很明白以太坊ABI是什么,他的作用是什么,读完本文就明白了。

写在前面

阅读本文前,你应该对以太坊、智能合约有所了解,
如果你还不了解,建议你先看以太坊是什么,也可以观看我们的视频:零基础搞懂区块链深入详解以太坊智能合约语言Solidity, 可以系统全面学习理解以太坊、智能合约。

ABI 是什么

ABI 全称是 Application Binary Interface,翻译过来就是:应用程序二进制接口,简单来说就是 以太坊的调用合约时的接口说明。还不是很理解,没关系。

调用合约函数发生了什么

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

比特币的交易也可以附加数据,以太坊革命性的地方就是能把附加数据转化为都函数的执行。

因此要想和合约交互,就离不开ABI数据。

演示调用函数

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pragma solidity ^0.4.0;

contract SimpleStorage {

uint storedData;

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

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

当然第一步需要先把合约部署到以太坊网络(其实部署也是一个)上,然后用 “1” 作为参数调用set,如下图:

然后我们打开etherscan查看交易详情数据, 可以看到其附加数据如下图:

这个数据就是ABI的编码数据:

1
0x60fe47b10000000000000000000000000000000000000000000000000000000000000001

ABI 编码分析

我把上面交易的附加数据拷贝出来分析一下,这个数据可以分成两个子部分:

  • 函数选择器(4字节)
    0x60fe47b1

  • 第一个参数(32字节)
    00000000000000000000000000000000000000000000000000000000000000001

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

1
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编码函数可以在不用调用函数的情况下,获得ABI编码值,下面通过一段代码来看看这些方法的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pragma solidity ^0.4.24;

contract testABI {
uint storedData;

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

function abiEncode() public constant returns (bytes) {
abi.encode(1); // 计算1的ABI编码
return abi.encodeWithSignature("set(uint256)", 1); //计算函数set(uint256) 及参数1 的ABI 编码
}
}

大家可以运行运行下abiEncode函数,它的输出其实就是前面调用的附加数据。

Web3 ABI 编码函数

另一个web3提供相应的API,例如使用web3计算函数选择器的方式如下:

1
web3.eth.abi.encodeFunctionSignature('myMethod(uint256,string)');

其完整的文档在这里,这里不一一演示。

如果你想学习以太坊DApp开发,这门视频课程以太坊DAPP开发实战是你不错的选择。

欢迎来知识星球提问,星球内已经聚集了300多位区块链技术爱好者。
深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。

Tiny熊 wechat
微信号:深入浅出区块链技术,欢迎订阅
有收获,赞赏下