Hardhat:錯誤:未解析的庫,但為什麼呢?
我正在嘗試使用 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)此時有一個用於在部署時連結庫的實現(程式碼片段取自他們這裡的文件)。注意:這使用了
ethers
Hardhat 外掛(見上面的連結):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
,它應該包含在你的項目中部署合約的腳本。