智能合约中的 TRX 转账
使用 transfer()、send() 或 call() 在 Solidity 合约内部转账 TRX。
前置阅读
持有 TRX 的智能合约能通过 Solidity 内置的地址成员函数向任意目标地址发送 TRX。常用选项有 transfer()、send() 和 call();选择哪一个,主要取决于接收方需要多少 Energy,以及失败时是否应立即回滚。
三种转账方式
transfer()
transfer()payable(receiver).transfer(amount);transfer() 固定向接收方转发 2,300 Energy。接收方拒收或执行失败时,transfer() 会自动 revert 整笔交易。对大多数用户发起的简单转账来说,这是更容易保持状态一致的默认选择。
send()
send()bool success = payable(receiver).send(amount);
require(success);send() 也只转发 2,300 Energy,但失败时不会自动回滚,只返回 false。如果使用 send(),必须检查返回值;否则转账失败后,后续状态更新仍可能继续执行。
call()
call()(bool success, ) = payable(receiver).call{value: amount}("");
require(success);call{value: ...}("") 默认转发剩余可用 Energy,适用于接收方合约确实需要在 receive() 或 fallback() 中执行更多逻辑的场景。它同样不会自动回滚,必须显式检查 success。
关于地址成员函数的完整语义,请参阅 Solidity 官方文档关于地址类型成员的章节。
示例:安全 TRX 转账
下面的合约提供一个 safeTransferTRX 函数:先检查转账金额和合约余额,再用 transfer() 发送 TRX。任何检查失败都会在状态变更前 revert。
pragma solidity 0.8.0;
contract SimpleTransfer {
// 允许合约接收 TRX
receive() external payable {}
fallback() external payable {}
event TRXTransferred(address indexed recipient, uint256 amount);
/**
* @dev 将指定数量的 TRX 转账给指定地址。
* @param recipient 接收方地址。
* @param amount 转账金额 (单位为 sun)。
*/
function safeTransferTRX(address payable recipient, uint256 amount) external {
require(amount > 0, "Amount must be greater than zero.");
require(address(this).balance >= amount, "Insufficient TRX balance in contract.");
// transfer() 在接收方拒绝或执行失败时自动回滚交易。
recipient.transfer(amount);
emit TRXTransferred(recipient, amount);
}
/**
* @dev 返回合约当前持有的 TRX 余额。
*/
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}开发要点
receive()和fallback()必须标记为payable,合约才能接收并持有 TRX。require应在转账前执行。检查失败时,交易会在状态变更前回滚。transfer()本身不会抛出业务事件。需要被索引器或浏览器追踪时,应手动发出应用层事件,例如TRXTransferred。
相关资源
- 编写与编译 Solidity — TRON 上的 Solidity 开发基础与流程
- FeeLimit 与能量成本 — 控制与支付智能合约执行的资源费用
- Solidity 官方文档地址成员说明 — 官方 Solidity 开发手册
Updated 26 days ago