#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()
.