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()

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()

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()

(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() and fallback() functions must be marked payable for the contract to receive and hold TRX.
  • Run require checks 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 as TRXTransferred, when indexers or explorers need to track the movement.

Related resources