繁体   English   中英

有没有办法在部署之前预先部署从智能合约中部署的库?

[英]Is there a way pre-deploy a library deployed from within a smart contract before it is deployed?

对不起,如果这个问题没有意义。 这是我想做的事情:我想部署这个智能合约(LenseHub),它导入一个需要将数据传递给其构造函数的库。 这是有问题的,因为我需要 LenseHub 来初始化合约(一个 function 我只能在部署合约后调用)。 如果我尝试在没有预先部署 IERC721Enumerable 的情况下部署 LenseHub,它显然会失败。 如果我无法弄清楚这一点,我将只继承 IERC721Enumerable 并通过构造函数对其进行初始化,但我真的很想保持原始智能合约的完整性(用于测试目的)。 任何有关如何做到这一点的建议将不胜感激

以下是智能合约的相关部分:

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

/**
 * @title LensHub
 * @author Lens Protocol
 *
 * @notice This is the main entrypoint of the Lens Protocol. It contains governance functionality as well as
 * publishing and profile interaction functionality.
 *
 * NOTE: The Lens Protocol is unique in that frontend operators need to track a potentially overwhelming
 * number of NFT contracts and interactions at once. For that reason, we've made two quirky design decisions:
 *      1. Both Follow & Collect NFTs invoke an LensHub callback on transfer with the sole purpose of emitting an event.
 *      2. Almost every event in the protocol emits the current block timestamp, reducing the need to fetch it manually.
 *
 * OVERVIEW: The lense protocall is one of the three main solidity contracts compiled. It compiles all of its code imports code into
 * one main "hub" from were you can interact with the protocall.
 *
 *
 */
contract LensHub is
  LensNFTBase,
  VersionedInitializable,
  LensMultiState,
  LensHubStorage,
  ILensHub
{
  uint256 internal constant REVISION = 1;

  address internal immutable FOLLOW_NFT_IMPL;
  address internal immutable COLLECT_NFT_IMPL;

  /**
   * @dev This modifier reverts if the caller is not the configured governance address.
   */
  modifier onlyGov() {
    _validateCallerIsGovernance();
    _;
  }

  /**
   * @dev The constructor sets the immutable follow & collect NFT implementations.
   *
   * @param followNFTImpl The follow NFT implementation address.
   * @param collectNFTImpl The collect NFT implementation address.
   */
  constructor(address followNFTImpl, address collectNFTImpl) {
    if (followNFTImpl == address(0)) revert Errors.InitParamsInvalid();
    if (collectNFTImpl == address(0)) revert Errors.InitParamsInvalid();
    FOLLOW_NFT_IMPL = followNFTImpl;
    COLLECT_NFT_IMPL = collectNFTImpl;
  }

  /// @inheritdoc ILensHub
  function initialize(
    string calldata name,
    string calldata symbol,
    address newGovernance
  ) external override initializer {
    super._initialize(name, symbol);
    _setState(DataTypes.ProtocolState.Paused);
    _setGovernance(newGovernance);
  }

这是初始化 function 调用的 _function:

 function _initialize(string calldata name, string calldata symbol) internal {
        ERC721Time.__ERC721_Init(name, symbol);

        emit Events.BaseInitialized(name, symbol, block.timestamp);
    }

这是图书馆的相关部分:

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

这是我试图将变量传递给的 ERC721 的构造函数:

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

首先,不要将 IERC721Enumerable 称为库 - 它只是您要在合约中实现的接口。 在solidity 的上下文中, library有一些不同的含义。 这个问题在稳固性的背景下变得具有误导性。

其次,您想要实现的目标可以通过两种方式完成 - 复杂但更正确和容易但不太正确:

  1. 复杂的方法要求您使用IERC721Upgradeable并在需要时正确升级您的联系人。 我认为您不需要 go 到目前为止,因为使用代理需要严格的学习曲线,而您的用例不需要它。
  2. 更简单的方法是直接在您的合同中复制所需的接口方法(或您的联系人将依赖的其他一些 class,这将对所需的修改开放)。 这样,您将能够随时设置您的名称和符号,并且您的合约仍然符合 NFT 接口。 我知道复制代码看起来是个坏主意,但是一旦部署合同(如果不可升级),您将无法更改合同中的任何内容,因此,复制代码在长跑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM