Transaction

Transactions are cryptographically signed instructions from accounts. An account will initiate a transaction to update the state of the TRON network. The simplest transaction is transferring TRX from one account to another.

Transactions, which change the state of the chain, need to be broadcast to the whole network. Any node can broadcast a request for a transaction. After the super node receives the transaction, it executes the transaction and includes it in a block, then propagates the block to the whole network.

Only after the transaction is packed into a block by the super node, and the block is confirmed, the transaction is finally confirmed.

The format of a transaction is as below:

{
    "raw_data": 
    {
        "contract": [{<-->}],
        "ref_block_bytes": "c145",
        "ref_block_hash": "c56bd8a3b3341d9d",
        "expiration": 1646796363000,
        "data": "74657374",
        "timestamp": 1646796304152,
        "fee_limit":10000000000
    },
    "signature":["47b1f77b3e30cfbbfa41d795dd34475865240617dd1c5a7bad526f5fd89e52cd057c80b665cc2431efab53520e2b1b92a0425033baee915df858ca1c588b0a1800" ] 
}

A submitted transaction mainly includes the following fields:

  • raw_data.contract - The main content of the transaction,contract is a list, but only one element is used at present. Different types of transactions have different contract contents. For example, for a TRX transfer type transaction, the contract will include the transfer amount, receiver address and other information. TRON supports multiple types of contracts, please refer to the Types of Transaction section below for details.
  • raw_data.ref_block_bytes - The height of the transaction reference block, using the 6th to 8th (exclusive) bytes of the reference block height, a total of 2 bytes. The reference block is used in the TRON TAPOS mechanism, which can prevent a replay of a transaction on forks that do not include the referenced block. Generally, the latest solidified block is used as the reference block.
  • raw_data.ref_block_hash - The hash of the transaction reference block, using the 8th to 16th (exclusive) bytes of the reference block hash, a total of 8 bytes. The reference block is used in the TRON TAPOS mechanism, which can prevent a replay of a transaction on forks that do not include the referenced block. Generally, the latest solidified block is used as the reference block.
  • raw_data.expiration - Transaction expiration time, beyond which the transaction will no longer be packed. If the transaction is created by calling the java-tron API, its expiration time will be automatically set by the node to the value of adding 60 seconds to the timestamp of the node's latest block. The expiration time interval can be modified in the node's configuration file, the maximum value cannot exceed 24 hours.
  • raw_data.data - Transaction memo.
  • raw_data.timestamp - Transaction timestamp, set as the transaction creation time.
  • raw_data.fee_limit - The maximum energy cost allowed for the execution of smart contract transactions. Only deploying and triggering smart contract transactions need to be set, others not.
  • signature - The sender's signature for the transaction. This proves that the transaction could only have come from the sender and was not sent fraudulently.

Types of Transaction

On TRON there are many different types of transactions, such as TRX transfer transactions, TRC10 transfer transactions, deploying smart contract transactions, triggering smart contract transactions, staking TRX transactions, and so on.

To create different types of transactions, you need to call different APIs. For example, the type of smart contract deployment transaction is CreateSmartContract, you need to call the wallet/deploycontract API to create a transaction, and the type of the staking TRX transaction is FreezeBalanceV2Contract, you need to call wallet/freezebalancev2 API to create transactions.

$ curl -X POST https://api.shasta.trongrid.io/wallet/freezebalancev2 -d '{"owner_address":"TCrkRWJuHP4VgQF3xwLNBAjVVXvxRRGpbA","frozen_balance": 2100000,"resource" : "BANDWIDTH","visible":true}' | jq
{
  "visible": true,
  "txID": "e54bab34838a59e85d5684e46a2e8e512cd11dfb07b35a9728adeaf3d2666fa6",
  "raw_data": {
    "contract": [
      {
        "parameter": {
          "value": {
            "frozen_balance": 2100000,
            "owner_address": "TCrkRWJuHP4VgQF3xwLNBAjVVXvxRRGpbA"
          },
          "type_url": "type.googleapis.com/protocol.FreezeBalanceV2Contract"
        },
        "type": "FreezeBalanceV2Contract"
      }
    ],
    "ref_block_bytes": "7139",
    "ref_block_hash": "d291dee525445093",
    "expiration": 1646902209000,
    "timestamp": 1646902151591
  },
  "raw_data_hex": "0a0271392208d291dee52544509340e8d39598f72f5a58080b12540a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e467265657a6542616c616e6365436f6e7472616374121e0a15411fafb1e96dfe4f609e2259bfaf8c77b60c535b9310a0968001180370a7939298f72f"
}

