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

如何在测试网测试ERC20合约?附Solidity代码优化咨询

关于USDT存提合约测试与代码优化的问题

1. 如何使用测试USDT测试合约?

  • 先给合约授权:测试账户调用测试USDT合约的approve方法,授权合约可划转的USDT额度,数值需大于等于你要存入的金额。
  • 执行存入操作:调用合约的depositUSDT方法,传入存入数量(注意USDT是6位小数,比如存1个USDT要传1000000)。
  • 验证提取逻辑:调用所有者专属的提取方法(需先优化合约代码),传入目标用户地址和提取金额,确认USDT是否成功转到所有者钱包。

2. 可在哪些环境测试?

  • Remix本地模拟链(Remix VM):自己部署一个测试版USDT合约(用OpenZeppelin的ERC20模板,设置6位小数),替换原合约中的USDT地址,再调用测试USDT的mint方法给自己发币测试。
  • 公链测试网:比如Sepolia、Polygon Mumbai等,这些网络有对应测试版的USDT合约,直接部署你的合约到对应测试网即可。
  • 本地私有链:用Hardhat或Foundry搭建本地测试链,部署测试USDT和你的合约,还能写自动化测试脚本批量验证逻辑。

3. 如何获取测试网USDT?

  • 测试网水龙头:部分公链测试网有官方或第三方水龙头,可直接申请测试USDT。
  • 自行部署测试代币:在测试网部署一个ERC20合约,设置小数为6,调用mint给自己的测试账户发币,完全可控。
  • 开发者社群互助:在web3开发者社群里找其他开发者索要少量测试USDT。

4. 合约代码优化建议

原合约未实现「所有者提取用户USDT」的核心需求,还存在冗余代码,优化后的代码如下:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

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

contract USDTManager {
    address public immutable owner;
    address public immutable usdtToken;
    mapping(address => uint256) public userBalances;
    uint256 public constant MIN_DEPOSIT = 1e6; // 对应1个USDT(6位小数)

    event USDTDeposited(address indexed user, uint256 amount);
    event USDTWithdrawnByOwner(address indexed owner, address indexed user, uint256 amount);

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner allowed");
        _;
    }

    constructor(address _usdtToken) {
        owner = msg.sender;
        usdtToken = _usdtToken;
        require(_usdtToken != address(0), "Invalid USDT address");
    }

    // 用户存入USDT
    function depositUSDT(uint256 _amount) external {
        require(_amount >= MIN_DEPOSIT, "Deposit amount too small");
        require(IERC20(usdtToken).transferFrom(msg.sender, address(this), _amount), "Transfer failed");
        
        userBalances[msg.sender] += _amount;
        emit USDTDeposited(msg.sender, _amount);
    }

    // 所有者提取指定用户的USDT到自己钱包
    function withdrawUserUSDT(address _user, uint256 _amount) external onlyOwner {
        require(_amount > 0, "Invalid withdrawal amount");
        uint256 userBalance = userBalances[_user];
        require(userBalance >= _amount, "User balance insufficient");
        
        userBalances[_user] -= _amount;
        require(IERC20(usdtToken).transfer(owner, _amount), "Transfer failed");
        
        emit USDTWithdrawnByOwner(msg.sender, _user, _amount);
    }

    // 查看合约当前USDT总余额
    function getContractUSDTBalance() external view returns (uint256) {
        return IERC20(usdtToken).balanceOf(address(this));
    }
}

优化点说明:

  • 移除SafeMath:Solidity 0.8.x版本内置溢出/下溢检查,无需额外引入。
  • 修正核心逻辑:新增withdrawUserUSDT方法,实现所有者提取指定用户USDT的需求。
  • 使用immutable:修饰owner和USDT地址,部署后不可修改,节省gas消耗。
  • 公开状态变量:userBalances和usdtToken设为public,方便外部查询状态。
  • 调整最小存入额:USDT是6位小数,原MIN_DEPOSIT_AMOUNT=1实际为0.000001 USDT,改为1e6对应1个USDT,更符合实际场景。
  • 增加转账校验:transferFrom和transfer返回bool值,用require确保转账成功。
  • 删除无用代码:移除未使用的fromAddressList、MAX_UINT以及ETH相关事件。
  • 构造函数传参:USDT地址通过构造函数传入,避免硬编码,方便切换不同网络。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:32:26