什么是合约ABI?

概述

与智能合约交互时,ABI 是必不可少的组件之一。在本文中,让我们了解智能合约的 ABI 是什么。

什么是合约ABI?_第1张图片

什么是 ABI?

计算机科学背景下的 ABI(应用程序二进制接口)是两个程序模块之间的接口,通常在操作系统和用户程序之间。

EVM(以太坊虚拟机)是以太坊网络的核心组件,智能合约是存储在以太坊区块链上的代码片段,在 EVM 上执行。用Solidity或Vyper等高级语言编写的智能合约需要编译成EVM可执行字节码;部署智能合约时,此字节码存储在区块链上,并与地址相关联。对于以太坊和 EVM,智能合约就是这一系列字节码。要访问用高级语言定义的函数,用户需要将名称和参数转换为字节表示形式,以便字节码使用它。为了解释响应中发送的字节,用户需要转换回用高级语言定义的返回值元组。为 EVM 编译的语言对这些转换保持严格的约定,但为了执行这些转换,必须知道与操作相关的精确名称和类型。ABI 以准确、易于解析的格式记录了这些名称和类型,在人为的方法调用和可发现且可靠的智能合约操作之间进行转换。

它与 API(应用程序接口)非常相似,API 是代码接口的可读表示。ABI 定义了用于与二进制合约交互的方法和结构,就像 API 一样,但在较低的级别上。ABI 指示函数的调用者以 EVM 可以理解的格式对所需的信息,如函数签名和变量声明等,进行编码,以便在字节码中调用该函数;这称为 ABI 编码。ABI 编码大部分是自动化的,由REMIX等编译器或与区块链交互的钱包处理。合约 ABI 以 JSON 格式表示。关于如何编码和解码合约 ABI 有明确的规范。

了解 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。

如何获取/生成 ABI?

最常见的方法之一是在智能合约编译完成后 ,使用 Ethereum REMIX IDE编译选项卡下的 ABI 按钮复制 ABI。

什么是合约ABI?_第2张图片

另一种方法是使用 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

你可能感兴趣的:(NFT系列)