Transferring TRX in smart contracts
Transfer TRX from inside a Solidity contract using transfer(), send(), or call().
Prerequisites
A smart contract holding TRX can send TRX to any address by calling one of Solidity's built-in address member functions. The common options are transfer(), send(), and call(). Choose between them based on how much Energy the recipient needs and whether failure should revert immediately.
Three transfer methods
transfer()
transfer()payable(receiver).transfer(amount);transfer() forwards a fixed 2,300 Energy stipend to the recipient. If the recipient rejects the transfer or execution fails, transfer() automatically reverts the whole transaction. For most simple user-initiated transfers, this is the easiest default for keeping state consistent.
send()
send()bool success = payable(receiver).send(amount);
require(success);send() also forwards only 2,300 Energy, but it does not automatically revert on failure. It returns false. If you use send(), always check the return value; otherwise, later state updates may continue even though the transfer failed.
call()
call()(bool success, ) = payable(receiver).call{value: amount}("");
require(success);call{value: ...}("") forwards the remaining available Energy by default. Use it when the recipient contract legitimately needs to run more logic in receive() or fallback(). It also does not automatically revert, so you must check success explicitly.
For the full semantic comparison, refer to the Solidity documentation on address members.
Example: safe TRX transfer
The contract below exposes a safeTransferTRX function that transfers a requested amount from the contract balance to a recipient, reverting cleanly if the amount is zero or if the contract does not hold enough TRX.
pragma solidity 0.8.0;
contract SimpleTransfer {
// Allow the contract to receive TRX
receive() external payable {}
fallback() external payable {}
event TRXTransferred(address indexed recipient, uint256 amount);
// Safely transfer a specified amount of TRX to a given address.
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() reverts the transaction automatically if the recipient rejects.
recipient.transfer(amount);
emit TRXTransferred(recipient, amount);
}
// Return the current TRX balance held by the contract.
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}Development notes
- The
receive()andfallback()functions must be markedpayablefor the contract to receive and hold TRX. - Run
requirechecks before the transfer. If a check fails, the transaction reverts before any state change. transfer()emits no event on its own. Emit an application-level event, such asTRXTransferred, when indexers or explorers need to track the movement.
Related resources
- Writing & compiling Solidity — Solidity basics on TRON
- FeeLimit & Energy cost — paying for contract execution
- Solidity documentation on address members — official Solidity reference
Updated 20 days ago