与智能合约交互时,ABI 是必不可少的组件之一。在本文中,让我们了解智能合约的 ABI 是什么。
计算机科学背景下的 ABI(应用程序二进制接口)是两个程序模块之间的接口,通常在操作系统和用户程序之间。
EVM(以太坊虚拟机)是以太坊网络的核心组件,智能合约是存储在以太坊区块链上的代码片段,在 EVM 上执行。用Solidity或Vyper等高级语言编写的智能合约需要编译成EVM可执行字节码;部署智能合约时,此字节码存储在区块链上,并与地址相关联。对于以太坊和 EVM,智能合约就是这一系列字节码。要访问用高级语言定义的函数,用户需要将名称和参数转换为字节表示形式,以便字节码使用它。为了解释响应中发送的字节,用户需要转换回用高级语言定义的返回值元组。为 EVM 编译的语言对这些转换保持严格的约定,但为了执行这些转换,必须知道与操作相关的精确名称和类型。ABI 以准确、易于解析的格式记录了这些名称和类型,在人为的方法调用和可发现且可靠的智能合约操作之间进行转换。
它与 API(应用程序接口)非常相似,API 是代码接口的可读表示。ABI 定义了用于与二进制合约交互的方法和结构,就像 API 一样,但在较低的级别上。ABI 指示函数的调用者以 EVM 可以理解的格式对所需的信息,如函数签名和变量声明等,进行编码,以便在字节码中调用该函数;这称为 ABI 编码。ABI 编码大部分是自动化的,由REMIX等编译器或与区块链交互的钱包处理。合约 ABI 以 JSON 格式表示。关于如何编码和解码合约 ABI 有明确的规范。
合约 ABI 的 JSON 格式由各种函数和/或事件描述给出。
以下是函数的 ABI 描述中存在的元素:
type:定义函数的类型。它可以是以下之一,“function”、“constructor”、“receive”(用于接收 ether 函数)或“fallback”(用于默认函数)。
name:定义函数的名称。
inputs:它是一个定义参数的对象数组;每个对象都有:
name:定义参数的名称。
type:定义参数的规范类型。例如,uint256。
components:用于定义元组类型,如果达到一个元组类型,则表示为 type = tuple [元组元素的其他属性,如name,type]。
outputs:它是一个类似于输入的输出对象数组。
stateMutability:定义函数的可变性。它可以是以下值之一:’ pure ‘(指定不读取或写入区块链状态),’ view '(指定读取区块链状态时,但不能进行修改),‘nonpayable’(这是默认的可变性,在代码中编写函数时不需要提及,这意味着函数不接受 Ether;使用它我们可以读取和写入区块链状态),‘payable’(提到这意味着函数接受 Ether 和可以读/写区块链状态)。
注意:构造函数和 fallback 函数的 ABI 的 name 和 output 字段为空;即使是 fallback 函数的 input 字段也是空的。
以下是事件的 ABI 描述中存在的元素:
type:在这里,它总是“event”。
name:定义事件的名称。
inputs:它是一个定义参数的对象数组;每个对象都有:
name:定义参数的名称。
type:定义参数的规范类型。例如,uint256。
components:用于定义元组类型,如果达到一个元组类型,则表示为 type = tuple [元组元素的其他属性,如 name,type]。
indexed:如果该字段是日志主题的一部分,则为“true”,如果该字段是日志的数据段之一,则为“false”。
anonymous:如果事件在合约代码中被声明为匿名,则该字段为 true。
最常见的方法之一是在智能合约编译完成后 ,使用 Ethereum REMIX IDE编译选项卡下的 ABI 按钮复制 ABI。
另一种方法是使用 solc编译和生成 ABI,它为 Solidity Compiler 提供 JavaScript 绑定。要安装 solc,我们需要使用node.js附带的 npm 。检查您的系统上是否安装了 node.js。
$ node -v
如果没有安装,可以从官网下载 LTS 版本的 NodeJS 。
现在让我们安装 solc
$ npm install solc
我们将为以下合约 test.sol 编译并生成 ABI,这是一个增加变量值的合约:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
contract test {
uint256 private count = 0;
function increment() public {
count += 1;
}
function getCount() public view returns (uint256) {
return count;
}
}
上面代码的解释:
第 1 行:指定SPDX 许可类型,是 Solidity ^0.6.8 之后添加的;每当智能合约的源代码向公众开放时,这些许可证都可以帮助解决/避免版权问题。如果您不想指定任何许可类型,您可以使用特殊值 UNLICENSED 或直接跳过整个注释(不会导致错误,只是警告)。
第 2 行:声明 Solidity 版本。
第 4 行:开始我们的合约名称测试。
第 6 行:声明一个名为 count 的私有变量,类型为无符号整数,并为其赋值为零。
第 8-10 行:声明一个公共函数增量,它在调用时将 count 的值加一。
第 12-14 行:声明一个公共函数 getCount,它将以无符号整数形式返回 count 的值。
现在,让我们获取上述合约的 ABI。
$ solcjs test.sol --abi
将在同一目录中创建一个名为 test_sol_test.abi 的文件;它将具有 JSON 格式的 ABI,如下所示:
[
{
"inputs": [],
"name": "getCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "increment",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
现在,您知道 ABI 是什么,了解有关 Solidity、 Vyper 智能合约的更多信息,并创建您的智能合约。从 Solidity 文档了解有关ABI 规范的更多信息。
原文链接:https://www.quicknode.com/guides/solidity/what-is-an-abi