TRC-20 合约交互

使用 HTTP API、TronWeb 和 Wallet-CLI 读取已部署 TRC-20 合约的状态并调用其方法。

📘

前置阅读

本文以 Shasta 测试网的 USDT 合约 为例,演示如何通过节点 HTTP API、TronWeb、Wallet-CLI 与 TRC-20 合约交互。

Wallet-CLI 命令参考

以下 Wallet-CLI 示例主要涉及两个命令,其参数约定如下:

TriggerConstantContract——适用于 view / pure(只读)函数,无交易广播:

TriggerConstantContract [ownerAddress] [contractAddress] [method] [args] [isHex]

TriggerContract——适用于改变状态的函数,且广播一笔交易:

TriggerContract [ownerAddress] [contractAddress] [method] [args] [isHex] [fee_limit] [value] [token_value] [token_id]
参数含义
ownerAddress调用方地址。
contractAddressTRC-20 合约地址。
method合约函数。
args函数参数。无参数时使用 # 作为占位符。
isHex地址参数是否为十六进制格式。
fee_limit字段单位为 sun;系统按该 TRX 金额换算本次交易可使用的能量上限,覆盖质押能量和燃烧 TRX 可换算出的能量。
value调用时转入合约的 TRX 数量,单位为 sun
token_value调用时转入合约的 TRC-10 资产数量。
token_id调用时转入合约的 TRC-10 资产 ID。

TronWeb 示例全程复用以下相同的配置:

const { TronWeb } = require('tronweb');

const tronWeb = new TronWeb({
  fullHost: 'https://api.shasta.trongrid.io',
  // headers: { 'TRON-PRO-API-KEY': 'YOUR_API_KEY' },   // 仅主网(api.trongrid.io)需要;Shasta 和 Nile 测试网不需要 API key
  privateKey: 'your private key'
});

const trc20ContractAddress = "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs";
const abi = [...]; // 替换为 Token 的 ABI。

name

调用 name 函数获取 Token 名称。

HTTP API

# 节点 HTTP API:/wallet/triggerconstantcontract
# 说明:触发智能合约常量调用;交易不上链。

BASE_URL=https://api.shasta.trongrid.io   # 示例——可替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "name()",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getName() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        // 对 pure 或 view 方法使用 call()——不广播,不消耗资源。
        const result = await instance.name().call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs name() # false

symbol

调用 symbol 函数获取Token的简称。

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # 示例——可替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "symbol()",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getSymbol() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.symbol().call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs symbol() # false

decimals

调用 decimals 函数获取Token的精度。

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # 示例——可替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "decimals()",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getDecimals() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.decimals().call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs decimals() # false

totalSupply

调用 totalSupply 函数获取Token的总供应量。

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # 示例——可替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "totalSupply()",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getTotalSupply() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.totalSupply().call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs totalSupply() # false

balanceOf

调用 balanceOf 函数获取指定账户的Token余额。

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # 示例——可替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "balanceOf(address)",
  "parameter": "000000000000000000000041977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getBalanceOf() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const address = "TM2TmqauSEiRf16CyFgzHV2BVxBejY9iyR";
        const result = await instance.balanceOf(address).call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs balanceOf(address) "TM2TmqauSEiRf16CyFgzHV2BVxBejY9iyR" false

transfer

调用 transfer 函数发送Token。

HTTP API

# 节点 HTTP API:/wallet/triggersmartcontract
# 说明:触发智能合约(改变状态)。

BASE_URL=https://api.shasta.trongrid.io   # 示例——可替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST ${BASE_URL}/wallet/triggersmartcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "transfer(address,uint256)",
  "parameter": "00000000000000000000004115208EF33A926919ED270E2FA61367B2DA3753DA0000000000000000000000000000000000000000000000000000000000000032",
  "fee_limit": 100000000,
  "call_value": 0,
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

parametertransfer(address,uint256)addressuint256 的编码值。详情请参见参数编码与解码

