{"content":{"title":"什么是ABI？","body":"## 概述 \r\n\r\n在与智能合约交互时，ABI 是一个重要的组成部分。在本指南中，让我们了解智能合约的 ABI是什么。\r\n\r\n> 希望通过视频了解吗？跟随 Radek 的步伐，在 11 分钟内了解 ABI。\r\n\r\n \r\n\r\n## 什么是 ABI？\r\n\r\nABI（应用程序二进制接口）在计算机科学的背景下，是两个程序模块之间的接口，通常是在操作系统和用户程序之间。\r\n\r\nEVM（以太坊虚拟机）是以太坊网络的核心组件，智能合约是在以太坊区块链上存储并在 EVM 上执行的代码片段。用高层次语言编写的智能合约，如 [Solidity](https://docs.soliditylang.org/en/v0.8.2/) 或 [Vyper](https://vyper.readthedocs.io/en/stable/)，需要被编译为 EVM 可执行字节码；当智能合约被部署时，这段字节码被存储在区块链上，并与一个地址相关联。对于以太坊和 EVM 来说，智能合约就是这段字节码序列。为了访问用高层语言定义的函数，用户需要将名称和参数转化为字节表示，以便字节码能处理它。为了解释响应中发送的字节，用户需要转换回高层语言中定义的返回值元组。编译 EVM 的语言遵循严格的转换规则，但为了执行这些转换，必须知道与操作相关的精确名称和类型。ABI 精确地记录了这些名称和类型，以可轻松解析的格式进行文档化，使得在用户期望的方式和智能合约操作之间进行转换变得可发现和可靠。\r\n\r\n这与 API（应用程序接口）非常相似，API 是代码接口的人类可读表示。ABI 定义了与二进制合约交互所使用的方法和结构，正如 API 在较低层次上所做的。ABI 指示函数的调用者如何以 EVM 能理解的格式编码所需信息，如函数签名和变量声明，以调用字节码中的函数；这被称为 ABI 编码。ABI 编码大多是自动化的，由像 [REMIX](https://remix.ethereum.org/) 这样的编译器或与区块链交互的钱包处理。合约的 ABI 以 JSON 格式表示。关于如何编码和解码合约 ABI，有明确的规范。\r\n\r\n## 理解 ABI 的元素 \r\n\r\n合约的 ABI 的 JSON 格式由各种函数和/或事件描述组成。\r\n\r\n以下是函数 ABI 描述中存在的元素：\r\n\r\n- **type**: 定义函数的类型。它可以是以下之一，‘function’（函数），‘constructor’（构造函数），‘receive’（接收以太函数），或 'fallback'（默认函数）。\r\n- **name**: 定义函数的名称。\r\n- **inputs**: 它是一个对象数组，定义参数；每个对象都有：\r\n  - **name**: 定义参数的名称。\r\n  - **type**: 定义参数的标准类型。例如，uint256。\r\n  - **components**: 用于定义元组类型，如果达到元组类型，则表示为 type = tuple \\[元组元素的其他属性，如名称、类型在此处\\]。\r\n- **outputs**: 它是一个输出对象数组，类似于 inputs。\r\n- **stateMutability**: 定义函数的可变性。它可以是以下值之一：‘[pure](https://docs.soliditylang.org/en/develop/contracts.html#pure-functions)’（指定不读取或写入区块链状态），‘[view](https://docs.soliditylang.org/en/develop/contracts.html#view-functions)’（指定在读取区块链状态时，不进行修改），‘nonpayable’（这是默认可变性，在编写函数时无需提及，这意味着函数不接受以太，因此我们可以读取和写入区块链状态），‘payable’（提到此意思为函数接受以太并可以读取/写入区块链状态）。\r\n\r\n> **注意**: 构造函数和回退函数的 ABI 的名称和输出字段为空；即使输入字段对回退函数也是空的。\r\n\r\n以下是事件 ABI 描述中存在的元素：\r\n\r\n- **type**: 这里，它总是‘event’。\r\n- **name**: 定义事件的名称。\r\n- **inputs**: 它是一个对象数组，定义参数；每个对象都有：\r\n  - **name**: 定义参数的名称。\r\n  - **type**: 定义参数的标准类型。例如，uint256。\r\n  - **components**: 用于定义元组类型，如果达到元组类型，则表示为 type = tuple \\[元组元素的其他属性，如名称、类型在此处\\]。\r\n  - **indexed**: 如果该字段是日志主题的一部分则是‘true’，如果它是日志的一个数据段则是‘false’。\r\n- **anonymous**: 如果事件在合约代码中声明为匿名，则该字段为真。\r\n\r\n## 如何获取/生成 ABI？ \r\n\r\n最常见的方法之一是在智能合约编译后，通过 [Ethereum REMIX IDE](https://remix.ethereum.org/) 的编译标签下的 ABI 按钮复制 ABI。\r\n\r\n![](https://img.learnblockchain.cn/2025/02/25/0-79e38a4b8d93d8c7e58ef3667a53f693.png)\r\n\r\n另一种方法是使用提供 [Solidity Compiler](https://github.com/ethereum/solidity) 的 JavaScript 绑定的 [solc](https://www.npmjs.com/package/solc) 编译和生成 ABI。要安装 solc，我们需要有 npm，这与 [node.js](https://nodejs.org/en/) 一起提供。检查你的系统是否安装了 node.js。\r\n\r\n``` \r\n$ node -v\r\n```\r\n\r\n简化调试的日志\r\n\r\n现在你可以访问 RPC 端点的日志，可以更有效地帮助你排查问题。如果你在 RPC 调用中遇到问题，只需检查 QuickNode 仪表板中的日志，以快速识别和解决问题。有关日志历史限制的更多信息，请查看 [我们的定价页面](https://www.quicknode.com/pricing#features)。\r\n\r\n如果未安装，可以从 [官方网站](https://nodejs.org/en/) 下载 LTS 版本的 NodeJS。\r\n\r\n现在让我们安装 solc\r\n\r\n``` \r\n$ npm install solc\r\n```\r\n\r\n我们将为以下合约 test.sol 编译并生成 ABI，该合约用于递增一个变量的值：\r\n\r\n以上代码的说明：\r\n\r\n第 1 行：指定 [SPDX 许可证](https://spdx.org/licenses/) 类型，该类型是在 Solidity ^0.6.8 后增加的；每当智能合约的源代码向公众提供时，这些许可证可以帮助解决/避免版权问题。如果你不想指定任何许可证类型，你可以使用特殊值 UNLICENSED 或简单地跳过整个注释（这不会导致错误，只会产生警告）。\r\n\r\n第 2 行：声明 Solidity 版本。\r\n\r\n第 4 行：开始我们的合约名称测试。\r\n\r\n第 6 行：声明一个名为 count 的私有变量，其类型为无符号整数，并赋值为零。\r\n\r\n第 8-10 行：声明一个公共函数 increment，当调用时，该函数将 count 的值增加 1。\r\n\r\n第 12-14 行：声明一个公共函数 getCount，该函数将以无符号整数形式返回 count 的值。\r\n\r\n现在，让我们获取上述合约的 ABI。\r\n\r\n``` \r\n$ solcjs test.sol --abi\r\n```\r\n\r\n将在同一目录中创建一个名为 test_sol_test.abi 的文件；它将具有类似以下格式的 JSON 格式的 ABI：\r\n\r\n``` \r\n[\r\n\t{\r\n\t\t\"inputs\": [],\r\n\t\t\"name\": \"getCount\",\r\n\t\t\"outputs\": [\r\n\t\t\t{\r\n\t\t\t\t\"internalType\": \"uint256\",\\\r\n\t\t\t\t\"name\": \"\",\\\r\n\t\t\t\t\"type\": \"uint256\"\\\r\n\t\t\t}\\\r\n\t\t],\\\r\n\t\t\"stateMutability\": \"view\",\\\r\n\t\t\"type\": \"function\"\\\r\n\t},\\\r\n\t{\\\r\n\t\t\"inputs\": [],\\\r\n\t\t\"name\": \"increment\",\\\r\n\t\t\"outputs\": [],\\\r\n\t\t\"stateMutability\": \"nonpayable\",\\\r\n\t\t\"type\": \"function\"\\\r\n\t}\\\r\n]\r\n```\r\n\r\n## 结论 \r\n\r\n现在你知道 ABI 是什么，了解更多 [Solidity](https://learnblockchain.cn/tags/solidity)、 [Vyper](https://learnblockchain.cn/tags/vyper) 智能合约，并创建你的智能合约。了解更多关于 [Solidity 文档中的 ABI 规范](https://docs.soliditylang.org/en/v0.8.2/abi-spec.html)。\r\n\r\n订阅我们的 [新闻通讯](https://go.quicknode.com/newsletter)，获取以太坊的更多文章和指南。如果你有任何反馈，请随时通过 [Twitter](https://twitter.com/QuickNode) 与我们联系。你可以随时与我们在 [Discord](https://discord.gg/quicknode) 社区服务器聊天，那里有一些你见过的最酷的开发人员 :)\r\n\r\n>- 原文链接： [quicknode.com/guides/eth...](https://www.quicknode.com/guides/ethereum-development/smart-contracts/what-is-an-abi)\r\n>- 登链社区 AI 助手，为大家转译优秀英文文章，如有翻译不通的地方，还请包涵～"},"author":{"user":"https://learnblockchain.cn/people/25306","address":null},"history":null,"timestamp":1740447160,"version":1}