ERC20合约设置最大代币供应量显示不匹配问题
问题根因
代码存在两处问题,核心问题为代币精度换算逻辑错误:
- OpenZeppelin标准ERC20实现默认采用18位小数精度,和ETH的单位逻辑一致:1个用户可见的主单位代币对应10^18个链上最小单位。
_mint()函数接收的第二个参数是最小单位的数量,而非直接传入主单位数值。你当前传入的铸造值为1000000(即1e6个最小单位),换算成主单位为1e6 / 1e18 = 0.000000000001,和MetaMask、Etherscan上的显示值完全吻合。 - 次要问题为状态变量遮蔽:ERC20父合约本身已经内置了
_totalSupply状态变量记录总供应量,你在子合约中重新定义的uint private _totalSupply属于冗余无效代码。两个同名变量是完全独立的存储项,你在构造函数中对自定义_totalSupply的赋值不会被父合约的_mint等逻辑读取,没有任何实际作用。
修复方案
- 删除自定义的冗余
_totalSupply状态变量 - 铸造时将主单位数量乘以10的精度次方,100万枚18位精度代币对应的铸造参数为
1000000 * 10 ** decimals()
修复后的完整合约代码:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract Artytoken is ERC20 { address public admin; constructor() ERC20('ArtyToken', 'AATK') { admin = msg.sender; _mint(admin, 1000000 * 10 ** decimals()); } }
补充说明:如果需要自定义代币小数位数(比如稳定币常用6位精度),可以重写
decimals()函数返回对应值,同步调整铸造数量的乘数即可。
内容的提问来源于stack exchange,提问作者ArtySaurio
相关产品推荐
相关产品推荐

