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);
我正在尝试将我的合约版本从 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);