You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何预部署LensHub依赖的带构造参数的合约并保持原合约完整性?

部署LensHub合约的解决方案(保留原合约完整性)

问题背景

我需要部署LensHub智能合约,但它依赖的ERC721Enumerable相关合约需要构造函数参数初始化。LensHub只能在部署后调用initialize完成初始化,不预部署依赖合约的话部署会失败。我不想通过继承IERC721Enumerable并在构造函数初始化的方式解决,希望完全保留原合约结构用于测试。


可行解决方案

方案1:预部署最小化Mock合约(推荐)

直接预部署一个符合IERC721Enumerable接口的Mock合约,不需要完整功能,只要满足构造函数参数要求且接口匹配即可。这样既满足LensHub构造函数的参数校验,又不会改动原合约逻辑。

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

import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";

contract MockERC721Enumerable is IERC721Enumerable {
    string public name;
    string public symbol;

    constructor(string memory name_, string memory symbol_) {
        name = name_;
        symbol = symbol_;
    }

    // 空实现满足接口要求,测试时按需扩展
    function totalSupply() external pure returns (uint256) { return 0; }
    function tokenOfOwnerByIndex(address, uint256) external pure returns (uint256) { revert("Mock: Not implemented"); }
    function tokenByIndex(uint256) external pure returns (uint256) { revert("Mock: Not implemented"); }

    // 实现IERC721基础接口(因IERC721Enumerable继承自它)
    function balanceOf(address) external pure returns (uint256) { return 0; }
    function ownerOf(uint256) external pure returns (address) { revert("Mock: Not implemented"); }
    function safeTransferFrom(address, address, uint256) external pure { revert("Mock: Not implemented"); }
    function transferFrom(address, address, uint256) external pure { revert("Mock: Not implemented"); }
    function approve(address, uint256) external pure { revert("Mock: Not implemented"); }
    function getApproved(uint256) external pure returns (address) { revert("Mock: Not implemented"); }
    function setApprovalForAll(address, bool) external pure { revert("Mock: Not implemented"); }
    function isApprovedForAll(address, address) external pure returns (bool) { return false; }
    function safeTransferFrom(address, address, uint256, bytes calldata) external pure { revert("Mock: Not implemented"); }
    function name() external view returns (string memory) { return name; }
    function symbol() external view returns (string memory) { return symbol; }
    function tokenURI(uint256) external pure returns (string memory) { revert("Mock: Not implemented"); }
}

部署Mock合约时传入任意合法的name和symbol参数,将返回的地址作为LensHub构造函数的followNFTImpl和collectNFTImpl参数传入,即可完成LensHub部署。测试时若需要真实功能,可重新部署替换地址。


方案2:工厂合约一键部署依赖+LensHub

编写工厂合约,在同一个交易内先部署所需的ERC721Enumerable合约,再用返回地址部署LensHub并完成初始化,全程无需修改原LensHub合约。

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

import "./LensHub.sol";
import "./YourERC721Enumerable.sol"; // 导入你的目标ERC721合约

contract LensHubFactory {
    event LensHubDeployed(address indexed lensHub, address followNFT, address collectNFT);

    function deployLensHub(
        string calldata followNFTName,
        string calldata followNFTSymbol,
        string calldata collectNFTName,
        string calldata collectNFTSymbol,
        string calldata lensHubName,
        string calldata lensHubSymbol,
        address governance
    ) external returns (address) {
        // 1. 部署Follow NFT合约
        YourERC721Enumerable followNFT = new YourERC721Enumerable(followNFTName, followNFTSymbol);
        // 2. 部署Collect NFT合约
        YourERC721Enumerable collectNFT = new YourERC721Enumerable(collectNFTName, collectNFTSymbol);
        // 3. 部署LensHub
        LensHub lensHub = new LensHub(address(followNFT), address(collectNFT));
        // 4. 初始化LensHub
        lensHub.initialize(lensHubName, lensHubSymbol, governance);

        emit LensHubDeployed(address(lensHub), address(followNFT), address(collectNFT));
        return address(lensHub);
    }
}

调用工厂合约的deployLensHub函数,传入所有必要参数即可一次性完成所有部署流程。


方案3:测试框架脚本自动处理(针对测试场景)

如果是在Hardhat/Truffle等测试环境中,可通过部署脚本按顺序自动部署依赖合约,再传入地址部署LensHub。以Hardhat为例:

const hre = require("hardhat");

async function main() {
  // 部署Follow NFT合约
  const FollowNFT = await hre.ethers.getContractFactory("YourERC721Enumerable");
  const followNFT = await FollowNFT.deploy("FollowNFT", "FOLLOW");
  await followNFT.deployed();

  // 部署Collect NFT合约
  const CollectNFT = await hre.ethers.getContractFactory("YourERC721Enumerable");
  const collectNFT = await CollectNFT.deploy("CollectNFT", "COLLECT");
  await collectNFT.deployed();

  // 部署LensHub
  const LensHub = await hre.ethers.getContractFactory("LensHub");
  const lensHub = await LensHub.deploy(followNFT.address, collectNFT.address);
  await lensHub.deployed();

  // 初始化LensHub
  await lensHub.initialize("LensHub", "LENS", "0xYourGovernanceAddress");

  console.log(`LensHub deployed to ${lensHub.address}`);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

这种方式完全不需要修改合约,仅通过脚本控制部署顺序,适配测试场景的快速迭代需求。


内容的提问来源于stack exchange,提问作者havendewart.eth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:09:36