You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

工厂合约生成ERC20代币 钱包导入后初始供应量显示为0

问题说明

编写了用于生成ERC20代币的工厂合约,目前可正常完成代币创建操作,但存在异常:代码中已设置初始供应量参数,将生成的代币地址导入钱包后,代币持有量显示为0,预期初始总供应量应为2000000枚。

相关代码

工厂合约代码片段

contract TokenFactory {
    event MyTokenCreated(address contractAddress);

    function createNewMyToken() public returns (address) {
        MyToken myToken = new MyToken(2000000);
        emit MyTokenCreated(address(myToken));
        return address(myToken);
    }

MyToken.sol 合约代码

pragma solidity ^0.8.7;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor (uint256 initialSupply) ERC20("MyToken", "MY") {
        _mint(msg.sender, initialSupply * 10 ** 18);
    }
}
问题根因

核心问题出在Solidity的msg.sender取值规则上:当合约内通过new关键字部署新合约时,新合约构造函数中的msg.sender指向的是发起部署操作的合约地址,而非调用工厂合约方法的外部用户地址。

  • 调用TokenFactory.createNewMyToken()方法时,MyToken合约的部署操作由TokenFactory合约发起,因此MyToken构造函数内的msg.sender是TokenFactory合约地址,不是发起交易的个人钱包地址。
  • 代码中_mint(msg.sender, initialSupply * 10 ** 18)逻辑,会将全部2000000枚代币铸造到TokenFactory合约地址下,个人钱包地址在该代币合约中的余额为0。
  • 绝大多数钱包导入代币地址后,默认展示的是当前连接钱包地址的对应代币持仓余额,不会主动查询代币的全局总供应量,因此页面显示为0。实际上该代币的链上总供应量是正确的2000000 * 10^18 基础单位,只是全部代币都存放在工厂合约地址中。

修复方式

选择任意一种方案即可:

  1. 调整代币合约构造函数,新增接收地址参数,部署时直接将代币铸造给调用工厂方法的用户:
// MyToken合约构造函数修改
constructor (uint256 initialSupply, address initialReceiver) ERC20("MyToken", "MY") {
    _mint(initialReceiver, initialSupply * 10 ** 18);
}

// 工厂合约部署代币时传入调用者地址
function createNewMyToken() public returns (address) {
    MyToken myToken = new MyToken(2000000, msg.sender);
    emit MyTokenCreated(address(myToken));
    return address(myToken);
}
  1. 保留现有MyToken代码不变,在工厂合约部署完代币后,调用代币的转账方法,将工厂合约收到的全部初始供应量转给调用者即可。

内容的提问来源于stack exchange,提问作者code_learner93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:51:23