For more transaction types, please refer to:Types of transactions on TRON,For more HTTP APIs, please refer to:HTTP API

Transaction Lifecycle

A transaction goes through the following stages in its life cycle:

  1. Transaction's creation and signature.
  2. The transaction is broadcast to the TRON network, it will be included in a transaction cache pool after passing the verification and execution by node(including the block-producing node).
  3. The block-producing node takes out transaction one by one from the transaction cache pool in the order in which they were put in, packages them into a new block, and then broadcasts the new block to the TRON network.
  4. The transaction will be "confirmed". Whether a transaction is confirmed depends on whether the block in which the transaction is included is confirmed. TRON's block confirmation mechanism is that after a block is produced, 19 different super nodes produce subsequent blocks based on this block, then the block is confirmed.

Create Transaction

A variety of libraries and tools are available to create transactions. The following takes tronweb to create a TRX transfer transaction as an example to illustrate how to create a transaction:

const unsignedTxn = await tronWeb.transactionBuilder.sendTrx("TVDGpn4hCSzJ5nkHPLetk8KQBtwaTppnkr", 100, "TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL");
 >{
    "visible": false,
    "txID": "9f62a65d0616c749643c4e2620b7877efd0f04dd5b2b4cd14004570d39858d7e",
    "raw_data": {
        "contract": [
            {
                "parameter": {
                    "value": {
                        "amount": 100,
                        "owner_address": "418840e6c55b9ada326d211d818c34a994aeced808",
                        "to_address": "41d3136787e667d1e055d2cd5db4b5f6c880563049"
                    },
                    "type_url": "type.googleapis.com/protocol.TransferContract"
                },
                "type": "TransferContract"
            }
        ],
        "ref_block_bytes": "0add",
        "ref_block_hash": "6c2763abadf9ed29",
        "expiration": 1581308685000,
        "timestamp": 1581308626092
    },
    "raw_data_hex": "0a020add22086c2763abadf9ed2940c8d5deea822e5a65080112610a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412300a15418840e6c55b9ada326d211d818c34a994aeced808121541d3136787e667d1e055d2cd5db4b5f6c880563049186470ac89dbea822e"
}

Sign Transaction

A transaction needs to be signed using the sender's private key before sending it.

Transaction signature generating process

  1. Calculate the hash of the transaction.
  2. Sign the transaction hash with the sender's private key.
  3. Add the generated signature to the transaction instance.

Most SDKs implement the above transaction signature-generating process and encapsulate them into an interface for developers to call. Taking tronweb as an example, users can directly call the sign method to complete the transaction signature.

Example of signature using tronweb
Use tronweb to sign the transaction created above:

const signedTxn = await tronWeb.trx.sign(unsignedTxn, privateKey);
>{
    "visible": false,
    "txID":"9f62a65d0616c749643c4e2620b7877efd0f04dd5b2b4cd14004570d39858d7e",
    "raw_data":
    {
        "contract": [{<-->}],
        "ref_block_bytes": "0add",
        "ref_block_hash": "6c2763abadf9ed29",
        "expiration": 1581308685000,
        "timestamp": 1581308626092 
    },
    "raw_data_hex": "0a020add22086c2763abadf9ed2940c8d5deea822e5a65080112610a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412300a15418840e6c55b9ada326d211d818c34a994aeced808121541d3136787e667d1e055d2cd5db4b5f6c880563049186470ac89dbea822e",
    "signature": [ "47b1f77b3e30cfbbfa41d795dd34475865240617dd1c5a7bad526f5fd89e52cd057c80b665cc2431efab53520e2b1b92a0425033baee915df858ca1c588b0a1800" ] 
 }

Broadcast Transaction

After the node receives a transaction sent by a user, it will try to verify and execute the transaction locally, and broadcasts valid transactions to other nodes, discards invalid transactions, which will effectively prevent spam transactions from invalid broadcast in the network.

To broadcast a signed transaction using tronweb:

