Preface

The development of blockchain technology is driving quantitative trading into the Web3 era. As a leading quantitative trading tool, FMZ Quant Trading Platform has long been exploring the Web3 direction and has provided Ethereum-related functions, enabling users to interact with smart contracts, manage funds, and execute automated trading strategies on the chain directly.

At present, the FMZ platform has further expanded its Web3 trading capabilities and supports the Tron (TRX) network, allowing users to deploy quantitative trading strategies on the two major public chains of Ethereum and Tron. This upgrade not only improves the flexibility of cross-chain transactions, but also provides traders with more possibilities for on-chain asset management.

In this article, we will cover in detail:

  • Discuss the Tron ecology, applications, development and other technical contents in the Web3 direction of the FMZ platform.
  • Practice the configuration based on the Tron network on the FMZ platform.
  • Resources and materials used in practice.
  • Practice calling methods on Tron nodes.
  • SunSwap, a DeFi practice based on the Tron ecosystem.

Introduction to Tron

Tron Introduction Details (Quoted from: https://www.feixiaohao.com/)

TRON was founded by Justin Sun in September 2017 and has achieved many outstanding achievements since its mainnet launch in May 2018. In July 2018, the TRON ecosystem completed its integration with BitTorrent, a pioneer in providing decentralized Web 3.0 services with more than 100 million monthly active users. In recent years, the TRON network has performed well. According to TRONSCAN data, as of October 2022, the total number of TRON public chain users exceeded 115 million, the number of transactions exceeded 4 billion, and the total value locked (TVL) exceeded US$13.2 billion. The TRON network was fully decentralized in December 2021 and is now a decentralized autonomous organization (DAO) governed by the community. In May 2022, TRON announced the launch of the decentralized super-collateralized stablecoin USDD, which is backed by the industry's cryptocurrency central bank TRON Joint Reserve, marking the official entry of TRON into the era of decentralized stablecoins. In October 2022, Dominica announced that TRON was its officially designated national blockchain infrastructure, and TRON has thus become a large public chain that has reached a cooperation with a sovereign state to develop blockchain infrastructure. TRON was authorized to issue Dominica's fan token, Dominica Coin (DMC), to enhance the global visibility of Dominica's natural heritage and tourist attractions. At the same time, TRON's seven major tokens were granted the status of legal digital currency and legal tender in Dominica.

  • High throughput: High throughput is achieved by improving TPS in TRON, and its practicality for daily use has surpassed Bitcoin and Ethereum.
  • Scalability: Based on good scalability and efficient smart contracts, applications can have more deployment methods in TRON, and TRON can support a large number of users.
  • High reliability: TRON has a more reliable network structure, user assets, intrinsic value, and a higher degree of decentralized consensus brings an improved reward distribution mechanism.

Resources and Materials Used in Practice

  • TRON mainnet official grpc node

grpc.trongrid.io:50051

  • Other nodes:

We can use JSON-RPC nodes, REST nodes, etc. from other node providers (we can use HttpQuery to request). The only call for the exchange object encapsulation on FMZ is the grpc method.

  • TRON Wallet

We need to prepare a TRON wallet. We can use OKX, imToken, etc., or generate one by ourselves.

  • tronscan

https://tronscan.org

  • Tron protocol

https://github.com/tronprotocol

  • SunSwap

https://sun.io/?lang=zh-CN#/v3/swap

https://github.com/sunswapteam

Configure WEB3 Exchange Objects on FMZ

Before FMZ platform supported Tron, it had already taken the lead in supporting Ethereum's Web3 development. You can review previous articles to learn how to access the UniSwap decentralized exchange. Since Tron is compatible with Ethereum and combines some features of ETH and EOS, it has unique advantages in smart contract execution and on-chain interaction. Configuring Tron exchange objects (wallets, node information) on the FMZ platform is almost the same as configuring Ethereum exchange objects (wallets, node information).

Add Exchange Object

On the Add platform page:

https://www.fmz.com/m/platforms/add

Configure the wallet, select TRON as ChainType, and use the default RPC node address.

Common JSON-RPC Node Method Practices

We can use the platform's debugging tools to test.

Debugging tool: https://www.fmz.com/m/debug

eth_getBalance

As the name suggests, this method is exactly the same as the Ethereum method, and its function is exactly the same. This method is used to read the TRX balance in the specified Tron wallet.

curl https://docs-demo.tron-mainnet.quiknode.pro/jsonrpc \
  -X POST \
  -H"Content-Type: application/json" \
  --data '{"method":"eth_getBalance","params":["0x41f0cc5a2a84cd0f68ed1667070934542d673acbd8", "latest"],"id":1,"jsonrpc":"2.0"}'

The balance data requested is a very large hexadecimal value, which requires the conversion function we used in the previous Ethereum-related strategy.

functiontoAmount(s, decimals) {
    returnNumber((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}

functiontoInnerAmount(n, decimals) {
    return (BigDecimal(n) * BigDecimal(Math.pow(10, decimals))).toFixed(0)
}

Since the wallet address copied from the Tron wallet is a base58-encoded address, it needs to be converted to a hex-encoded parameter before it can be used.

functionbase58ToHex(base58Str) {
    constALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"var num = BigInt(0)
    for (var char of base58Str) {
        var digit = BigInt(ALPHABET.indexOf(char));
        if (digit === BigInt(-1)) thrownewError("Invalid Base58 character: " + char)
        num = num * BigInt(58) + digit
    }

    var hex = num.toString(16)
    
    if (hex.length % 2 !== 0) {
        hex = "0" + hex
    }

    return"0x" + hex
}

After we convert the address, we can call the eth_getBalance method.

Complete test code:

functiontoAmount(s, decimals) {
    returnNumber((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}

functiontoInnerAmount(n, decimals) {
    return (BigDecimal(n) * BigDecimal(Math.pow(10, decimals))).toFixed(0)
}

functionbase58ToHex(base58Str) {
    constALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"var num = BigInt(0)
    for (var char of base58Str) {
        var digit = BigInt(ALPHABET.indexOf(char));
        if (digit === BigInt(-1)) thrownewError("Invalid Base58 character: " + char)
        num = num * BigInt(58) + digit
    }

    var hex = num.toString(16)
    
    if (hex.length % 2 !== 0) {
        hex = "0" + hex
    }

    return"0x" + hex
}

functionmain() {
    var tronAddress = "Tron wallet address"var hexAddress = base58ToHex(tronAddress).substring(2, 44)

    var jsonrpcBase = "https://go.getblock.io/xxx/jsonrpc"// Specific JSON-RPC nodesvar body = {
        "method": "eth_getBalance",
        "params": [hexAddress, "latest"],
        "id":1,
        "jsonrpc":"2.0"
    }

    var options = {
        method: "POST",
        body: JSON.stringify(body),
        headers: {"accept": "application/json", "content-type": "application/json"},
        timeout: 1000
    }

    var ret = JSON.parse(HttpQuery(jsonrpcBase, options))
    var balance = ret.resultreturntoAmount(balance, 6)
}

TRX token precision is 6, so fill in parameter 6 when processing bigNumber.

Test in the debugging tool of the FMZ platform, the function result is 72.767348

Comparing the TRX balance in the wallet queried on tronscan, the data is consistent.

gRPC Node Method Practice

The main practice content on the FMZ platform is the method call of the grpc node. Due to limited space, only the commonly used method calls are listed here.

Call prototype: exchange.IO("api", "tron", "method name", ...). "method name" is the name of the method to be called.

GetAccount

Query wallet account information.

functionmain() {
    var account = exchange.IO("api", "tron", "GetAccount", "tron wallet address")  // tron wallet address: fill in the actual wallet address.return account
}

Return call information (excerpt):

{
    "address": {},
    "balance": 72767348,   // That is, the TRX balance of the wallet: 72.767348"asset_optimized": true,
    "create_time": 1693463943000,
    ...

GetTransactionInfoByID

Check transfers.

functionmain() {
    return exchange.IO("api", "tron", "GetTransactionInfoByID", "305f0c2487095effcf9e2db61f021f976707611424cba57e1d6464736f7f49e7") 
}

Data returned:

{"id":{},"fee":1100000,"blockNumber":70192360,"blockTimeStamp":1741229766000,"contractResult":[{}],"receipt":{"net_fee":100000}}

ListNodes

Returns all node information.

functionmain() {
    return exchange.IO("api", "tron", "ListNodes")
}

TRC20GetDecimals

Query the accuracy information of TRC20 tokens.

functionmain() {
    return exchange.IO("api", "tron", "TRC20GetDecimals", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t")  // USDT
}

TRC20ContractBalance

Query the balance of a certain TRC20 token in a certain wallet address.

functionmain() {
    return exchange.IO("api", "tron", "TRC20ContractBalance", "TRX wallet address", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t")
}

GetNowBlock

Returns the latest block information on the current blockchain.

functionmain() {
    return exchange.IO("api", "tron", "GetNowBlock")
}

Data returned:

{
    "transactions": [
        {
            "transaction": {
                "raw_data": {
                    "ref_block_bytes": {},
                    "ref_block_hash": {},
                    "expiration": 1741489083000,
                    "contract": [
                        {
                            "type": 1,
                            "parameter": {
                                "type_url": "type.googleapis.com/protocol.TransferContract",
                                "value": {}
                                ...

GetAccountNet

Query the bandwidth information of TRON account.

functionmain() {
    return exchange.IO("api", "tron", "GetAccountNet", "TWTbnQuiWvEg...")
}

Data returned:

{
    "freeNetLimit": 600,
    "TotalNetLimit": 43200000000,
    "TotalNetWeight": 26982826755
}

CreateAccount

Create a Tron account.

functionmain() {
    return exchange.IO("api", "tron", "CreateAccount", "TWTbnQ...", "TKCG9...")
}

Trying to create an existing account will return an error:

Futures_OP 4: Contract validate error : Account has existed

GetBlockByNum

Get block information based on block height.

functionmain() {
    return exchange.IO("api", "tron", "GetBlockByNum", 70227286)
}

Data returned:

{
    "transactions": [
        {
            "transaction": {
                "raw_data": {
                    "ref_block_bytes": {},
                    "ref_block_hash": {},
                    "expiration": 1741334628000,
                    "contract": [
                    ...

TRC20GetName / TRC20GetSymbol

TRC20GetName, query the TRC20 token name based on the contract address.
TRC20GetSymbol, query the TRC20 token symbol based on the contract address.

functionmain() {
    Log("TRC20GetName:", exchange.IO("api", "tron", "TRC20GetName", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"))
    Log("TRC20GetSymbol:", exchange.IO("api", "tron", "TRC20GetSymbol", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"))
}

Data returned:

2025-03-09 11:18:43.083		info TRC20GetSymbol: USDT
2025-03-09 11:18:43.006		info TRC20GetName: Tether USD

ParseTRC20...

functionmain() {
    // For example, the data in a transfer data is converted into a readable valueLog("ParseTRC20NumericProperty:", exchange.IO("api", "tron", "ParseTRC20NumericProperty", "0x00000000000000000000000000000000000000000000000000000001a13b8600"))  // 7000000000// For example, Data in a transfer data is converted into a readable stringLog("ParseTRC20StringProperty:", exchange.IO("api", "tron", "ParseTRC20StringProperty", "0x0000000000000000000000000000000000000000000000000000000055534454"))    // USDT
}

TRC20Call

To call the TRC20 contract, we use the balanceOf method of the TRC20 contract, first encode it, and then call it using TRC20Call.

functionmain() {
    var data = exchange.IO("pack", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "balanceOf", "TWTbnQuiWvEg...")
    var tx = exchange.IO("api", "tron", "TRC20Call", "TWTbnQuiWvEg...", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", data, true, 0)
    return tx.constant_result
}
  • "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" : The contract address of TRC20 USDT.
  • "TWTbnQuiWvEg..." : Parameter, the TRX wallet address of the balance requested by the balanceOf method.
  • "balanceOf" : The name of the method that needs to be encoded.

Constant methods do not need to be broadcast. The call result is recorded in tx.constant_result.

Transfer

Construct a trans data.

functionmain() {
    var trans = exchange.IO("api", "tron", "Transfer", "TWTb...", "TKCG9FN...", 1000000)
    return trans
}
  • TWTb... : The address of TRX wallet A.
  • TKCG9FN... : The address of TRX wallet B.
  • 1000000 : Transfer 1TRX.

Data returned:

{
    "transaction": {
        "raw_data": {
            "ref_block_bytes": {},
            "ref_block_hash": {},
            "expiration": 1741493085000,
            "contract": [
                {
                    "type": 1,
                    "parameter": {
                        "type_url": "type.googleapis.com/protocol.TransferContract",
                        "value": {}
                    }
                }
            ],
            "timestamp": 1741493025759
        }
    },
    "txid": {},
    "result": {
        "result": true
    }
}

GetContractABI

Get the contract ABI based on the contract address.

functionmain() {
    var usdtABI = exchange.IO("api", "tron", "GetContractABI", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t")
    return usdtABI
}

Data returned:

{
    "entrys": [
        {
            "constant": true,
            "name": "name",
            "outputs": [
                {
                    "type": "string"
                }
            ],
            "type": 2,
            "stateMutability": 2
        },
        {
            "constant": true,
            "name": "deprecated",
            "outputs": [
                {
                    "type": "bool"
                }
            ],
            "type": 2,
            "stateMutability": 2
        },
        ...

Transfer

Transfer 1 TRX to the TKCG9FN1j...tron wallet address.

functionmain() {
    var ownerAddress = exchange.IO("address")
    var ret = exchange.IO("api", "tron", "Transfer", ownerAddress, "TKCG9FN1j...", 1000000)     
    return ret
}

TriggerConstantContract

Call the method of the smart contract.

functionmain() {
    var tx = exchange.IO("api", "tron", "TriggerConstantContract", "TWTbnQu...", "TSUUVjysXV8YqHytSNjfkNXnnB49QDvZpx", "token0()", "")
    var ret2 = Encode("raw", "raw", "hex", tx.constant_result[0])
    Log(ret2) // 000000000000000000000000891cdb91d149f23b1a45d9c5ca78a88d0cb44c18
}

The returned data is the token0 token address of the sunSwap trading pool.

Smart contract method call

  • Check USDT balance

Call the smart contract method balanceOf on the tron ​​chain, TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t is the smart contract address of the USDT token.

functiontoAmount(s, decimals) {
    returnNumber((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}

functionmain() {
    var balance = exchange.IO("api", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "balanceOf", "Tron wallet address")
    returntoAmount(balance, 6)
}

We can check the balance of USDT in the wallet is: 0.000019

Other Functions of exchange.IO

The exchange.IO function of the Web3 tron exchange object of the FMZ platform implements the following functions.

  • TRX transfer
functionmain() {
    var ret = exchange.IO("api", "tron", "send", "target TRX wallet address", 1)  // Note that parameter 1 represents 0.000001 TRX and needs to be converted to an on-chain value.return ret   // Transfer hash: 305f0c2487095effcf9e2db61f021f9767076114...
}
  • Switch node address
exchange.IO("base", "rpc address")  // rpc address is replaced with the specific node address// or
exchange.IO("rpc", "rpc address")
  • Register smart contract ABI
exchange.IO("abi", "contract ABI")  // contract ABI is replaced with the specific contract ABI content
  • Get the address of the wallet bound to the current exchange object
exchange.IO("address")  // Return to tron ​​wallet address
  • pack / encode / encodePacked

pack / encode : Encoding/packaging data, method calls.

functionmain() {
    // Call the balanceOf method of the packaged TRC20 contractvar data1 = exchange.IO("pack", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "balanceOf", "TWTbnQu...")  // TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t is the USDT contract addressLog(data1)
    var data2 = exchange.IO("encode", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "balanceOf", "TWTbnQu...")
    Log(data2)
    Log("data1 == data2:", data1 == data2)  // true// Encoded data is uint256var data3 = exchange.IO("pack", "uint256", 19)   // Data: 19Log(data3)
    var data4 = exchange.IO("encode", "uint256", 19)
    Log(data4)
    Log("data3 == data4:", data3 == data4)
}

encodePacked : Encoding and packaging

functionmain() {
    var data1 = exchange.IO("encodePacked", "address", "TWTbnQu...")
    Log(data1)
    //                          e0c12e16a9f713e5f104c...var data2 = exchange.IO("encode", "address", "TWTbnQu...")
    Log(data2)
    // 000000000000000000000000 e0c12e16a9f713e5f104c...
}
  • unpack / decode

unpack / decode : Unpack/decode data, method calls.

functionmain() {
    var data = exchange.IO("pack", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "balanceOf", "TWTbnQu...")
    Log(data)
    var tx = exchange.IO("api", "tron", "TRC20Call", "TWTbnQu...", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", data, true, 0)
    var ret = Encode("raw", "raw", "hex", tx.constant_result[0])
    Log(ret)

    // decodingvar usdtBalance = exchange.IO("decode", "uint256", ret)
    Log("usdtBalance:", usdtBalance)

    // decodingreturn exchange.IO("unpack", "uint256", ret)
}
  • Update/Import private key
exchange.IO("key", "xxx")  // xxx is the private key
  • Calculating hash
    Calling prototype: exchange.IO("hash", algo, inputFormat, outputFormat, data)

Sign with the currently configured private key and return the signed data.

var signature = exchange.IO("hash", "sign", "string", "hex", "txHash")  // txHash: specific hash value

A First Look at SunSwap

Initial practice on the DEX exchange on the Tron chain: sunSwap. We call the factory contract of sunSwap, request the indexes of all trading pairs, and then request the address of the trading pair with index 1.

functionmain() {
    var poolIndexs = exchange.IO("api", "TThJt8zaJzJMhCEScH7zWKnp5buVZqys9x", "allPoolsLength")
    Log("poolIndexs:", poolIndexs)  // Total number of trading pair indexesvar hexAddress = exchange.IO("api", "TThJt8zaJzJMhCEScH7zWKnp5buVZqys9x", "allPools", exchange.IO("encode", "uint256", 1)) 
    Log("hexAddress:", hexAddress)  // The trading pair address with index 1
}

Due to limited space, we will share the detailed sunSwap content with readers in the next article. Thank you for your support.

THE END

FMZ Quant Trading Platform continues to innovate in the Web3 era, providing quantitative traders with a broader on-chain trading space. By supporting the Tron network, FMZ not only enhances cross-chain trading capabilities, but also enables users to execute smart contract interactions, fund management, and automated trading strategies in the Tron ecosystem efficiently.

In this article, we introduced the FMZ platform's support for the Tron network and implemented the contract method call of SunSwap DEX on the Tron chain. With the development of blockchain technology, the possibilities of Web3 quantitative trading will continue to expand. FMZ will continue to optimize and improve its Web3 capabilities, provide quantitative traders with a more flexible, secure, and efficient trading environment, and help users gain greater advantages in the on-chain market.

Thank you for reading and thank you for your support.

From: FMZ Quant Web3 Expansion: Tron Support Added, Expand On-chain Tradings

Leave a Reply

Your email address will not be published. Required fields are marked *