Ошибка компиляции ERC4907 в «функции _beforeTokenTransfer»

Я работаю над задачей создания NFT Marketplace с Truffle . Для этого я использую смарт-контракт 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);
   |    

Я использую следующие версии

  • Трюфель v5.6.8 (ядро: 5.6.8)

  • Ганаш v7.5.0

  • Solidity v0.5.16 (solc-js)

  • Узел v16.17.1

  • Web3.js v1.7.4

Я проверил эталонную реализацию на https://eips.ethereum.org/EIPS/eip-4907. Но это все тот же код.

Может кто-нибудь показать мне, что я ошибся здесь? Спасибо


РЕДАКТИРОВАТЬ

Как ответил @Muhammad Hassan, было установлено, что совсем недавно (08.11.2022) в функции _beforeTokenTransfer на ERC721 произошло критическое изменение. Пожалуйста, обратитесь к журналу изменений по следующей ссылке. https://github.com/OpenZeppelin/openzeppelin-contracts/blob/7c5f6bc2c8743d83443fa46395d75f2f3f99054a/CHANGELOG.md#breaking-changes

Добавление дополнительного аргумента «uint256 batchSize» решило проблему компиляции. Спасибо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
164
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Erc4907 — это расширение Erc721, которое вы, возможно, уже знаете. поэтому при звонке super._beforeTokenTransfer() вы на самом деле используете функцию ERC721. Если вы перейдете к ERC721, вы увидите, что действительно требуется 4 аргумента для

function _beforeTokenTransfer(
        address from,
        address to,
        uint256, /* firstTokenId */
        uint256 batchSize
    ) internal virtual {}

Вы можете посетить страницу oz erc721 github, чтобы узнать больше. Аргумент, который вам не хватает, это uint256 batchSize.

Другие вопросы по теме