调用此 HTTP API 后,还需调用签名和广播。

TronWeb

async function sendTransfer() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        // 对改变状态的方法使用 send()——广播交易并消耗资源(带宽和能量)。
        const result = await instance.transfer(
            "TWbcHNCYzqAGbrQteKnseKJdxfzBHyTfuh", // 接收方地址
            1000000                                // 数量
        ).send({
            feeLimit: 100_000_000,
            callValue: 0,
            shouldPollResponse: true
        });
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 transaction error", error);
    }
}

Wallet-CLI

TriggerContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs transfer(address,uint256) "TWbcHNCYzqAGbrQteKnseKJdxfzBHyTfuh",1000000 false 100000000 0 0 #
📘

确认交易

广播后,通过查询 getTransactionInfoById API 确认 TRC-20 转账是否成功。

approve

调用 approve 函数授权另一个地址花费指定数量的Token。

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # 示例——可替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST ${BASE_URL}/wallet/triggersmartcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "approve(address,uint256)",
  "parameter": "0000000000000000000000410FB357921DFB0E32CBC9D1B30F09AAD13017F2CD0000000000000000000000000000000000000000000000000000000000000064",
  "fee_limit": 100000000,
  "call_value": 0,
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

调用此 HTTP API 后,还需调用签名和广播。

TronWeb

// 账户 A 授权账户 B 花费 A 的 10 个 USDT:A 调用 approve(B, 10)。
async function sendApprove() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.approve(
            "TWbcHNCYzqAGbrQteKnseKJdxfzBHyTfuh", // address _spender
            10000000                              // 数量
        ).send({
            feeLimit: 100_000_000,
            callValue: 0,
            shouldPollResponse: true
        });
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 transaction error", error);
    }
}

Wallet-CLI

TriggerContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs approve(address,uint256) "TWbcHNCYzqAGbrQteKnseKJdxfzBHyTfuh",10000000 false 100000000 0 0 #
📘

确认交易

广播后,通过查询 getTransactionInfoById API 确认授权是否成功。

transferFrom

被授权地址可调用 transferFrom 从授权方账户转账Token。

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # 示例——可替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST ${BASE_URL}/wallet/triggersmartcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "transferFrom(address,address,uint256)",
  "parameter": "00000000000000000000004109669733965A37BA3582E70CCC5302F8D254675D0000000000000000000000410FB357921DFB0E32CBC9D1B30F09AAD13017F2CD0000000000000000000000000000000000000000000000000000000000000032",
  "fee_limit": 100000000,
  "call_value": 0,
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

调用此 HTTP API 后,还需调用签名和广播。

TronWeb

// 地址 B 将地址 A 的 10 个 USDT 转移到 C:B 调用 transferFrom(A, C, 10)。
async function sendTransferFrom() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.transferFrom(
            "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH", // address _from
            "TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee", // address _to
            10000000                              // 数量
        ).send({
            feeLimit: 100_000_000,
            callValue: 0,
            shouldPollResponse: true
        });
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 transaction error", error);
    }
}

Wallet-CLI

TriggerContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs transferFrom(address,address,uint256) "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH","TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee",10000000 false 100000000 0 0 #
📘

确认交易

广播后,通过查询 getTransactionInfoById API 确认转账是否成功。

allowance

被授权地址可调用 allowance 查询从授权方账户剩余可使用的授权额度。

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # 示例——可替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "allowance(address,address)",
  "parameter": "00000000000000000000004109669733965A37BA3582E70CCC5302F8D254675D000000000000000000000041A245B99ECB47B18C6A90ED1D51100C5A9F0641A7",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

// 查询 A 已授权 B 多少花费额度:B 调用 allowance(A, B)。
async function getAllowance() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.allowance(
            "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH", // address _owner
            "TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee"  // address _spender
        ).call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs allowance(address,address) "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH","TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee" false

相关资源