如何将库和合同链接到一个文件中?

Ara*_*aki 2 solidity

我正在用安全帽编写智能合约,并面临类似的错误missing links for the following libraries

我想我应该做点什么sample-nft-test.js,但我不知道该怎么做。

有谁知道如何解决这个问题?

% bin/npm-install
% bin/test
Run Code Online (Sandbox Code Playgroud)
  SampleNft
    1) "before each" hook for "should be able to return token name by token id"


  0 passing (2s)
  1 failing

  1) SampleNft
       "before each" hook for "should be able to return token name by token id":
     NomicLabsHardhatPluginError: The contract SampleNft is missing links for the following libraries:
* contracts/SampleNft.sol:TokenTrait

Learn more about linking contracts at https://hardhat.org/plugins/nomiclabs-hardhat-ethers.html#library-linking

      at collectLibrariesAndLink (node_modules/@nomiclabs/hardhat-ethers/src/internal/helpers.ts:258:11)
      at getContractFactoryFromArtifact (node_modules/@nomiclabs/hardhat-ethers/src/internal/helpers.ts:149:32)
      at getContractFactory (node_modules/@nomiclabs/hardhat-ethers/src/internal/helpers.ts:93:12)
      at Context.<anonymous> (test/sample-nft-test.js:13:29)
Run Code Online (Sandbox Code Playgroud)

重现错误的源代码

样本-nft-test.js

const {
  expect,
} = require("chai");

const {
  ethers,
} = require("hardhat");

describe("SampleNft", () => {
  beforeEach(async () => {
    signers = await ethers.getSigners();

    const contractFactory = await ethers.getContractFactory("SampleNft", {
      signer: signers[0],
    });

    contract = await contractFactory.deploy();
  });

  it("should be able to return token name by token id", async () => {
    await contract.deployed();

    await contract.getName();
  });
});
Run Code Online (Sandbox Code Playgroud)

样品Nft.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

struct Token {
    string name;
}

library TokenTrait {
    function getName(Token memory token) external pure returns (string memory) {
        return token.name;
    }
}

contract SampleNft {
    using TokenTrait for Token;

    uint tokenId;

    mapping(uint => Token) private _tokenIdTokenMap;

    constructor() {
        tokenId = 0;
    }

    function mint() external {
        Token memory token = Token("First Token");

        _tokenIdTokenMap[tokenId] = token;
    }

    function getName() external view returns (string memory) {
        Token memory token = _tokenIdTokenMap[tokenId];

        return token.getName();
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

library TokenTrait {
    function getName(Token memory token) external pure returns (string memory) {
        return token.name;
    }
}
Run Code Online (Sandbox Code Playgroud)

您将函数的可见性设置为external。在这种情况下,您必须部署该库,然后需要在合同部署中指定该库的链接。解决问题的方法是使函数可见internal


Jiu*_*ong 5

部署合约时需要添加库链接。beforeEach部分请替换为以下代码

  beforeEach(async () => {
    signers = await ethers.getSigners();

    const Lib = await ethers.getContractFactory("TokenTrait");
    const lib = await Lib.deploy();
    await lib.deployed();

    const contractFactory = await ethers.getContractFactory("SampleNft", {
      signer: signers[0],
      libraries: {
        TokenTrait: lib.address,
      },
    });

    contract = await contractFactory.deploy();
  });
Run Code Online (Sandbox Code Playgroud)