Контракт «Монета» должен быть помечен как абстрактный

#solidity #smartcontracts

#прочность #смарт-контракты

Вопрос:

я хочу создать токен в сети ERC-20.

я хочу получить наследство от интерфейса в своем контракте .

когда я использую интерфейс формы наследования, он показывает мне эту ошибку :

Контракт «CpayCoin» должен быть помечен как абстрактный.

solc версия в трюфеле :

 compilers: { solc: {  version: "0.8.10", // Fetch exact version from solc-bin (default: truffle's version)  docker: false, // Use "0.5.1" you've installed locally with docker (default: false)  settings: { // See the solidity docs for advice about optimization and evmVersion  optimizer: {  enabled: false,  runs: 200  },  evmVersion: "byzantium"  } }  

},

в чем проблема ? как я могу решить эту проблему ???

это мой интерфейс :

 // SPDX-License-Identifier: MIT pragma solidity gt;=0.4.22 lt;0.9.0;  interface IERC20 {  function decimals() external view returns (uint8);   function totalSupply() external view returns (uint256);   function balanceOf(address account) external view returns (uint256);   function transfer(address recipient, uint256 amount)  external  returns (bool);   function allowance(address owner, address spender)  external  view  returns (uint256);   function approve(address spender, uint256 amount) external returns (bool);   function transferFrom(  address sender,  address recipient,  uint256 amount  ) external returns (bool);   event Transfer(address indexed from, address indexed to, uint256 value);  event Approval(  address indexed owner,  address indexed spender,  uint256 value  ); }  

контракт :

 // SPDX-License-Identifier: MIT  

pragma solidity gt;=0.4.22 lt;0.9.0;

 import "./IERC-20.sol";  contract CpayCoin is IERC20 {  //mapping  mapping(address =gt; uint256) private _balances;  mapping(address =gt; mapping(address =gt; uint256)) private _allowances;   //Unit256  uint256 private _totalSupply;  uint256 private _tokenPrice;   // String  string private _name;  string private _symbol;   //Address  address _minter;   constructor(  string memory name_,  string memory symbol_,  uint256 totalSupply_  ) {  _minter = msg.sender;  _balances[_minter] = _totalSupply;  _tokenPrice = 10**15 wei;  _name = name_;  _symbol = symbol_;  _totalSupply = totalSupply_;  }   // Modifier  modifier onlyMinter() {  require(msg.sender == _minter, "Only Minter can Mint!");  _;  }   modifier enoughBalance(address adr, uint256 amount) {  require(_balances[adr] gt;= amount, "Not enough Balance!");  _;  }   modifier enoughValue(uint256 amount) {  require(msg.value == amount * _tokenPrice, "Not enough Value!");  _;  }   modifier checkZeroAddress(address adr) {  require(adr != address(0), "ERC20: mint to the zero address");  _;  }   // Functions  function name() public view virtual returns (string memory) {  return _name;  }   function symbol() public view virtual returns (string memory) {  return _symbol;  }   function totalSupply() public view virtual override returns (uint256) {  return _totalSupply;  }   function balanceOf(address adr)  public  view  virtual  override  returns (uint256)  {  return _balances[adr];  }   function _mint(address account, uint256 amount)  internal  virtual  onlyMinter  checkZeroAddress(account)  {  _totalSupply  = amount;  _balances[account]  = amount;   emit Transfer(address(0), account, amount);  }   function _burn(address account, uint256 amount)  internal  virtual  onlyMinter  checkZeroAddress(account)  {  uint256 accountBalance = _balances[account];  unchecked {  _balances[account] = accountBalance - amount;  }   _totalSupply  = amount;  emit Transfer(account, address(0), amount);  }   function _transfer(  address sender,  address recipient,  uint256 amount  ) internal virtual {  require(sender != address(0), "ERC20: transfer from the zero address");  require(recipient != address(0), "ERC20: transfer to the zero address");   uint256 senderBalance = _balances[sender];  require(  senderBalance gt;= amount,  "ERC20: transfer amount exceeds balance"  );   unchecked {  _balances[sender] = senderBalance - amount;  }   _balances[recipient]  = amount;   emit Transfer(sender, recipient, amount);  }   function _approve(  address owner,  address spender,  uint256 amount  ) internal virtual {  require(owner != address(0), "ERC20: approve from the zero address");  require(spender != address(0), "ERC20: approve to the zero address");   _allowances[owner][spender] = amount;  emit Approval(owner, spender, amount);  } }  

Ответ №1:

В настоящее время у солидности (v0.8) нет способа определить, что класс (контракт) реализует интерфейс. Вместо is этого ключевое слово используется для обозначения наследования как «производное от».

Таким CpayCoin is IERC20 образом, выражение помечает CpayCoin как дочернее и IERC20 как родительское, а не как интерфейс.

IERC20 (Родитель) определяет несколько функций (например decimals() , и transfer() ), которые CpayCoin (потомок) не реализует, что делает CpayCoin абстрактный класс.


Решение:

Реализуйте CpayCoin все функции, определенные в IERC20 интерфейсе, чтобы не превращать его в абстрактный класс и чтобы он соответствовал стандарту ERC-20. Затем вы можете удалить наследование, поскольку оно становится излишним.

Или просто удалите наследование, чтобы не было никаких нереализованных определений функций (но тогда контракт не будет соответствовать стандарту ERC-20).

Имейте в виду, что в вашем текущем коде _transfer() внутренняя функция недоступна. Я бы рекомендовал реализовать transfer() внешнюю функцию, которая вызывает эту внутреннюю _transfer() .