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:
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.
grpc.trongrid.io:50051
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.
We need to prepare a TRON wallet. We can use OKX, imToken, etc., or generate one by ourselves.
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).
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.
We can use the platform’s debugging tools to test.
Debugging tool: https://www.fmz.com/m/debug
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.
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function toInnerAmount(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.
function base58ToHex(base58Str) {
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
var num = BigInt(0)
for (var char of base58Str) {
var digit = BigInt(ALPHABET.indexOf(char));
if (digit === BigInt(-1)) throw new Error("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:
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function toInnerAmount(n, decimals) {
return (BigDecimal(n) * BigDecimal(Math.pow(10, decimals))).toFixed(0)
}
function base58ToHex(base58Str) {
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
var num = BigInt(0)
for (var char of base58Str) {
var digit = BigInt(ALPHABET.indexOf(char));
if (digit === BigInt(-1)) throw new Error("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
}
function main() {
var tronAddress = "Tron wallet address"
var hexAddress = base58ToHex(tronAddress).substring(2, 44)
var jsonrpcBase = "https://go.getblock.io/xxx/jsonrpc" // Specific JSON-RPC nodes
var 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.result
return toAmount(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.
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.
Query wallet account information.
function main() {
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,
...
Check transfers.
function main() {
return exchange.IO("api", "tron", "GetTransactionInfoByID", "305f0c2487095effcf9e2db61f021f976707611424cba57e1d6464736f7f49e7")
}
Data returned:
{"id":{},"fee":1100000,"blockNumber":70192360,"blockTimeStamp":1741229766000,"contractResult":[{}],"receipt":{"net_fee":100000}}
Returns all node information.
function main() {
return exchange.IO("api", "tron", "ListNodes")
}
Query the accuracy information of TRC20 tokens.
function main() {
return exchange.IO("api", "tron", "TRC20GetDecimals", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t") // USDT
}
Query the balance of a certain TRC20 token in a certain wallet address.
function main() {
return exchange.IO("api", "tron", "TRC20ContractBalance", "TRX wallet address", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t")
}
Returns the latest block information on the current blockchain.
function main() {
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": {}
...
Query the bandwidth information of TRON account.
function main() {
return exchange.IO("api", "tron", "GetAccountNet", "TWTbnQuiWvEg...")
}
Data returned:
{
"freeNetLimit": 600,
"TotalNetLimit": 43200000000,
"TotalNetWeight": 26982826755
}
Create a Tron account.
function main() {
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
Get block information based on block height.
function main() {
return exchange.IO("api", "tron", "GetBlockByNum", 70227286)
}
Data returned:
{
"transactions": [
{
"transaction": {
"raw_data": {
"ref_block_bytes": {},
"ref_block_hash": {},
"expiration": 1741334628000,
"contract": [
...
TRC20GetName, query the TRC20 token name based on the contract address. TRC20GetSymbol, query the TRC20 token symbol based on the contract address.
function main() {
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
function main() {
// For example, the data in a transfer data is converted into a readable value
Log("ParseTRC20NumericProperty:", exchange.IO("api", "tron", "ParseTRC20NumericProperty", "0x00000000000000000000000000000000000000000000000000000001a13b8600")) // 7000000000
// For example, Data in a transfer data is converted into a readable string
Log("ParseTRC20StringProperty:", exchange.IO("api", "tron", "ParseTRC20StringProperty", "0x0000000000000000000000000000000000000000000000000000000055534454")) // USDT
}
To call the TRC20 contract, we use the balanceOf method of the TRC20 contract, first encode it, and then call it using TRC20Call.
function main() {
var data = exchange.IO("pack", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "balanceOf", "TWTbnQuiWvEg...")
var tx = exchange.IO("api", "tron", "TRC20Call", "TWTbnQuiWvEg...", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", data, true, 0)
return tx.constant_result
}
Constant methods do not need to be broadcast. The call result is recorded in tx.constant_result.
Construct a trans data.
function main() {
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
}
}
Get the contract ABI based on the contract address.
function main() {
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 1 TRX to the TKCG9FN1j...tron
wallet address.
function main() {
var ownerAddress = exchange.IO("address")
var ret = exchange.IO("api", "tron", "Transfer", ownerAddress, "TKCG9FN1j...", 1000000)
return ret
}
Call the method of the smart contract.
function main() {
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.
Call the smart contract method balanceOf
on the tron chain, TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
is the smart contract address of the USDT
token.
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function main() {
var balance = exchange.IO("api", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "balanceOf", "Tron wallet address")
return toAmount(balance, 6)
}
We can check the balance of USDT in the wallet is: 0.000019
The exchange.IO
function of the Web3 tron exchange object of the FMZ platform implements the following functions.
function main() {
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...
}
exchange.IO("base", "rpc address") // rpc address is replaced with the specific node address
// or
exchange.IO("rpc", "rpc address")
exchange.IO("abi", "contract ABI") // contract ABI is replaced with the specific contract ABI content
exchange.IO("address") // Return to tron wallet address
pack / encode : Encoding/packaging data, method calls.
function main() {
// Call the balanceOf method of the packaged TRC20 contract
var data1 = exchange.IO("pack", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "balanceOf", "TWTbnQu...") // TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t is the USDT contract address
Log(data1)
var data2 = exchange.IO("encode", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "balanceOf", "TWTbnQu...")
Log(data2)
Log("data1 == data2:", data1 == data2) // true
// Encoded data is uint256
var data3 = exchange.IO("pack", "uint256", 19) // Data: 19
Log(data3)
var data4 = exchange.IO("encode", "uint256", 19)
Log(data4)
Log("data3 == data4:", data3 == data4)
}
encodePacked : Encoding and packaging
function main() {
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 data, method calls.
function main() {
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)
// decoding
var usdtBalance = exchange.IO("decode", "uint256", ret)
Log("usdtBalance:", usdtBalance)
// decoding
return exchange.IO("unpack", "uint256", ret)
}
exchange.IO("key", "xxx") // xxx is the private key
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
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.
function main() {
var poolIndexs = exchange.IO("api", "TThJt8zaJzJMhCEScH7zWKnp5buVZqys9x", "allPoolsLength")
Log("poolIndexs:", poolIndexs) // Total number of trading pair indexes
var 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.
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.