Error while upgrading smart contract | solidity | TypeError: Contract "IERC721" should be marked as abstract

Error while upgrading smart contract | solidity | TypeError: Contract "IERC721" should be marked as abstract

我正在尝试将我的合约版本从 0.5.0 升级到 0.8.0 我将向操作员授予此智能合约的权限。稍后通过这个智能合约我将转移 NFT 代币。这是 0.5.0 版本的合约

pragma solidity ^0.5.0;

interface IERC165 {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

contract IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    function balanceOf(address owner) public view returns (uint256 balance);
    function ownerOf(uint256 tokenId) public view returns (address owner);
    function safeTransferFrom(address from, address to, uint256 tokenId) public;
    function transferFrom(address from, address to, uint256 tokenId) public;
    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);
    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}

contract TransferProxy {

    function erc721safeTransferFrom(IERC721 token, address from, address to, uint256 tokenId) external {
        token.safeTransferFrom(from, to, tokenId);
    }
}

但是当我将 solidity 版本更改为 0.8.0 时,出现以下错误,

TypeError: Contract "IERC721" should be marked as abstract.
 --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:7:1:
  |
7 | contract IERC721 is IERC165 {
  | ^ (Relevant source part starts here and spans across multiple lines).
Note: Missing implementation:
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:16:5:
   |
16 |     function approve(address to, uint256 tokenId) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Missing implementation:
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:12:5:
   |
12 |     function balanceOf(address owner) public view returns (uint256 balance);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Missing implementation:
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:17:5:
   |
17 |     function getApproved(uint256 tokenId) public view returns (address operator);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Missing implementation:
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:19:5:
   |
19 |     function isApprovedForAll(address owner, address operator) public view returns (bool);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Missing implementation:
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:13:5:
   |
13 |     function ownerOf(uint256 tokenId) public view returns (address owner);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Missing implementation:
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:14:5:
   |
14 |     function safeTransferFrom(address from, address to, uint256 tokenId) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Missing implementation:
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:20:5:
   |
20 |     function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Missing implementation:
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:18:5:
   |
18 |     function setApprovalForAll(address operator, bool _approved) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Missing implementation:
 --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:4:5:
  |
4 |     function supportsInterface(bytes4 interfaceId) external view returns (bool);
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Missing implementation:
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:15:5:
   |
15 |     function transferFrom(address from, address to, uint256 tokenId) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Functions without implementation must be marked virtual.
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:12:5:
   |
12 |     function balanceOf(address owner) public view returns (uint256 balance);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Functions without implementation must be marked virtual.
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:13:5:
   |
13 |     function ownerOf(uint256 tokenId) public view returns (address owner);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Functions without implementation must be marked virtual.
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:14:5:
   |
14 |     function safeTransferFrom(address from, address to, uint256 tokenId) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Functions without implementation must be marked virtual.
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:15:5:
   |
15 |     function transferFrom(address from, address to, uint256 tokenId) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Functions without implementation must be marked virtual.
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:16:5:
   |
16 |     function approve(address to, uint256 tokenId) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Functions without implementation must be marked virtual.
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:17:5:
   |
17 |     function getApproved(uint256 tokenId) public view returns (address operator);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Functions without implementation must be marked virtual.
  --> /Users/delete/transfer-proxy/contracts/TransferProxy.sol:18:5:
   |
18 |     function setApprovalForAll(address operator, bool _approved) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Functions without implementation must be marked virtual.
  --> /Users/transfer-proxy/contracts/TransferProxy.sol:19:5:
   |
19 |     function isApprovedForAll(address owner, address operator) public view returns (bool);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

,TypeError: Functions without implementation must be marked virtual.
  --> /Users/transfer-proxy/contracts/TransferProxy.sol:20:5:
   |
20 |     function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Compilation failed. See above.
Truffle v5.3.1 (core: 5.3.1)
Node v12.14.0

帮我解决这个问题。

Solidity 0.6 中引入了抽象合约。与许多其他编程语言一样,抽象 class 允许定义具有部分实现的接口。

因此您可以将合同标记为 abstract

abstract contract IERC721 is IERC165 {

并将没有实现的函数标记为 external virtual(而不是 public)。

function balanceOf(address owner) external virtual view returns (uint256 balance);
// ... etc

因为你的IERC721没有实现任何功能,所以也可以标记为interface(而不是abstract

interface IERC721 is IERC165 {

这也会对多余的 virtual 修饰符发出警告,因此您也可以将其删除(但可见性修饰符需要保留 external

function balanceOf(address owner) external view returns (uint256 balance);