发行 TRC-20 Token

使用 OpenZeppelin Contracts for TRON、TronBox 和 TronWeb 编译并部署 TRC-20 Token。

📘

前置阅读

本指南使用 OpenZeppelin Contracts for TRON 提供的 TRC20 实现创建固定供应量 Token,并使用 TronBox 编译、TronWeb 部署到 Shasta 测试网。确认合约行为符合预期后,再考虑部署到主网。

1. 准备账户和开发环境

准备 Node.js 20 或更高版本,并为测试账户领取 Shasta 测试 TRX。部署会消耗能量;主网部署前应先估算能耗,并为部署账户准备足够的质押能量或 TRX。

部署脚本从环境变量读取私钥。请仅使用专门的测试账户,不要把私钥写入源码、配置文件或版本库。后续登记和钱包展示步骤需要 TronLink

2. 准备 TRC-20 合约代码

在项目的 contracts/ 目录中创建 MyToken.sol

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

import {TRC20} from "@openzeppelin/tron-contracts/token/TRC20/TRC20.sol";

contract MyToken is TRC20 {
    constructor(string memory name_, string memory symbol_, uint256 initialSupply)
        TRC20(name_, symbol_)
    {
        _mint(msg.sender, initialSupply);
    }
}

该实现默认使用 18 位精度。initialSupply 使用最小单位,例如 100 万枚 Token 应传入 1000000000000000000000000。需要其他精度时,应覆盖 decimals(),并按相同精度计算初始供应量。若项目还需要后续增发、销毁、暂停或角色权限,应按业务规则显式组合相应扩展并限制管理入口。

3. 编译并部署到 Shasta

在项目根目录创建 package.json,固定本教程使用的依赖版本:

{
  "name": "tron-token-example",
  "version": "1.0.0",
  "private": true,
  "dependencies": {
    "@openzeppelin/tron-contracts": "5.6.0",
    "tronweb": "6.5.0"
  },
  "devDependencies": {
    "tronbox": "4.10.0"
  },
  "overrides": {
    "diff": "8.0.3",
    "serialize-javascript": "7.0.5",
    "ws": "8.21.0",
    "tronbox": {
      "tronweb": "6.5.0"
    }
  }
}

创建 tronbox-config.js,将编译器设置为 Solidity 0.8.20:

// tronbox-config.js
module.exports = {
  compilers: {
    solc: {
      version: '0.8.20',
      settings: {
        optimizer: {
          enabled: true,
          runs: 200
        }
      }
    }
  }
};

安装依赖并编译合约:

npm install
npx tronbox compile

将以下脚本保存为项目根目录下的 deploy-trc20.mjs

import { TronWeb } from 'tronweb';
import { readFile } from 'node:fs/promises';

const privateKey = process.env.TRON_PRIVATE_KEY;
if (!/^[0-9a-fA-F]{64}$/.test(privateKey ?? '')) {
  throw new Error('TRON_PRIVATE_KEY 必须是 Shasta 测试账户的 64 位十六进制私钥');
}

const artifact = JSON.parse(
  await readFile(new URL('./build/contracts/MyToken.json', import.meta.url), 'utf8')
);
if (!Array.isArray(artifact.abi) || !/^(0x)?[0-9a-fA-F]+$/.test(artifact.bytecode ?? '')) {
  throw new Error('MyToken.json 缺少有效的 ABI 或十六进制字节码');
}

const tronWeb = new TronWeb({
  fullHost: 'https://api.shasta.trongrid.io',
  privateKey
});

const wait = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));

async function waitForContract(address, attempts = 20) {
  for (let attempt = 1; attempt <= attempts; attempt++) {
    try {
      const deployed = await tronWeb.trx.getContract(address);
      if (deployed.contract_address && deployed.bytecode) return;
    } catch {
      // 目标节点尚未查询到该合约。
    }
    if (attempt < attempts) await wait(3000);
  }
  throw new Error(`目标节点未能在指定时间内查询到合约,请在 Shasta TRONSCAN 核对地址:${address}`);
}

const contract = await tronWeb.contract().new({
  abi: artifact.abi,
  bytecode: artifact.bytecode,
  feeLimit: 1_000_000_000,
  callValue: 0,
  parameters: ['MyToken', 'MTK', '1000000000000000000000000']
});

const address = tronWeb.address.fromHex(contract.address);
await waitForContract(address);
console.log(`Contract available at: ${address}`);

使用 Shasta 测试账户私钥运行脚本,并在运行后立即清除环境变量:

read -s TRON_PRIVATE_KEY
export TRON_PRIVATE_KEY
node deploy-trc20.mjs
unset TRON_PRIVATE_KEY

脚本只有在目标节点能够查询到合约字节码后才输出地址。记录编译器版本、优化设置、依赖锁文件和合约地址;随后调用 name()symbol()decimals()totalSupply(),并将部署账户地址传给 balanceOf(),确认链上结果与构造参数一致。

4. 验证 TRC-20 合约(可选)

先将合约及其依赖展平为单文件:

npx tronbox flatten contracts/MyToken.sol > MyToken.flat.sol

打开 Shasta TRONSCAN 验证工具,填写合约地址并上传 MyToken.flat.sol。有关完整流程,请参见合约验证

验证时必须使用与部署构建完全一致的配置:

  • 主合约MyToken
  • Solidity 编译器版本0.8.20
  • 许可证MIT
  • 优化与 Runs:启用优化,Runs 为 200

验证成功后,应再次在 TRONSCAN 上核对构造参数、合约 ABI 和链上字节码。

5. 在 TRONSCAN 上登记 Token

打开 Shasta TRONSCAN Token 登记工具,选择 TRC-20,然后使用部署合约的账户连接并签名。

填写 Token 名称、符号、精度、合约地址、图标、项目网站和说明。名称、符号与精度必须与合约查询结果一致;不要仅依据本地源码填写。提交后等待 TRONSCAN 完成数据同步。

登记只是在 TRONSCAN 中补充 Token 展示信息,不会改变合约代码、供应量或持有人余额。

6. 将 Token 添加到 TronLink

在 TronLink 中切换到合约所在网络,通过 TRC-20 合约地址搜索并添加 Token。如果暂时无法搜索到,先确认合约地址和网络正确,再等待 TRONSCAN 完成登记信息同步。

添加后,核对 TronLink 显示的名称、符号、精度和余额,并使用少量测试 Token 完成一次转账测试。主网部署前还应检查权限配置、供应量规则和外部集成需求,并对新增的业务逻辑进行安全审查。


相关资源