const receipt = await tronWeb.trx.sendRawTransaction(signedTxn);
>{ 
    "result": true,
    "transaction":
    { 
        "visible": false,
        "txID": "9f62a65d0616c749643c4e2620b7877efd0f04dd5b2b4cd14004570d39858d7e",
        "raw_data":
        {
            "contract": [{<-->}],
            "ref_block_bytes": "0add",
            "ref_block_hash": "6c2763abadf9ed29",
            "expiration": 1581308685000,
            "timestamp": 1581308626092 
        },
        "raw_data_hex": "0a020add22086c2763abadf9ed2940c8d5deea822e5a65080112610a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412300a15418840e6c55b9ada326d211d818c34a994aeced808121541d3136787e667d1e055d2cd5db4b5f6c880563049186470ac89dbea822e",
        "signature": [ "47b1f77b3e30cfbbfa41d795dd34475865240617dd1c5a7bad526f5fd89e52cd057c80b665cc2431efab53520e2b1b92a0425033baee915df858ca1c588b0a1800" ] 
    } 
 }

Transaction confirmation

Whether a transaction is confirmed depends on whether the block in which the transaction is included is confirmed. TRON's block confirmation mechanism is that after a block is produced, 19 different super nodes produce subsequent blocks based on this block, then the block is confirmed.

