TRON Developer Guide — TRC10 & TRX Transfer in Exchanges

TRON DAO
6 min readMay 14, 2019

--

Introduction

Detecting a TRX or TRC10 transaction in TRON involves 4 types of contracts:

  • TransferContract (System Contract Type)
  • TransferAssetContract (System Contract Type)
  • CreateSmartContract(Smart Contract Type)
  • TriggerSmartContract(Smart Contract Type)

The data for Transaction, TransactionInfo, and Block contain all the smart contract transaction information.

Detecting and Recording Transfers

The two contracts TransferContract and TransferAssetContract are system contracts used to transfer TRX and TRC10, respectively. A transaction contains only one contract, so the query transaction obtains specific information about a contract, using the interface GetTransactionbyId. Use GetBlockByNum to retrieve the block information of the packaged transactions. Either travel the Block or use GetTransactionInfoById to obtain specific transaction information. Check the root Transaction result. If Transaction.Result.code is Failed, reject this transaction. No transferring happened. Otherwise, check type in Transaction.raw to get contract type information (TransferContract or TransferAssetContract). Check parameter in Transaction.raw to get contract details according to type.

TransferContract

  • owner_address (Bytes) is the TRX sender address. Need to convert Bytes to a base58Check String to show readable TRON address.
  • to_address (Bytes) is the TRX receiver address. Need to convert Bytes to a base58Check String.
  • amount (int64) is the TRX amount sent to the contract address.

