Solidity
契約應標記為摘要
我收到錯誤:
契約“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
: 所有已定義函式