合同 "Coin" 应标记为摘要
Contract "Coin" should be marked as abstract
我想在 ERC-20 网络上创建一个令牌。
我想继承我合同中的接口。
当我继承表单界面时,它显示这个错误:
Contract "CpayCoin" should be marked as abstract.
solc
truffle 版本:
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 >=0.4.22 <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 >=0.4.22 <0.9.0;
import "./IERC-20.sol";
contract CpayCoin is IERC20 {
//mapping
mapping(address => uint256) private _balances;
mapping(address => mapping(address => 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] >= 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 >= 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);
}
}
Solidity 目前 (v0.8) 无法判断 class(合约)实现了接口。相反,is
关键字用于标记继承,如“派生自”。
因此 CpayCoin is IERC20
表达式将 CpayCoin
标记为子项,将 IERC20
标记为父项 - 而不是接口。
IERC20
(父级)定义了 CpayCoin
(子级)未实现的几个函数(例如 decimals()
和 transfer()
),这使得 CpayCoin
摘要 class.
解法:
在CpayCoin
中实现IERC20
接口中定义的所有函数,使其不抽象class,并使其遵循ERC-20标准。然后您可以自由删除继承,因为它变得多余。
或者只是删除继承以没有任何未实现的函数定义(但这样合约将不遵循 ERC-20 标准)。
请注意,在您当前的代码中,_transfer()
内部函数无法访问。我建议实现一个调用此内部 _transfer()
.
的 transfer()
外部函数
正如 Petr Hejda 在之前的回答中所述:您需要实现所有声明的函数才能拥有普通合约而不是抽象合约。
对于在 truffle 或 hardhat 等本地环境中获取 Contract <ContractName> should be mark as abstract
时遇到此问题的人,您可以使用在线编译器 Remix 找出缺少实现的功能。尝试编译合约后 Remix 中的错误消息明确告诉您缺少的函数。
我想在 ERC-20 网络上创建一个令牌。
我想继承我合同中的接口。
当我继承表单界面时,它显示这个错误:
Contract "CpayCoin" should be marked as abstract.
solc
truffle 版本:
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 >=0.4.22 <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 >=0.4.22 <0.9.0;
import "./IERC-20.sol";
contract CpayCoin is IERC20 {
//mapping
mapping(address => uint256) private _balances;
mapping(address => mapping(address => 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] >= 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 >= 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);
}
}
Solidity 目前 (v0.8) 无法判断 class(合约)实现了接口。相反,is
关键字用于标记继承,如“派生自”。
因此 CpayCoin is IERC20
表达式将 CpayCoin
标记为子项,将 IERC20
标记为父项 - 而不是接口。
IERC20
(父级)定义了 CpayCoin
(子级)未实现的几个函数(例如 decimals()
和 transfer()
),这使得 CpayCoin
摘要 class.
解法:
在CpayCoin
中实现IERC20
接口中定义的所有函数,使其不抽象class,并使其遵循ERC-20标准。然后您可以自由删除继承,因为它变得多余。
或者只是删除继承以没有任何未实现的函数定义(但这样合约将不遵循 ERC-20 标准)。
请注意,在您当前的代码中,_transfer()
内部函数无法访问。我建议实现一个调用此内部 _transfer()
.
transfer()
外部函数
正如 Petr Hejda 在之前的回答中所述:您需要实现所有声明的函数才能拥有普通合约而不是抽象合约。
对于在 truffle 或 hardhat 等本地环境中获取 Contract <ContractName> should be mark as abstract
时遇到此问题的人,您可以使用在线编译器 Remix 找出缺少实现的功能。尝试编译合约后 Remix 中的错误消息明确告诉您缺少的函数。