java-tron node provides /walletsolidty/* API, which is convenient for users to query confirmed transactions. The difference between /walletsolidty/* and /wallet/* is that the transaction queried by /wallet/* indicates that it has been on the chain but not necessarily confirmed. The transaction was queried by /walletsolidty/* indicates that it has been on the chain and solidified, that is, the transaction has been confirmed.

For different transactions, there are different ways to determine whether it is confirmed:

  • System Contract Transaction
    All types of transactions other than creating smart contract types and triggering smart contract types are system contract transactions. System contract transaction confirmation method:
    • As long as the transaction can be queried through /walletsolidity/gettransactioninfobyid or /walletsolidity/gettransactionbyid API, it is confirmed.
  • Smart Contract Transaction
    Including creating smart contracts and triggering smart contract transactions. Because they need to be executed in TRON virtual machine, some exceptions may be thrown during the execution. These transactions are on the chain, but it does not mean that the transactions are successfully executed. And there are two ways to determine whether the smart contract transaction is successfully executed:
    • Find transactionInfo.receipt.result equals success via calling the /walletsolidity/gettransactioninfobyid API
    • Find transaction.ret.contractRet equalssuccess via calling /walletsolidity/gettransactionbyidAPI
  • Internal Transaction
    An internal transaction is a transaction that transfers tokens to other external addresses or contract addresses in a contract. First, the internal transactions can be queried through /walletsolidity/gettransactioninfobyid API, and the rejected field in the internal transaction is used to determine whether the internal transaction is confirmed, but differs for HTTP and GRPC API:
    • HTTP API: for successful transactions, the rejected field is not returned by default. For failed transactions, rejected equals true.
    • GRPC API: for successful transactions, rejected equals false, indicating that the current internalTransaction has not been discarded; for failed transactions, rejected equals true.

Transaction Fee

In addition to query operations, any on-chain transaction will consume system resources. All types of transactions need to consume bandwidth. In addition to consuming bandwidth, smart contract deployment and calling transactions also consume energy. When the available bandwidth or energy in the account is insufficient, TRX needs to be burned to pay for the corresponding resource fee. In addition to resource fees, some special transactions require additional fees.

Bandwidth Fee

The amount of bandwidth consumed by a transaction is equal to the number of bytes occupied by the on-chain transaction, which includes three parts: the raw_data of the transaction, the transaction signature, and the transaction result. The number of bytes occupied by these three parts after protobuf serialization encoding is the amount of bandwidth consumed by the transaction.

When both the bandwidth obtained through staking and the daily free bandwidth in the account are insufficient, TRX needs to be burned to pay for the bandwidth:

TRX burned to pay for bandwidth = Total bandwidth consumed by the transaction * Bandwidth unit price

The current bandwidth unit price is 1000 sun.

When the receiver address of TRX and TRC10 transfer transaction is an inactivated address, the transaction will activate the receiver address. In this case, if the caller address does not have enough bandwidth obtained through staking, the transaction will consume 0.1TRX as Bandwidth fee.

For how to estimate the bandwidth consumption of a transaction, please refer to here.

Energy Fee

In addition to consuming bandwidth, smart contract deployment and invocation transactions also consume energy. When the contract is executed, Energy is calculated and deducted according to instruction one by one. The energy obtained by staking will be consumed first. If this part of the energy is not enough, the account's TRX will continue to be burned to pay for the energy resources required for the transaction.

TRX burned to pay for energy fee = (Total amount of energy consumed by the transaction - Amount of energy available in the caller's account) * Energy unit price

The current energy unit price is 420 sun. For how to estimate energy consumption, please refer to here.

Other Fee

For some special transactions, in addition to resource fees, additional fees need to be paid. If the transaction initiator adds notes to the transaction, an additional transaction note fee of 1TRX needs to be paid. If the transaction uses multiple signatures, that is, the number of signatures in the transaction is greater than 1, the transaction initiator needs to pay an additional multi-signature fee of 1TRX. In addition, there are transaction fees for the following specific types of transactions:

Transaction TypeDescriptionFee
WitnessCreateContractApply to become a super representative candidate9999 TRX
AssetIssueContractIssue an TRC10 token1024 TRX
AccountCreateContractCreate a new account, that is, activate an account1 TRX
AccountPermissionUpdateContractUpdate account permissions100 TRX
ExchangeCreateContractCreate a exchange pair1024 TRX

Note that for TransferContract or TransferAssetContract type transactions, that is, TRX transfer, TRC10 token transfer, if the target address is not activated, the transaction will also trigger the creation of a new account, and a new account creation fee of 1TRX will be deducted. At the same time, if the bandwidth obtained through staking in the transaction initiator's account is insufficient, 0.1TRX needs to be paid as bandwidth fee.

Internal Transactions

The so-called transactions generally refer to transactions triggered by external accounts, such as smart contract call transactions. But during the execution of smart contract transactions, the contract may trigger other contract method invocation, or transfer TRX/TRC10 tokens to external accounts, or it may also perform operations such as staking, voting, resource delegating, etc. Such transactions that occur during a smart contract execution are called internal transactions. Therefore internal transactions are transactions triggered in TVM by contract accounts.

The generation of internal transactions

This article takes the exchange of USDT for TRX in a decentralized exchange as an example to illustrate the generation of internal transactions.

The following is the tokenToTrxSwapInput method of TRX-USDT trading pair contract, which can exchange TRX for the user according to the amount of USDT sold by the user:

function tokenToTrxSwapInput(uint256 tokens_sold, uint256 min_trx, uint256 deadline) public returns (uint256) {
    return tokenToTrxInput(tokens_sold, min_trx, deadline, msg.sender, msg.sender);
  }
  
function tokenToTrxInput(uint256 tokens_sold, uint256 min_trx, uint256 deadline, address buyer, address payable recipient) private nonReentrant returns (uint256) {
    require(deadline >= block.timestamp && tokens_sold > 0 && min_trx > 0);
    uint256 token_reserve = token.balanceOf(address(this));
    uint256 trx_bought = getInputPrice(tokens_sold, token_reserve, address(this).balance);
    uint256 wei_bought = trx_bought;
    require(wei_bought >= min_trx);
    recipient.transfer(wei_bought);

    require(address(token).safeTransferFrom(buyer, address(this), tokens_sold));
    emit TrxPurchase(buyer, tokens_sold, wei_bought);
    emit Snapshot(buyer,address(this).balance,token.balanceOf(address(this)));

    return wei_bought;
  }

We can see that there are four codes in this contract function that involve triggering other contracts or transferring tokens to external accounts, which are:

  • Line 7: token.balanceOf(address(this)), used to query the USDT balance of this contract
  • Line 11: recipient.transfer(wei_bought), used to transfer TRX to the invocation account
  • Line 13: address(token).safeTransferFrom(buyer, address(this), tokens_sold)), used to transfer USDT from the invocation account to this contract
  • Line 15: token.balanceOf(address(this)), used to query the USDT balance of this contract

The above four codes respectively correspond to the internal transactions queried through TRONSCAN or through the API interface.

Use-Cases

Internal transactions can provide some vital information for your users. Here are a few use cases where internal transaction information can be used inside a dApp:

  • Failed Transactions Notifications -The entire transaction will fail if an internal transaction fails. The purpose of notifying users of the exact location of the fault point can be achieved through internal transactions, which helps to quickly locate and solve problems
  • Smart Contract Monitoring - Your deployed smart contract can interact with other contracts via internal transactions. To know when and which contracts it interacts with, you can monitor your smart contract address for any internal transactions.
  • Smart Contract Analytics - Since internal transactions can be complex, getting insights is helpful. By looking at the number of internal transactions performed by a smart contract, you can understand the performance of that contract.
  • Batch Transactions - If you send a batch of transactions to different sender addresses, you can use internal transactions to more conveniently and securely ensure they reach the right addresses.

The preservation of internal transactions

There are many use cases for internal transactions, which can guide and inform users about the execution of transactions, but the TRON node does not save internal transaction information by default, and needs to be manually enabled through the node configuration file:

vm = {
    ...
  saveInternalTx = true
  saveFeaturedInternalTx = true
    ...
}
  • saveInternalTx: Whether to save internal transactions
  • saveFeaturedInternalTx: When saveInternalTx is enabled, whether to save Stake2.0-related internal transactions

After the internal transaction storage configuration item is enabled, restart the node. From the moment of the restart, the node will save its internal transactions. Users can view their internal transactions according to the transaction ID of the outer transaction. It is not supported to view internal transactions directly through the hash of internal transactions. The API is gettransactioninfobyid.

The examples of internal transactions

The internal transaction saved by the node contains the following information:

  • hash: the hash value of the internal transaction
  • caller_address: caller address
  • transferTo_address: the calling contract address or the account address receiving TRX/TRC10 tokens
  • callValueInfo.callValue: the amount of TRX/TRC10 tokens transferred
  • callValueInfo.tokenId: TRC10 name or id of the transfer; when transferring TRX, this field is empty.
  • note: instruction type, such as call, create, suicide, freezeBalanceV2ForEnergy, freezeBalanceV2ForBandwidth, unfreezeBalanceV2ForBandwidth, etc.
  • rejected: Whether the internal transaction is executed failed, true means the execution failed.
  • extra: At present, it is mainly used to save voting information and record the voting SR and its number of votes in JSON format

Let's look at the information contained in internal transactions based on various examples:

1. Smart contract calls other smart contract methods

Here is an example, the transaction is an external address calling the "TQn9Y...." contract, in "TQn9Y...." contract, it calls the "TR7NHq...." contract:

{
    "id": "50e6dd05c37b8666cf4a689fe6c0d52053b76b53d8649b256e6b9dca8c9df098",
    ......
    "internal_transactions": [
        {
            "hash": "380f4d87271b83afcf5e867271ee2d30b36c19d3eeb15a043477bce7fd5b2079",
            "caller_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
            "transferTo_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
            "callValueInfo": [
                {}
            ],
            "note": "63616c6c"
        },
        .......
    ]
}

The information contained in the above internal transactions is as follows:

  • internal_transactions.caller_address is the address of the caller, that is, the contract address directly called by the external address
  • internal_transactions.transferTo_address is the address of another contract called in the contract
  • internal_transactions.callValueInfo In this example, the contract did not pass TRX/TRC10 token using value when calling other contracts, so the value of this field is empty. If value information is attached when the contract calls other contract functions, it will be reflected through this field.
  • internal_transactions.note is the instruction description, in Hex format, after converting it to a string, you can get the operation information in plain text, in this example it iscall

2. Smart contract transfers TRX to external accounts

Here is an example, the transaction is an external address calling the "TQn9Y...." contract, in "TQn9Y...." contract, it transfers TRX to the "TQnpn...." address:

{
    "id": "50e6dd05c37b8666cf4a689fe6c0d52053b76b53d8649b256e6b9dca8c9df098",
     ......
    "internal_transactions": [
        ......
        {
            "hash": "f47fede2a45e722e6406421d0df16142e159ae7404525de5a595f4fc0c357e26",
            "caller_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
            "transferTo_address": "TQnpnLZJYMzH5xku535rAiYTnqYXTDTEHQ",
            "callValueInfo": [
                {
                    "callValue": 4514968563
                }
            ],
            "note": "63616c6c"
        },
        ......
    ]
}
  • internal_transactions.caller_addressis the address of the caller, that is, the address of the contract directly called by the external address
  • internal_transactions.transferTo_address is the target address for transferring TRX
  • internal_transactions.callValueInfo[0].callValue is the transfer amount of TRX, the unit is sun
  • internal_transactions.note is the instruction description, in Hex format, after converting it to a string, you can get the operation information in plain text, this example is call

3. Smart contract transfers TRC10 tokens to external accounts

TRC10 transfer is basically the same as TRX transfer, except for the following two fields:

  • internal_transactions.callValueInfo[0].callValue is the amount of TRC10 tokens transferred
  • internal_transactions.callValueInfo[0].tokenId is the TRC10 name or id. Since No. 14 Committee Proposal allows the same token name, so before this proposal takes effect (blocks before 5537806), this field indicates the TRC10 token name, after the proposal takes effect (block 5537806 and later), this field indicates the TRC10 token ID.

4. Smart contract stakes TRX

Here is an example, the transaction is an external address calling the "TU8Mb...." contract, in "TU8Mb....", the contract stakes 1000TRX to obtain energy:

{
    "id": "9d25a4fe417e0c7540cc5c5841e1d8c9215aec556d9b06e18910ed8b5088f0d8",
    ......
    "internal_transactions": [
        {
            "hash": "a3a4d666e7bf0729bbd8b5e5ad7afb7f8dd20191e7298ea9dbd17af345c96ed5",
            "caller_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
            "transferTo_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
            "callValueInfo": [
                {
                    "callValue": 1000000000
                }
            ],
            "note": "667265657a6542616c616e63655632466f72456e65726779"
        }
    ]
}
  • internal_transactions.caller_address is the address of the stake initiator, that is, the address of the contract directly called by the external address
  • internal_transactions.transferTo_address is the resource receiving address, that is, the stake initiator address, that is, the address of the contract directly called by the external address
  • internal_transactions.callValueInfo[0].callValue is the staked TRX amount (in sun)
  • internal_transactions.note is the instruction description in Hex format, and the instruction information in plain text can be obtained after converting it into a string. In this example, it is freezeBalanceV2ForEnergy, which means that the contract stakes TRX to obtain energy. If the contract stakes TRX to obtain bandwidth, the value of this field is freezeBalanceV2ForBandwidth

5. Smart contract unstakes TRX

Here is an example, the transaction is an external address calling the "TU8Mb...." contract, "TU8Mb...." contract performs the unstaking operation to unstake the 100TRX staked to obtain bandwidth:

{
    "id": "dc110091fbd1568f8b264f287c7e0896d1afaf47b906a9e684fd17d57c7a1151",
    ......
    "internal_transactions": [
        {
            "hash": "16f73bdad5e9f984e082909b1028fff0b9865952131e681ca887446f8ec89918",
            "caller_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
            "transferTo_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
            "callValueInfo": [
                {
                    "callValue": 100000000
                }
            ],
            "note": "756e667265657a6542616c616e63655632466f7242616e647769647468"
        }
    ]
}
  • internal_transactions.caller_address is the address of the unstaking initiator, that is, the address of the contract directly called by the external address
  • internal_transactions.transferTo_address is the TRX receiving address, that is, the contract address directly called by the external address
  • internal_transactions.callValueInfo[0].callValue is the amount of TRX unstaked (in sun)
  • internal_transactions.note is the instruction description, in this example it is unfreezeBalanceV2ForBandwidth, which means that the contract unstakes the TRX staked for obtaining bandwidth. If the contract unstakes the TRX staked for obtaining energy, the value of this field is unfreezeBalanceV2ForEnergy

6. Smart contracts delegate resources to other accounts

Here is an example, the transaction is an external address calling the "TU8Mb...." contract, "TU8Mb...." contract delegated the energy share of 500000000sun to the "TUznH...." address:

{
    "id": "342daa21f8865786295c45bb80e2f257740091e4e1a3a546b90daa51bcbcbd18",
    ......
    "internal_transactions": [
        {
            "hash": "58382a79c3af68c472383580309a81a9322e7520a48b6463917ba9219ca32a7d",
            "caller_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
            "transferTo_address": "TUznHJfHe6gdYY7gvWmf6bNZHuPHDZtowf",
            "callValueInfo": [
                {
                    "callValue": 500000000
                }
            ],
            "note": "64656c65676174655265736f757263654f66456e65726779"
        }
    ]
}
  • internal_transactions.caller_address is the resource delegate address, that is, the contract address directly called by the external address
  • internal_transactions.transferTo_address is the resource receiving address
  • internal_transactions.callValueInfo[0].callValue is the delegated resource share(unit is sun)
  • internal_transactions.note is the instruction description, in this example it is delegateResourceOfEnergy, which means the contract delegates energy resources. If it is a contract delegating bandwidth, the field value is delegateResourceOfBandwidth

7. The smart contract cancels the resource delegation for other accounts

Here is an example, the transaction is an external address calling the "TU8Mb...." contract, "TU8Mb...." contract cancels the delegation of 200000000 sun energy shares for the "TUznH...." address:

{
    "id": "aa3961ffb0781d8b66d5e22368e92708135dac9c81eac1e2adcaa8546d729bc8",
    ......
    "internal_transactions": [
        {
            "hash": "1a8524704098770d9c6535e1112d1fb91855363c8366c93810f3cb56e8ee12bf",
            "caller_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
            "transferTo_address": "TUznHJfHe6gdYY7gvWmf6bNZHuPHDZtowf",
            "callValueInfo": [
                {
                    "callValue": 200000000
                }
            ],
            "note": "756e44656c65676174655265736f757263654f66456e65726779"
        }
    ]
}
  • internal_transactions.caller_address is the resource delegate address, that is, the contract address directly called by the external address
  • internal_transactions.transferTo_address is the resource receiving address, that is, to cancel the resource delegation of this address
  • internal_transactions.callValueInfo[0].callValue is the amount of TRX to undelegate (unit is sun)
  • internal_transactions.note is the instruction description, in this example it is unDelegateResourceOfEnergy, which means canceling the energy resource delegation. If the contract cancels the bandwidth resource delegation, the value of this field is unDelegateResourceOfBandwidth

8. Smart contract votes for super representatives

Here is an example, the transaction is an external address calling the "TNaDY...." contract, "TNaDY...." contract votes 200 and 400 for the super representatives "TUoHa...." and "TUznH...." respectively:

{
    "id": "58506325f692eee0bd730d97a0086f8b0c50e8aa5392b9e4b0edd5fb0916a718",
    ......
    "internal_transactions": [
        {
            "hash": "792b26cb6fbd1c92030721c62f7fd14522a94f412e04b05442d78e1ce743c9f4",
            "caller_address": "TNaDYZaXEpL1LY8Uk4LtGTwwQrGzXTwss9",
            "callValueInfo": [
                {}
            ],
            "note": "766f74655769746e657373",
            "extra": "{\"votes\":[{\"vote_address\":\"TUoHaVjx7n5xz8LwPRDckgFrDWhMhuSuJM\",\"vote_count\":200},{\"vote_address\":\"TUznHJfHe6gdYY7gvWmf6bNZHuPHDZtowf\",\"vote_count\":400}]}"
        }
    ],
    ......
}
  • internal_transactions.caller_address: this is the address voting for the super representative, that is, the contract address directly called by the external address
  • internal_transactions.transferTo_address: for contract voting transactions, the value of this field is empty, so this field is not displayed in the returned result
  • internal_transactions.callValueInfo: for contract voting transactions, the value of this field is an empty array
  • internal_transactions.note: this is the instruction description, in this case, it is voteWitness, which means the super representative voting operation
  • internal_transactions.extra: voting details, record the voting SR and its votes in JSON format: votes[i].vote_address is the SR address, votes[i].vote_count is the number of votes

9. Smart Contract Withdrawals Rewards

Here is an example, the transaction is an external address calling the "TNaDY...." contract, "TNaDY...." contract withdraws the reward of 443803418sun:

{
    "id": "8dc24b5ce1399b553cd173529e77b22172d9abf31e9f50dd32c473bcc5234b71",
    ......
    "internal_transactions": [
        {
            "hash": "e5b047a4a3d64407c93a9e667a083fe52c52b24e859e3a44488249436e79c8d4",
            "caller_address": "TNaDYZaXEpL1LY8Uk4LtGTwwQrGzXTwss9",
            "transferTo_address": "TNaDYZaXEpL1LY8Uk4LtGTwwQrGzXTwss9",
            "callValueInfo": [
                {
                    "callValue": 443803418
                }
            ],
            "note": "7769746864726177526577617264"
        }
    ]
}
  • internal_transactions.caller_address is the address for withdrawing rewards, that is, the contract address directly called by the external address
  • internal_transactions.transferTo_address is the address to receive the reward, that is, the contract address directly called by the external address
  • internal_transactions.callValueInfo[0].callValue is the withdrawn TRX reward amount, the unit is sun
  • internal_transactions.note is the instruction description, in this example it is withdrawReward, which means withdrawing the reward