我正在使用Truffle进行NFT Marketplace创建任务。为此,我使用ERC4907智能合约并试图编译它。以下是我的ERC4907代码。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "./IERC4907.sol";
contract ERC4907 is ERC721URIStorage, IERC4907 {
struct UserInfo {
address user; // address of user role
uint64 expires; // unix timestamp, user expires
}
mapping(uint256 => UserInfo) internal _users;
constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}
/// @notice set the user and expires of a NFT
/// @dev The zero address indicates there is no user
/// Throws if `tokenId` is not valid NFT
/// @param user The new user of the NFT
/// @param expires UNIX timestamp, The new user could use the NFT before expires
function setUser(
uint256 tokenId,
address user,
uint64 expires
) public virtual override {
require(
_isApprovedOrOwner(msg.sender, tokenId),
"ERC721: transfer caller is not owner nor approved"
);
UserInfo storage info = _users[tokenId];
info.user = user;
info.expires = expires;
emit UpdateUser(tokenId, user, expires);
}
/// @notice Get the user address of an NFT
/// @dev The zero address indicates that there is no user or the user is expired
/// @param tokenId The NFT to get the user address for
/// @return The user address for this NFT
function userOf(uint256 tokenId)
public
view
virtual
override
returns (address)
{
if (uint256(_users[tokenId].expires) >= block.timestamp) {
return _users[tokenId].user;
} else {
return address(0);
}
}
/// @notice Get the user expires of an NFT
/// @dev The zero value indicates that there is no user
/// @param tokenId The NFT to get the user expires for
/// @return The user expires for this NFT
function userExpires(uint256 tokenId)
public
view
virtual
override
returns (uint256)
{
return _users[tokenId].expires;
}
/// @dev See {IERC165-supportsInterface}.
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override
returns (bool)
{
return
interfaceId == type(IERC4907).interfaceId ||
super.supportsInterface(interfaceId);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
if (from != to && _users[tokenId].user != address(0)) {
delete _users[tokenId];
emit UpdateUser(tokenId, address(0), 0);
}
}
}
我得到以下错误时,试图编译它。错误出现在&;_beforetokentransfer &;函数。
CompileError: TypeError: Wrong argument count for function call: 3 arguments given but expected 4.
--> project:/contracts/ERC4907.sol:87:5:
|
87 | super._beforeTokenTransfer(from, to, tokenId);
|
我正在使用以下版本
Truffle v5.6.8 (core: 5.6.8)
甘那许v7.5.0
Solidity v0.5.16 (solc-js)
节点v16.17.1Web3.js v1.7.4
我已经检查了https://eips.ethereum.org/EIPS/eip-4907上的参考实现。但它仍然是相同的代码。
谁能告诉我我哪里搞错了吗?谢谢你编辑正如@Muhammad Hassan回答的那样,最近(2022-11-08)发现ERC721上的_beforeTokenTransfer函数有一个突破性的变化。请通过以下链接查看变更日志。https://github.com/OpenZeppelin/openzeppelin-contracts/blob/7c5f6bc2c8743d83443fa46395d75f2f3f99054a/CHANGELOG.md的修改
添加额外的参数"uint256 batchSize"解决了编译问题。谢谢你。
Erc4907是您可能已经知道的Erc721的扩展。所以当调用super._beforeTokenTransfer()
时,你实际上是在点击ERC721的功能。如果你去ERC721你会看到
function _beforeTokenTransfer(
address from,
address to,
uint256, /* firstTokenId */
uint256 batchSize
) internal virtual {}
您可以访问oz erc721 github页面了解更多信息。您缺少的参数是uint256 batchSize
。