TransferAssetContract

  • asset_name (String) is the TRC10 ID. There is no need for conversion to show readable TRON address. (This parameter is used to represent the name of the TRC10 token. After the TRON Improvement Proposal #14 passed to allow for same name tokens, this has been modified to TRC10 ID).
  • owner_address (Bytes) is the TRC10 sender address. Need to convert Bytes to a base58Check String to show a readable TRON address.
  • to_address (Bytes) is the TRC10 receiver address. Need to convert Bytes to a base58Check String to show a readable TRON address.
  • amount (int64) is the TRC10 amount sent to the contract address.

Detection for CreateSmartContract and TriggerSmartContract is similar. Use GetBlockByNum to retrieve the block information of the packaged transactions. Either travel the Block or use GetTransactionInfoById to obtain specific transaction information. Check the root Transaction result. If Transaction.Result.code is FAILED, reject this transaction. No transferring happened. Otherwise, check type in Transaction.raw to get contract type information (CreateSmartContract or TriggerSmartContract). Check parameter in Transaction.raw to get contract details according to type.

CreateSmartContract

  • owner_address (Bytes) is the TRX or TRC10 sender address. Need to convert Bytes to a base58Check String to show a readable TRON address.
  • SmartContract.contract_address (Bytes) is the TRX or TRC10 receiver's address and it MUST BE a smart contract address. Due to the creation in runtime, you cannot retrieve it from the Transaction. Instead, use GetTransactionInfoById to obtain contract_address in TransactionInfo. The data needs to be converted from Bytes to a base58Check String to show a readable TRON address.
  • SmartContract.call_value (int64) is the TRX amount sent to the contract address.
  • call_token_value (int64) is the TRC10 amount sent to the contract address.
  • token_id (String) is the related TRC10 ID. There is no need for conversion to show a readable TRON address.

TriggerSmartContract

  • owner_address (Bytes) is the TRX or TRC10 sender address. The address needs to be converted from Bytes to a base58Check String to show a readable TRON address.
  • contract_address (Bytes) is the TRX or TRC10 receiver's address and it MUST BE a smart contract address. The address needs to be converted from Bytes to a base58Check String to show a readable TRON address.
  • call_value (int64) is the TRX amount sent to the contract address.
  • call_token_value (int64) is the TRC10 amount sent to the contract address.
  • token_id (String) is the related TRC10 ID.

Check Transfer in InternalTransaction

  • caller_address (Bytes) is the TRX or TRC10 token sender address. Bytes should be converted to a base58Check String to show a readable TRON address.
  • transferTo_address (Bytes) is the TRX or TRC10 token receiver address. Bytes should be converted to a base58Check String to show a readable TRON address.
  • CallValueInfo is a list of transfer details.
  • callvalue (int64) represents the TRX amount if tokenId is empty. Otherwise, it is the token transfer value.
  • tokenId (String) is the token identifier. rejected represents whether this internal transaction is failed and rejected. If rejected is true, there is no need to deal with the current internal transaction, since some error occurred. Otherwise, a value of false signifies a successful transaction.

Related Protobuf

TransferContract

message TransferContract {
bytes owner_address = 1;
bytes to_address = 2;
int64 amount = 3;
}

TransferAssetContract

message TransferAssetContract {
bytes asset_name = 1; // this field is token name before the proposal ALLOW_SAME_TOKEN_NAME is active, otherwise it is token id and token is should be in string format.
bytes owner_address = 2;
bytes to_address = 3;
int64 amount = 4;
}

CreateSmartContract

message CreateSmartContract {
bytes owner_address = 1;
SmartContract new_contract = 2;
int64 call_token_value = 3;
int64 token_id = 4;
}

TriggerSmartContract

message TriggerSmartContract {
bytes owner_address = 1;
bytes contract_address = 2;
int64 call_value = 3;
bytes data = 4;
int64 call_token_value = 5;
int64 token_id = 6;
}

Transaction

message Transaction {
message Contract {
enum ContractType {
AccountCreateContract = 0;
TransferContract = 1;
TransferAssetContract = 2;
VoteAssetContract = 3;
VoteWitnessContract = 4;
WitnessCreateContract = 5;
AssetIssueContract = 6;
WitnessUpdateContract = 8;
ParticipateAssetIssueContract = 9;
AccountUpdateContract = 10;
FreezeBalanceContract = 11;
UnfreezeBalanceContract = 12;
WithdrawBalanceContract = 13;
UnfreezeAssetContract = 14;
UpdateAssetContract = 15;
ProposalCreateContract = 16;
ProposalApproveContract = 17;
ProposalDeleteContract = 18;
SetAccountIdContract = 19;
CustomContract = 20;
// BuyStorageContract = 21;
// BuyStorageBytesContract = 22;
// SellStorageContract = 23;
CreateSmartContract = 30;
TriggerSmartContract = 31;
GetContract = 32;
UpdateSettingContract = 33;
ExchangeCreateContract = 41;
ExchangeInjectContract = 42;
ExchangeWithdrawContract = 43;
ExchangeTransactionContract = 44;
UpdateEnergyLimitContract = 45;
AccountPermissionUpdateContract = 46;
PermissionAddKeyContract = 47;
PermissionUpdateKeyContract = 48;
PermissionDeleteKeyContract = 49;
}
ContractType type = 1;
google.protobuf.Any parameter = 2;
bytes provider = 3;
bytes ContractName = 4;
}
message Result {
enum code {
SUCESS = 0;
FAILED = 1;
}
enum contractResult {
DEFAULT = 0;
SUCCESS = 1;
REVERT = 2;
BAD_JUMP_DESTINATION = 3;
OUT_OF_MEMORY = 4;
PRECOMPILED_CONTRACT = 5;
STACK_TOO_SMALL = 6;
STACK_TOO_LARGE = 7;
ILLEGAL_OPERATION = 8;
STACK_OVERFLOW = 9;
OUT_OF_ENERGY = 10;
OUT_OF_TIME = 11;
JVM_STACK_OVER_FLOW = 12;
UNKNOWN = 13;
}
int64 fee = 1;
code ret = 2;
contractResult contractRet = 3;
string assetIssueID = 14;
int64 withdraw_amount = 15;
int64 unfreeze_amount = 16;
int64 exchange_received_amount = 18;
int64 exchange_inject_another_amount = 19;
int64 exchange_withdraw_another_amount = 20;
int64 exchange_id = 21;
}
message raw {
bytes ref_block_bytes = 1;
int64 ref_block_num = 3;
bytes ref_block_hash = 4;
int64 expiration = 8;
repeated authority auths = 9;
// data not used
bytes data = 10;
//only support size = 1, repeated list here for extension
repeated Contract contract = 11;
// scripts not used
bytes scripts = 12;
int64 timestamp = 14;
int64 fee_limit = 18;
}
raw raw_data = 1;
// only support size = 1, repeated list here for muti-sig extension
repeated bytes signature = 2;
repeated Result ret = 5;
}

TransactionInfo

message TransactionInfo {
enum code {
SUCESS = 0;
FAILED = 1;
}
message Log {
bytes address = 1;
repeated bytes topics = 2;
bytes data = 3;
}
bytes id = 1;
int64 fee = 2;
int64 blockNumber = 3;
int64 blockTimeStamp = 4;
repeated bytes contractResult = 5;
bytes contract_address = 6;
ResourceReceipt receipt = 7;
repeated Log log = 8;
code result = 9;
bytes resMessage = 10;
string assetIssueID = 14;
int64 withdraw_amount = 15;
int64 unfreeze_amount = 16;
repeated InternalTransaction internal_transactions = 17;
int64 exchange_received_amount = 18;
int64 exchange_inject_another_amount = 19;
int64 exchange_withdraw_another_amount = 20;
int64 exchange_id = 21;
}

Block

message Block {
repeated Transaction transactions = 1;
BlockHeader block_header = 2;
}

--

--

TRON DAO
TRON DAO

Written by TRON DAO

The official Medium of TRON DAO.

No responses yet