在TRON上触发智能合约:TronWeb和API指南 — TRON Wiki

在TRON上触发智能合约:TronWeb和API指南

11 分钟阅读 · ⌘K 搜索

与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
复杂的 DeFi150_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。

前端 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}

  1. 首先在 Shasta/Nile 上进行测试 — testnet
  2. 在TronScan上验证合约 — 验证合约
  3. 设置明确的feeLimit——避免默认值太低
  4. 在假设成功之前解析收据result
  5. 幂等重试——重发前检查 txid

多重调用模式

路由器在一笔交易中批量交换。您的合约可以使用内部调用 - 请注意重入 和每笔交易的能量限制。

相关指南 {#相关}

常见问题解答

TRON 上的调用和触发有什么区别?

常量调用读取状态而无需事务。触发智能合约广播消耗能量的状态变化。

一次智能合约调用使用多少能量?

TRC-20 转移~65,000 能量。复杂的调用更多——在测试网上进行测试。

没有私钥可以触发吗?

读取呼叫是的。写入需要签名 - TronLink 或服务器端密钥。

API 中的visible: true 是什么意思?

请求/响应中的地址在 true 时使用 Base58 T 格式,在 false 时使用十六进制。

我如何批准然后交换两笔交易?

首先是代币合约上的approve(router, amount),然后是路由器上的swap——两个单独的触发器。一些 UI 通过多重调用合约进行批处理。