跳至内容
0%

什么是智能合约的 ABI?

Alchemy team headshot

作者 Alchemy

发布于 2022年3月9日1 分钟阅读

智能合约的应用二进制接口(ABI)使合约能够与外部应用程序及其他智能合约进行通信和交互。从外部来源接收数据,对于完成应用程序和用户的目标至关重要。

在传统 Web 开发中,应用程序与服务器之间通过 API(应用程序接口)进行数据交流。服务器作为集中化的信息来源,按请求向应用程序提供数据。

在区块链上,不存在这种数据的集中化。节点本质上充当服务器的角色,智能合约则是链上"托管"的函数。链外的应用程序(以及其他智能合约)需要一种方式来与链上的智能合约通信。这正是 ABI 发挥作用的地方。

为什么需要 ABI?

在详细介绍 ABI 是什么之前,先了解一下我们为什么需要它。

智能合约是 EVM(以太坊虚拟机) 的核心应用。智能合约的作用是在满足合约中定义的特定条件时执行交易。这些条件可以是链上或链下的事件。智能合约使用 Solidity 等高级语言编写,但它们以二进制格式的可执行字节码形式存储在 EVM 上。

智能合约代码以可执行字节码形式存储在 EVM 上的示意图
EVM 上的可执行字节码

由于这些字节码并非人类可读,需要经过解释才能理解。ABI 使编写智能合约的人能够在用 Javascript 等高级语言编写的 Web 应用程序与 EVM 所理解的字节码之间进行通信。

什么是 ABI?

与其 Web2 领域的表亲 API 类似,ABI 充当函数选择器的角色,定义了智能合约中可被调用执行的具体方法。这些具体方法及其相关联的数据类型被列在一个生成的 JSON RPC 文件中。

ABI 作为智能合约方法函数选择器的示意图
ABI 函数选择器

与 API 不同,我们不能直接以 JSON 格式向智能合约发送请求并期待响应,因为合约只能以字节码进行通信。为了将其转换为 EVM 能理解的内容,这些信息需要通过 ABI 编码进行编码。这些编码包括函数签名和变量声明,使 EVM 能够准确知道要在智能合约中执行哪个函数。

ABI 编码将函数调用转换为 EVM 字节码的示例
ABI 编码

响应结果同样以字节码形式返回,因此在被 Web 应用程序处理之前也需要经过解释。使用字节码作为响应的优势在于,我们可以预期调用合约函数后会返回某种特定的结构。

如何使用 ABI?

生成

如果你使用 Hardhat/Truffle 之类的工具,或 Remix 之类的 IDE,合约 ABI 会自动为你生成。你也可以通过使用 Solidity Compiler NPM 包 手动创建 ABI。安装该包后,可以在终端中运行 'solcjs contractname.sol --abi' 命令。如果执行成功,将生成一个 .abi 文件。

现在你已经有了一个生成的 ABI,我们来看看这个文件中的一些要素:

生成的智能合约 ABI JSON 文件示例
生成的合约 ABI

执行

由于 ABI 承担着 EVM 字节码与网站 Javascript 之间解释器的角色,因此在你想要执行智能合约的任何函数时都需要用到它。除了 ABI 之外,还需要合约在区块链上的地址。下面是一段简短的 Javascript 代码,展示了具体的操作方式:

使用 ABI 和地址执行合约函数的 JavaScript 代码片段
执行 ABI

如果你想查找一个已部署合约的 ABI,可以通过在 Etherscan 上搜索该合约的地址来找到。例如这个例子

Etherscan 合约页面展示已部署合约的 ABI
已部署合约的 ABI

编码

由于所有通信都以字节码进行,很难指望开发者自己去编码这些消息。幸运的是,像 Remix 这样常用的编译器也可以为你处理编码。这些编码遵循特定的模式,因此通过查阅 ABI 规范,可以更好地了解其运作方式。

前四个字节是函数签名,指明了智能合约中正在执行的函数类型。一个常见的函数标识符是 a9059cbb,它表示这是一个 ERC20 转账操作。这里有一个函数签名的数据库目录,可供进一步查阅。

ABI 函数签名哈希示例,包括 ERC20 的 transfer 选择器
ABI 函数哈希

从第五个字节开始,是参数的编码部分。响应遵循类似的结构,但不包含函数签名。

结论

ABI 常常是使用智能合约时容易被忽视的一个方面,但它在这项技术的可用性方面扮演着重要角色。通过学习 智能合约教程 进行实践,是理解这个默默工作的核心组件、并应用所学知识的好方法。

Background gradient

构建区块链应用

Alchemy 将最强大的 Web3 开发者产品和工具与资源、社区及专业支持结合在一起。