在TRON上触发智能合约:TronWeb和API指南
与TRON智能合约交互——无论是转移USDT、交换SunSwap,还是调用你自己的DeFi逻辑——都可以归结为编码函数参数、广播triggerSmartContract交易以及支付执行能量。
本指南涵盖 TronWeb 的高级 API、原始 HTTP 触发器、读取与写入调用以及生产模式。
读与写
| 类型 | 广播 | 能源成本 | 方法 |
|---|---|---|---|
| 阅读(查看/纯) | 没有 | 没有 | contract.method().call() |
| 写(状态改变) | 是的 | 是的 | contract.method().send() |
读取使用 triggerconstantcontract — 本地 TVM 模拟。
写入使用 triggersmartcontract — 在区块中开采。
TronWeb 合约实例
const TronWeb = require('tronweb');
const tronWeb = new TronWeb({
fullHost: 'https://api.trongrid.io',
privateKey: process.env.PRIVATE_KEY
});
const USDT = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t';
const abi = [/* TRC-20 ABI fragment */];
const contract = await tronWeb.contract(abi, USDT);
如果contract not found — 网络或地址错误。 找不到合约疑难解答。
读取余额
const balance = await contract.balanceOf('TRecipient...').call();
console.log(balance.toString()); // smallest units
写传输
const amount = 1_000_000; // 1 USDT (6 decimals)
const txid = await contract.transfer('TRecipient...', amount).send({
feeLimit: 100_000_000, // max TRX sun to burn for Energy
});
console.log(txid);
完整演练:以编程方式发送 USDT。
Fee_limit 和 Energy
如果能量不足(在阳光下 — 1 TRX = 1e6 个太阳),feeLimit 帽TRX 会燃烧。
典型设置:
| 运营 | 费用限制(太阳) |
|---|---|
| TRC-20 转机 | 50_000_000 – 100_000_000 |
| 复杂的 DeFi | 150_000_000 – 500_000_000 |
账户应该有冻结的能量或液体TRX。失败的交易仍然会消耗费用——交易失败。
HTTP API:triggerSmartContract
低级 POST 到全节点:
POST https://api.trongrid.io/wallet/triggersmartcontract
正文(简化):
{
"owner_address": "41...hex",
"contract_address": "41...hex",
"function_selector": "transfer(address,uint256)",
"parameter": "0000...encoded",
"fee_limit": 100000000,
"visible": true
}
响应包含transaction对象——本地签名并通过broadcasttransaction广播。
TronWeb 对此进行了抽象。原始 HTTP 对于非 JS 堆栈很有用。请参阅 TRON HTTP API 参考。
触发ConstantContract(读取){#constant}
POST /wallet/triggerconstantcontract
相同编码,无需广播。返回 constant_result 十六进制。
const result = await tronWeb.transactionBuilder.triggerConstantContract(
tronWeb.address.toHex(contractAddress),
'balanceOf(address)',
{},
[{ type: 'address', value: holderAddress }],
tronWeb.address.toHex(callerAddress)
);
参数编码
函数选择器 = keccak256("transfer(address,uint256)") 的前 4 个字节。
参数 ABI 编码为 32 字节槽。 TronWeb 在使用 .send() / .call() 时处理编码。
手动编码错误→链上REVERT。
TronLink 浏览器流程
前端 dApp 使用 TronLink 注入:
const tronWeb = window.tronWeb; const contract = await tronWeb.contract().at(USDT_ADDRESS); await contract.transfer(to, amount).send();
用户在弹出窗口中登录 - 私钥不在网页中。警告用户有关 dApp 风险。
触发 {#events} 后的事件日志
写入后,获取收据:
const info = await tronWeb.trx.getTransactionInfo(txid); const logs = info.log; // Transfer events for TRC-20
事件监听器 用于监控。
常见错误{#errors}
| 错误 | 原因 |
|---|---|
| REVERT | 参数错误,余额/津贴不足 |
| OUT_OF_ENERGY | 提高费用限制或冻结TRX |
| 合同验证错误 | 错误的 ABI 或选择器 |
| 带宽错误 | 冻结带宽 |
最佳实践{#best-practices}
- 首先在 Shasta/Nile 上进行测试 — testnet
- 在TronScan上验证合约 — 验证合约
- 设置明确的
feeLimit——避免默认值太低 - 在假设成功之前解析收据
result - 幂等重试——重发前检查 txid
多重调用模式
路由器在一笔交易中批量交换。您的合约可以使用内部调用 - 请注意重入 和每笔交易的能量限制。
相关指南 {#相关}
常见问题解答
TRON 上的调用和触发有什么区别?
常量调用读取状态而无需事务。触发智能合约广播消耗能量的状态变化。
一次智能合约调用使用多少能量?
TRC-20 转移~65,000 能量。复杂的调用更多——在测试网上进行测试。
没有私钥可以触发吗?
读取呼叫是的。写入需要签名 - TronLink 或服务器端密钥。
API 中的visible: true 是什么意思?
请求/响应中的地址在 true 时使用 Base58 T 格式,在 false 时使用十六进制。
我如何批准然后交换两笔交易?
首先是代币合约上的approve(router, amount),然后是路由器上的swap——两个单独的触发器。一些 UI 通过多重调用合约进行批处理。
感谢你的反馈——帮助我们改进文档。