Contract-Deployment

Hardhat:錯誤:未解析的庫,但為什麼呢?

  • August 2, 2021

我正在嘗試使用 Hardhat(通過腳手架-eth)部署契約,但出現以下錯誤:

Error: Factory contains unresolved libraries. You must deploy and link the following libraries before you can deploy a new version of Factory: $c63268ab2b467de325495e38718facdea1$

有問題的合約 ( Factory.sol) 導入了三個合約,其中之一稱為庫 (Library_Token.sol)。不過,即使我先部署它,我也會收到此錯誤。

導致此錯誤的原因是什麼,如何解決?

**更新:**我看到 Truffle 具有連結庫的功能:https ://www.trufflesuite.com/docs/truffle/getting-started/running-migrations#deployer-link-library-destinations-

我認為 Hardhat 應該有類似的東西,這就是這裡需要發生的事情。因此,我猜這個問題應該改寫為“如何使用 Hardhat 將庫連結到契約”,但我想在弄清楚之前我不會知道它是否有效。

首先,讓我們再深入探討一下這個問題。

連結庫不僅僅是部署在同一生態系統中的另一個合約,它需要主動連結到使用它的合約,如上面的連結(指向這樣做的 Truffle 程式碼)所示。

更新的答案

我會為後人保留最初的答案(不知道為什麼,只是感覺是正確的做法),Hardhat(以前稱為 Buidler)此時有一個用於在部署時連結庫的實現(程式碼片段取自他們這裡的文件)。注意:這使用了ethersHardhat 外掛(見上面的連結):

const contractFactory = await this.env.ethers.getContractFactory("Example", {
 libraries: {
   ExampleLib: "0x...",
 },
});

舊答案

Buidler 目前(2020 年 7 月中旬)沒有執行此操作的本機快捷方式。GitHub上已經打開了一個問題,其中也有以下解決方法,也複製並粘貼在下面。

在解決方法之前,開發人員說應該有一種更直接和簡單的方法來連結合約,因此在使用下面的程式碼之前,可能值得驗證他們是否為此實現了一些東西。

const { ethers, config } = require("@nomiclabs/buidler");
const { readArtifact } = require("@nomiclabs/buidler/plugins");

async function main() {
 const Library = await ethers.getContractFactory("Library");
 const library = await Library.deploy();
 await library.deployed();

 const cArtifact = await readArtifact(config.paths.artifacts, "Contract");
 const linkedBytecode = linkBytecode(cArtifact, { Library: library.address });
 const Contract = await ethers.getContractFactory(
   cArtifact.abi,
   linkedBytecode
 );

 const contract = await Contract.deploy();
 await contract.deployed();

 console.log("Contract address:", contract.address);
}

function linkBytecode(artifact, libraries) {
 let bytecode = artifact.bytecode;

 for (const [fileName, fileReferences] of Object.entries(
   artifact.linkReferences
 )) {
   for (const [libName, fixups] of Object.entries(fileReferences)) {
     const addr = libraries[libName];
     if (addr === undefined) {
       continue;
     }

     for (const fixup of fixups) {
       bytecode =
         bytecode.substr(0, 2 + fixup.start * 2) +
         addr.substr(2) +
         bytecode.substr(2 + (fixup.start + fixup.length) * 2);
     }
   }
 }

 return bytecode;
}

main()
 .then(() => process.exit(0))
 .catch((error) => {
   console.error(error);
   process.exit(1);
 });

如果我對程式碼的理解是正確的,你很可能會在裡面使用這個/scripts/deploy.js,它應該包含在你的項目中部署合約的腳本。

引用自:https://ethereum.stackexchange.com/questions/85061