Solidity

契約應標記為摘要

  • November 20, 2021

我收到錯誤:

契約“StarNotary”應標記為摘要。

pragma solidity >=0.4.24;

import "../node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol";


contract StarNotary is ERC721 {
   struct Star {
       string name;
   }

   mapping(uint256 => Star) public tokenIdToStarInfo;
   mapping(uint256 => uint256) public starsForSale;

   // Create Star using the Struct
   function createStar(string memory _name, uint256 _tokenId) public {
       Star memory newStar = Star(_name);
       tokenIdToStarInfo[_tokenId] = newStar;
       _mint(msg.sender, _tokenId);
   }

   // Putting an Star for sale (Adding the star tokenid into the mapping starsForSale, first verify that the sender is the owner)
   function putStarUpForSale(uint256 _tokenId, uint256 _price) public {
       require(
           ownerOf(_tokenId) == msg.sender,
           "You can't sale the Star you don't owned"
       );
       starsForSale[_tokenId] = _price;
   }

   function _make_payable(address x) internal pure returns (address payable) {
       return address(uint160(x));
   }

   function buyStar(uint256 _tokenId) public payable {
       require(starsForSale[_tokenId] > 0, "The Star should be up for sale");
       uint256 starCost = starsForSale[_tokenId];
       address ownerAddress = ownerOf(_tokenId);
       require(msg.value > starCost, "You need to have enough Ether");
       transferFrom(ownerAddress, msg.sender, _tokenId);
       address payable ownerAddressPayable = _make_payable(ownerAddress);
       ownerAddressPayable.transfer(starCost);
       if (msg.value > starCost) {
           msg.sender.transfer(msg.value - starCost);
       }
   }
}

我對抽象合約的了解是它們與介面有關。我懷疑它與 Open Zeppelin 庫的 ERC721 的繼承有關。

ERC721 繼承了三個介面:IERC721、IERC721Metadata、IERC721Enumerable。我是否必須從這三個介面中查看整個函式列表並填寫 StarNotary 合約或 ERC721 中缺少的內容?

問題概述

只要您需要從繼承的契約中實現契約中的功能,就會出現此錯誤。例如,如果你有一個合約繼承了一個callMe聲明了函式的介面,你需要確保你的合約在callMe某個地方有一個函式。

這裡發生了什麼

在這種特定情況下,您缺少建構子呼叫。即使您不想更改原來的 ERC721 建構子,您的合約中仍然需要一個。因此,您會收到將其聲明為“抽象”契約的錯誤。抽象合約不能被實例化。

constructor() ERC721("GameItem", "ITM") public { }

已經足夠了。您可以隨時查看文件以了解如何使用契約:https ://docs.openzeppelin.com/contracts/3.x/erc721

另一個例子

另一個例子是,如果你有一個看起來像這樣的契約:

pragma solidity ^0.8.9;

interface inheritMe {
   function interitedFunction() external;
}

contract mainContract is inheritMe {
}

在這個例子中,你也會遇到這個錯誤。這是因為我們的合約mainContract是繼承inheritMe的,它有一個interitedFunction,但是沒有定義這個函式。所以沒有定義interitedFunction,這意味著我們mainContract也有這個未定義的函式。如果我們有一個同時具有已定義和未定義功能的合約,則稱為abstract合約。

interface: 所有未定義函式 abstract: 混合定義和未定義函式 contract: 所有已定義函式

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