Compilation
TypeError:契約應標記為抽象
我收到此錯誤:
TypeError: Contract "BaseRegistrarImplementation" should be marked as abstract. --> Contracts/BaseRegistrarImplementation.sol:7:1: | 7 | contract BaseRegistrarImplementation is BaseRegistrar, ERC721 { | ^ (Relevant source part starts here and spans across multiple lines). Note: Missing implementation: --> @openzeppelin/contracts/token/ERC721/ERC721.sol:44:5: | 44 | constructor(string memory name_, string memory symbol_) { | ^ (Relevant source part starts here and spans across multiple lines).
在嘗試編譯這個合約時(基本上是 ENS BaseRegistrarImplementation,更新到solidity 0.8.0)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import './BaseRegistrar.sol'; import '@openzeppelin/contracts/token/ERC721/ERC721.sol'; contract BaseRegistrarImplementation is BaseRegistrar, ERC721 { // A map of expiry times mapping(uint256=>uint) expiries; bytes4 constant private INTERFACE_META_ID = bytes4(keccak256("supportsInterface(bytes4)")); bytes4 constant private ERC721_ID = bytes4( keccak256("balanceOf(address)") ^ keccak256("ownerOf(uint256)") ^ keccak256("approve(address,uint256)") ^ keccak256("getApproved(uint256)") ^ keccak256("setApprovalForAll(address,bool)") ^ keccak256("isApprovedForAll(address,address)") ^ keccak256("transferFrom(address,address,uint256)") ^ keccak256("safeTransferFrom(address,address,uint256)") ^ keccak256("safeTransferFrom(address,address,uint256,bytes)") ); bytes4 constant private RECLAIM_ID = bytes4(keccak256("reclaim(uint256,address)")); constructor(ENS _ens, bytes32 _baseNode) { ens = _ens; baseNode = _baseNode; } modifier live { require(ens.owner(baseNode) == address(this)); _; } modifier onlyController { require(controllers[msg.sender]); _; } /** * @dev Gets the owner of the specified token ID. Names become unowned * when their registration expires. * @param tokenId uint256 ID of the token to query the owner of * @return address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view override returns (address) { require(expiries[tokenId] > block.timestamp); return super.ownerOf(tokenId); } // Authorises a controller, who can register and renew domains. function addController(address controller) external override onlyOwner { controllers[controller] = true; emit ControllerAdded(controller); } // Revoke controller permission for an address. function removeController(address controller) external override onlyOwner { controllers[controller] = false; emit ControllerRemoved(controller); } // Set the resolver for the TLD this registrar manages. function setResolver(address resolver) external override onlyOwner { ens.setResolver(baseNode, resolver); } // Returns the expiration timestamp of the specified id. function nameExpires(uint256 id) external view override returns(uint) { return expiries[id]; } // Returns true iff the specified name is available for registration. function available(uint256 id) public view override returns(bool) { // Not available if it's registered here or in its grace period. return expiries[id] + GRACE_PERIOD < block.timestamp; } /** * @dev Register a name. * @param id The token ID (keccak256 of the label). * @param owner The address that should own the registration. * @param duration Duration in seconds for the registration. */ function register(uint256 id, address owner, uint duration) external override returns(uint) { return _register(id, owner, duration, true); } /** * @dev Register a name, without modifying the registry. * @param id The token ID (keccak256 of the label). * @param owner The address that should own the registration. * @param duration Duration in seconds for the registration. */ function registerOnly(uint256 id, address owner, uint duration) external returns(uint) { return _register(id, owner, duration, false); } function _register(uint256 id, address owner, uint duration, bool updateRegistry) internal live onlyController returns(uint) { require(available(id)); require(block.timestamp + duration + GRACE_PERIOD > block.timestamp + GRACE_PERIOD); // Prevent future overflow expiries[id] = block.timestamp + duration; if(_exists(id)) { // Name was previously owned, and expired _burn(id); } _mint(owner, id); if(updateRegistry) { ens.setSubnodeOwner(baseNode, bytes32(id), owner); } emit NameRegistered(id, owner, block.timestamp + duration); return block.timestamp + duration; } function renew(uint256 id, uint duration) external live onlyController override returns(uint) { require(expiries[id] + GRACE_PERIOD >= block.timestamp); // Name must be registered here or in grace period require(expiries[id] + duration + GRACE_PERIOD > duration + GRACE_PERIOD); // Prevent future overflow expiries[id] += duration; emit NameRenewed(id, expiries[id]); return expiries[id]; } /** * @dev Reclaim ownership of a name in ENS, if you own it in the registrar. */ function reclaim(uint256 id, address owner) external live override { require(_isApprovedOrOwner(msg.sender, id)); ens.setSubnodeOwner(baseNode, bytes32(id), owner); } function supportsInterface(bytes4 interfaceID) public view override returns (bool) { return interfaceID == INTERFACE_META_ID || interfaceID == ERC721_ID || interfaceID == RECLAIM_ID; } }
知道我在做什麼錯嗎?
“缺少的實現”來自您沒有為您的 erc721 創建建構子的事實。
它應該是:
constructor(ENS _ens, bytes32 _baseNode) ERC721("MY_NAME", "MY_SYMBOL"){ ens = _ens; baseNode = _baseNode; }
希望這可以幫助!
當您需要從繼承的契約中實現契約中的功能時,會發生此錯誤。如果合約沒有實現所有功能,則必須將其標記為抽象。在您的情況下,錯誤是指@openzeppelin/contracts/token/ERC721/ERC721.sol:44:5,這是建構子呼叫。因此,您需要添加 ERC721 合約的建構子,例如:
constructor() ERC721("MyNFT", "MNFT") { }
看:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol