库合约 library

本章讲解在 Solidity 中,库合约 library 的定义和使用方法。

推特@Hita_DAO    DiscordHitaDAO

Solidity 中的库合约 library 是一种特殊的合约,它能够提高代码的重用性和可维护性。

库合约,也称为库函数、函数库,它是一个函数合集,里面包含了一些常用函数,并把它们封装在一个单独的文件中,可以被其它合约引用。

库函数在其它编程语言中也普遍存在,作用也基本相同,都是为了提高代码的可复用性。

1. 库合约的好处

Solidity 中使用库合约有两个用处:

1.1 代码重用和模块化

库合约允许你将一组相关的功能封装到一个地方,并在多个合约中重复使用。这种模块化设计提高了代码的可复用性、可维护性和可读性。

1.2 减少部署成本和 gas 消耗

库合约的字节码在合约中保持一份,这样可以在使用它的代码中共享,因此不需要每次都在链上部署相同的代码。这可以减少部署成本,也有助于减少 gas 消耗。

2. 库合约的定义

定义一个库合约与定义普通合约类似,但需要使用 library 关键字:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library Maths {
  function add(uint a, uint b) external pure returns (uint) {
    return a + b;
  }
}

在上面的示例中,Maths 是一个库合约,它里面包含了一个简单的加法函数。

我们把上面的合约保存在一个单独文件 Maths.sol 中。

2. 库合约的定义使用

一个合约要使用库合约中的函数,首先需要将库合约文件,通过 import 关键字引入到合约中。

import "./Maths.sol";

然后就可以使用库合约中的函数了。使用方法有两种:

2.1 通过库合约名称调用

第一种方法是使用库合约名称。比如,使用 Maths 库合约的函数 add,计算 1 + 2:

function calculate() public pure returns(uint){
  return Maths.add(1, 2);
}

前面是库合约名称 Maths,后面跟着一个点,然后跟着函数名称 add

2.2 通过 using for 指令

第二种方法是使用 using for 指令。比如,使用这样一条指令:

using A for B;

这条指令表示,将库合约 A 中的所有函数附加到数据类型 B 上。这条指令之后,库库合约 A 中的函数会自动成为 B 类型变量的成员,可以直接调用。

下面是一个使用 using for 指令的智能合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./Maths.sol";

contract UsingMaths {
  using Maths for uint;

  function calculate(uint x, uint y) external pure returns (uint) {
    return x.add(y);
  }
}

其中,x.add(y) 就等同于 add(x, y)x.add(y)  在调用的时候,x 变量会被当作第一个参数传递给函数。

我们把这个合约复制到 Remix 上,对其进行编译和部署,并调用 calculate 函数:

3. 库合约的编译

库合约在部署时,并没有自己的单独地址,它的字节码被包含在使用该库的合约中,而不是在链上以独立的合约地址进行部署。

当你使用 Solidity 中的库合约时,库合约的代码会被复制并嵌入到使用它的合约中。这样,使用库的合约在部署时会包含库合约的代码,并且在合约中会有一份对应合约函数的跳转表。这种方式可以节省 gas 费用并提高代码的重用性。

当你调用库函数时,实际上是在使用库合约的合约内部执行了库函数的代码,而不是通过在链上调用一个独立的合约地址。