# Exchange FAQ

# General information

# TOP Tokens

# 1. TOP Token

The smallest unit in TOP is Micro (uTOP).

  • 1 TOP = 10 ^ 6 Micro (uTOP)
  • Cent (cTOP): 1 Cent-top = 1/100 TOP, 1/hundred
  • Milli (mTOP): 1 Milli-top = 1/1000 TOP, 1/Thousand
  • Micro (μTOP): 1 Micro-TOP = 1/10^6 TOP, 1/Million

# 2. Total Circulation of TOP Token

The total circulation of TOP Token is 20 billion.

# Account and transaction

# 3. User account (address) and Table

  • The account model is used in TOP.
  • The TOP account address starts with T80000 and the format is T80000 + Ethereum format address.
  • Any account address is logically and fixedly mapped to one of the 64 tables according to calculating the Hash, and each table is similar to an independent sub-chain (also a logical shard).
  • Each table will package the transactions of the accounts under the table and generate blocks independently.
  • The 64 Table sub-chain addresses correspond to Ta0000@0 ~ Ta0000@63.
  • The numbers (IDs) of the 64 Table sub-chain are 0 ~ 63.

# 4. Format of account address

package org.topnetwork.account;

import java.io.IOException;

import org.topnetwork.account.property.AccountUtils;

import com.alibaba.fastjson.JSONObject;

/**
* Create offline account
*/
public class CreateOfflineAccount {

public static void main(String[] args) throws IOException {
  // 1. Randomly create offline address
  Account account=new Account();
  System.out.println("account > "+ JSONObject.toJSONString(account));
  System.out.println("privateKeyBytes > "+ account.getPrivateKeyBytes());

  // 2. Specify a certain table to create offline address, targetTableId[0,63]
  int targetTableId = 0;
  Account account1 = AccountUtils.genAccount(targetTableId);
  System.out.println("account1 > "+ JSONObject.toJSONString(account1));

  // 3. Create the address according to the privatekey
  String privateKey = "0x638785b5e9bb9271f031f6ef852e3d5f33b9f46bff6d920b8622d44e69d6666f";
  Account account2 = new Account("0x638785b5e9bb9271f031f6ef852e3d5f33b9f46bff6d920b8622d44e69d6666f");
  System.out.println("account2 > "+ JSONObject.toJSONString(account2));

  //4. Create the account according to privateKeyBytes
  byte[] privateKeyBytes = account2.getPrivateKeyBytes();
  Account account3 = new Account(account2.getPrivateKeyBytes());
  System.out.println("account3 >" + JSONObject.toJSONString(account3));
}
}

# 5. How to scan all the transactions of an account

You can firstly query the address of the Table sub-chain where the user account is located and the latest block height, then scan all the blocks under a specified Table sub-chain.

# 6. How to get the balance information of a user's account

package org.topnetwork.account;

import java.io.IOException;

import org.topnetwork.core.Topj;
import org.topnetwork.methods.response.AccountInfoResponse;
import org.topnetwork.methods.response.ResponseBase;
import org.topnetwork.procotol.http.HttpService;
import org.topnetwork.tx.PollingTransactionReceiptProcessor;

/**
 * Get the balance of s specified account
 */
public class GetAccountBalance {
    private static Topj topj =null;

    public static void main(String[] args) throws IOException {
        HttpService httpService = new HttpService("http://206.189.210.106:19081");
        topj = Topj.build(httpService);
        // If the request fails, it is called every 5 s, up to 3 times. It defaults to topj.setTransactionReceiptProcessor(new NoOpProcessor());
        topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
        // Query the balance of a specified address
        String address = "T80000f4d41bf4035e972649a8168ba06a15fa19a15ded";
        Account account=new Account();
        account.setAddress(address);
        topj.passport(account);
        ResponseBase<AccountInfoResponse> accountResult = topj.getAccount(account);
        System.out.println("account balance (utop) > "+accountResult.getData().getBalance());
    }

}

# 7. How to get the latest nonce of a user's account

package org.topnetwork.account;

import java.io.IOException;

import org.topnetwork.core.Topj;
import org.topnetwork.methods.response.AccountInfoResponse;
import org.topnetwork.methods.response.ResponseBase;
import org.topnetwork.procotol.http.HttpService;
import org.topnetwork.tx.PollingTransactionReceiptProcessor;

/**
 * Get the latest nonce of a specified account
 */
public class GetAccountNonce {
    private static Topj topj =null;

    public static void main(String[] args) throws IOException {
        HttpService httpService = new HttpService("http://206.189.210.106:19081");
        topj = Topj.build(httpService);
        // If the request fails, it is called every 5 s, up to 3 times. It defaults to topj.setTransactionReceiptProcessor(new NoOpProcessor());
        topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));

        // Query the account information of a specified address
        String address = "T80000f4d41bf4035e972649a8168ba06a15fa19a15ded";
        Account account=new Account();
        account.setAddress(address);
        topj.passport(account);
        ResponseBase<AccountInfoResponse> accountResult = topj.getAccount(account);
        System.out.println("account latest nonce > "+accountResult.getData().getNonce());
    }
}

# 8. How to query the corresponding Table block according to the transaction Hash

The self transaction is sent and received by the same address, so the self transaction has only one block, while the non-self transaction has 3 blocks per transaction.

  • send block corresponds to the block of sending the transaction.

  • recv block corresponds to the block of receiving the transaction.

  • confirm block corresponds to the block of confirming the transaction.

package org.topnetwork.block;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.topnetwork.account.Account;
import org.topnetwork.core.Topj;
import org.topnetwork.methods.response.ResponseBase;
import org.topnetwork.methods.response.block.TableBlockResponse;
import org.topnetwork.methods.response.tx.TxConsensusState;
import org.topnetwork.methods.response.tx.XTransactionResponse;
import org.topnetwork.procotol.http.HttpService;
import org.topnetwork.tx.PollingTransactionReceiptProcessor;

import java.io.IOException;

/**
 * How to query the corresponding Table block according to the transaction Hash
 */
public class GetTableBlockByTxHash {
    private static Topj topj =null;

    public static void main(String[] args) throws IOException {
        HttpService httpService = new HttpService("http://206.189.210.106:19081");
        topj = Topj.build(httpService);
        // If the request fails, it is called every 5 s, up to 3 times. It defaults to topj.setTransactionReceiptProcessor(new NoOpProcessor());
        topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));

        Account account=new Account();
        topj.passport(account);

        // Every normal transaction has 3 blocks
        String txHash = "0x052945e6f8f56bd9215e603aecde92a255ada57bd3d40cf662fc802805be406a";
        ResponseBase<XTransactionResponse> transactionResponseResponseBase = topj.getTransaction(account,txHash);
        System.out.println("transaction >> " + JSON.toJSONString(transactionResponseResponseBase));
        TxConsensusState state = transactionResponseResponseBase.getData().getTxConsensusState();
        // 1.send block
        ResponseBase<TableBlockResponse> sendTableIdBlock = topj.getTableBlockByHeight(account,state.getSendBlockInfo().getAccount(),state.getSendBlockInfo().getHeight().intValue());
        System.out.println("sendTableIdBlock info > "+ JSONObject.toJSONString(sendTableIdBlock));

        // 2.recv block
        ResponseBase<TableBlockResponse> recvTableIdBlock = topj.getTableBlockByHeight(account,state.getSendBlockInfo().getAccount(),state.getRecvBlockInfo().getHeight().intValue());
        System.out.println("recvTableIdBlock info > "+ JSONObject.toJSONString(recvTableIdBlock));

        // 3.confirm block
        ResponseBase<TableBlockResponse> confirmTableIdBlock = topj.getTableBlockByHeight(account,state.getSendBlockInfo().getAccount(),state.getConfirmBlockInfo().getHeight().intValue());
        System.out.println("confirmTableIdBlock info > "+ JSONObject.toJSONString(confirmTableIdBlock));
    }

}

# 9. How to send a transaction, and how to carry Memo information in the transaction

package org.topnetwork.transaction;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Map;

import org.topnetwork.account.Account;
import org.topnetwork.core.Topj;
import org.topnetwork.methods.Model.TransferParams;
import org.topnetwork.methods.request.Transfer;
import org.topnetwork.methods.response.AccountInfoResponse;
import org.topnetwork.methods.response.ResponseBase;
import org.topnetwork.methods.response.XTransaction;
import org.topnetwork.methods.response.tx.XTransactionResponse;
import org.topnetwork.procotol.http.HttpService;
import org.topnetwork.utils.ArgsUtils;

/**
 *  Connect to RPC to directly send a transaction
 */
public class SendTransaction {
    // Initialize communication protocol object according to the node address and ports, websocket is supported.
    private static HttpService httpService = new HttpService("http://206.189.210.106:19081");
    private static Topj topj = Topj.build(httpService);

    public static void main(String[] args) throws IOException {
        // 1. Build sending account
        Account sendAccount=new Account("0x638785b5e9bb9271f031f6ef852e3d5f33b9f46bff6d920b8622d44e69d6666f");
        topj.passport(sendAccount);
        ResponseBase<AccountInfoResponse> accountResult = topj.getAccount(sendAccount);
        System.out.println("Current account nonce > "+accountResult.getData().getBalance());
        System.out.println("Current account nonce > "+accountResult.getData().getNonce());
        // 2. Receiver address
        Account toAccount = new Account();

        // 3. Build parameters of sending transaction and signature information
        Transfer transfer = new Transfer();
        TransferParams transferParams = new TransferParams(toAccount.getAddress(), BigInteger.valueOf(1000000), "your note");

        // Method one of sending a transaction
        Map<String, String> requestTokenArgsMap = transfer.getArgs(sendAccount, Arrays.asList(transferParams));
        System.out.println("transaction body > "+requestTokenArgsMap);
        // 4. Send transaction
        ResponseBase<XTransactionResponse> result = httpService.send(requestTokenArgsMap, XTransactionResponse.class);
        XTransaction xTransaction = ArgsUtils.decodeXTransFromArgs(requestTokenArgsMap);
        XTransactionResponse xTransactionResponse = new XTransactionResponse();
        xTransactionResponse.setOriginalTxInfo(xTransaction);
        result.setData(xTransactionResponse);
        System.out.println(result.getData().getOriginalTxInfo().getTxHash());

        // Method two of sending a transaction
        ResponseBase<XTransactionResponse> result2 = topj.transfer(sendAccount,transferParams);
        System.out.println(result2.getData().getOriginalTxInfo().getTxHash());
    }

}

# 10. How to calculate the transaction fee

Transaction fee = used_deposit (send_block_info) + used_deposit (confirm_block_info) + tx_fee. Where:

  • used_deposit is the TOP that is deducted as a gas fee. When the free Tgas is sufficient, the value is 0.
  • For ordinary transactions, the used_deposit under send_block_info is deducted. For contract transactions, the used_deposit under confirm_block_info is deducted, see the following codes for reference.
  • tx_fee is a fixed fee for calling some system contract transactions (for example, 100 TOP fees will be deducted when registering a node). For ordinary transfer transactions, the value is 0.
{
    "data": {
        "original_tx_info": {
            "amount": 0,
            "authorization": "0x00da74315ede21da0ebc0ce4f8d1fb8409c978c74a0be4d7660410e3eae7ebcfa36f386bff302c3fd6c7c1be040076fe7f5cda50afc7f842aa71bf05d1a6feea02",
            "edge_nodeid": "",
            "ext": "",
            "last_tx_nonce": 0,
            "note": "",
            "premium_price": 0,
            "receiver_account": "T800002276a7d58218ac4978733e5cca927a7d86cb7c87",
            "receiver_action_name": "",
            "receiver_action_param": "0x2e00000054383030303033376434666263303862663435313361363861323837656432313862306164626434393765663330",
            "send_timestamp": 1631791128,
            "sender_account": "T8000037d4fbc08bf4513a68a287ed218b0adbd497ef30",
            "sender_action_name": "",
            "sender_action_param": "",
            "token_name": "",
            "tx_deposit": 100000,
            "tx_expire_duration": 100,
            "tx_hash": "0xfb33b056757f7d3ba6bccd0c8cd1a923a68dec1fd0c0633f513cee58214b648d",
            "tx_len": 189,
            "tx_structure_version": 2,
            "tx_type": 0
        },
        "tx_consensus_state": {
            "confirm_block_info": {
                "account": "Ta0000@39",
                "exec_status": "success",
                "height": 7,
                "recv_tx_exec_status": "success",
                "used_deposit": 0,
                "used_gas": 0
            },
            "recv_block_info": {
                "account": "Ta0000@55",
                "height": 7,
                "used_gas": 0
            },
            "send_block_info": {
                "account": "Ta0000@39",
                "height": 4,
                "tx_fee": 0,
                "used_deposit": 0,
                "used_gas": 468
            }
        },
        "tx_state" : "success"
    },
    "errmsg": "ok",
    "errno": 0,
    "sequence_id": "17"
}

# 11. (Advanced usage) How to make all created user addresses under the same Table sub-chain

package org.topnetwork.account;

import java.io.IOException;

import org.topnetwork.account.property.AccountUtils;

import com.alibaba.fastjson.JSONObject;

/**
 * Create offline account
 */
public class CreateOfflineAccount {

    public static void main(String[] args) throws IOException {
        
        // Specify a certain table to create offline address, targetTableId[0,63]
        int targetTableId = 0;
        Account account1 = AccountUtils.genAccount(targetTableId);
        System.out.println("account1 > "+ JSONObject.toJSONString(account1));
        
    }
}

# Table Chain

# 12. Query the address of the Table sub-chain where the user account is located and the latest block height

package org.topnetwork.account;

import java.io.IOException;

import org.topnetwork.account.property.AccountUtils;
import org.topnetwork.core.Topj;
import org.topnetwork.methods.response.AccountInfoResponse;
import org.topnetwork.methods.response.ResponseBase;
import org.topnetwork.methods.response.block.TableBlockResponse;
import org.topnetwork.procotol.http.HttpService;
import org.topnetwork.tx.PollingTransactionReceiptProcessor;

import com.alibaba.fastjson.JSONObject;

/**
 * Query the address of the Table sub-chain where the user account is located and the latest block height
 */
public class CheckAccount {
    private static Topj topj =null;

    public static void main(String[] args) throws IOException {
        HttpService httpService = new HttpService("http://206.189.210.106:19081");
        topj = Topj.build(httpService);
        // If the request fails, it is called every 5 s, up to 3 times. It defaults to topj.setTransactionReceiptProcessor(new NoOpProcessor());
        topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
     	// Get the table sub-chain ID corresponding to the specified address offline [0,63]
        int tableId = AccountUtils.getAddressTableId(account2.getAddress());
        System.out.println("tableId::"+tableId);

        // Query the latest block height of the account
        ResponseBase<TableBlockResponse> lastTableBlock = topj.getLastTableBlock(account2,account2.getAddress());
        System.out.println("Last Block info > "+ lastTableBlock.getData().getValue().getTableHeight());
    }

}

# 13. Query the height of a specified block under a specified Table sub-chain

package org.topnetwork.block;

import java.io.IOException;

import org.topnetwork.account.Account;
import org.topnetwork.account.property.AccountUtils;
import org.topnetwork.core.Topj;
import org.topnetwork.methods.response.ResponseBase;
import org.topnetwork.methods.response.block.TableBlockResponse;
import org.topnetwork.procotol.http.HttpService;
import org.topnetwork.tx.PollingTransactionReceiptProcessor;

import com.alibaba.fastjson.JSONObject;

/**
 * Query the block information of the subchain to which the specified account belongs
 */
public class GetTableBlockByHeight {
    private static Topj topj =null;

    public static void main(String[] args) throws IOException {
        HttpService httpService = new HttpService("http://206.189.210.106:19081");
        topj = Topj.build(httpService);
        // If the request fails, it is called every 5 s, up to 3 times. It defaults to topj.setTransactionReceiptProcessor(new NoOpProcessor());
        topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));

        int height = 67;// Specify the block height
        String address = "T80000f4d41bf4035e972649a8168ba06a15fa19a15ded";// Specify the address
        Account account=new Account();
        account.setAddress(address);
        topj.passport(account);
        // Specify the sub-chain address to which the account belongs
        String targetTableAccount = AccountUtils.getAddressTable(account.getAddress());
        // Query the the information of the specified block under the specified Table sub-chain
        ResponseBase<TableBlockResponse> subTableIdBlock = topj.getTableBlockByHeight(account, targetTableAccount,height);
        System.out.println("Block info > "+ JSONObject.toJSONString(subTableIdBlock));
    }

}

# 14. Scan the latest block under a specified Table sub-chain

package org.topnetwork.block;

import java.io.IOException;

import org.topnetwork.account.Account;
import org.topnetwork.account.property.AccountUtils;
import org.topnetwork.core.Topj;
import org.topnetwork.methods.response.ResponseBase;
import org.topnetwork.methods.response.block.TableBlockResponse;
import org.topnetwork.procotol.http.HttpService;
import org.topnetwork.tx.PollingTransactionReceiptProcessor;

import com.alibaba.fastjson.JSONObject;

/**
 * Query the information of the latest block under a specified Table sub-chain
 */
public class GetTableBlockByTableId {
    private static Topj topj =null;

    public static void main(String[] args) throws IOException {
        HttpService httpService = new HttpService("http://206.189.210.106:19081");
        topj = Topj.build(httpService);
        // If the request fails, it is called every 5 s, up to 3 times. It defaults to topj.setTransactionReceiptProcessor(new NoOpProcessor());
        topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));

        int height = 67;// Specify the block height
        String address = "T80000f4d41bf4035e972649a8168ba06a15fa19a15ded";// Specify the address
        Account account=new Account();
        account.setAddress(address);
        topj.passport(account);

        // Specify the sub-chain address where the account is located
        String targetTableAccount = AccountUtils.getAddressTable(account.getAddress());
        // Query the information of the latest block under a specified Table sub-chain
        ResponseBase<TableBlockResponse> subTableIdBlock = topj.getLastTableBlock(account, targetTableAccount);
        System.out.println("Block info > "+ JSONObject.toJSONString(subTableIdBlock));
    }

}

# 15. How to scan the blocks with a specified height in all Tables

Traverse Ta0000@0 ~ Ta0000@63 and scan the block with a height of 0 in each Table sub-chain.

package org.topnetwork.block;

import java.io.IOException;

import org.topnetwork.account.Account;
import org.topnetwork.account.property.AccountUtils;
import org.topnetwork.core.Topj;
import org.topnetwork.methods.response.ResponseBase;
import org.topnetwork.methods.response.block.TableBlockResponse;
import org.topnetwork.procotol.http.HttpService;
import org.topnetwork.tx.PollingTransactionReceiptProcessor;
import org.topnetwork.utils.TopjConfig;

import com.alibaba.fastjson.JSONObject;

/**
 * Scan the blocks of all sub-chains
 */
public class ScanAllTableBlock {

    private static Topj topj =null;

    public static void main(String[] args) throws IOException {
        HttpService httpService = new HttpService("http://206.189.210.106:19081");
        topj = Topj.build(httpService);
        // If the request fails, it is called every 5 s, up to 3 times. It defaults to topj.setTransactionReceiptProcessor(new NoOpProcessor());
        topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
        Account account=new Account();
        topj.passport(account);
        // Scan the information of the blocks under the specified sub-chain account, the height starts from 0
        // Scan all tabe sub-chains [0-63], you can start the thread on each sub-chain, the scan from height 0 to the latest height
        int height = 0;
        for (int i=0;i<64;i++){
            // Sub-chain address
            String targetTableAddress = TopjConfig.getShardingTableBlockAddr() + "@" + i;
            ResponseBase<TableBlockResponse> subTableIdBlock = topj.getTableBlockByHeight(account, targetTableAddress,height);
            System.out.println("Block info > table" +i +" >"+ JSONObject.toJSONString(subTableIdBlock));
        }
    }

}

# 16. How to query the latest heights of all Table sun-chains

package org.topnetwork.block;

import java.io.IOException;
import java.math.BigInteger;
import java.util.List;

import org.topnetwork.account.Account;
import org.topnetwork.core.Topj;
import org.topnetwork.methods.response.ResponseBase;
import org.topnetwork.procotol.http.HttpService;
import org.topnetwork.tx.PollingTransactionReceiptProcessor;

import com.alibaba.fastjson.JSON;

/**
 * How to query the latest heights of all Table sun-chains
 */
public class GetAllLastTableBlockHeight {
    private static Topj topj =null;

    public static void main(String[] args) throws IOException {
        HttpService httpService = new HttpService("http://206.189.210.106:19081");
        topj = Topj.build(httpService);
        topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
        // Create a random account
        Account firstAccount = new Account();
        // Set identityToken
        topj.passport(firstAccount);
        // Get the heights of 64 tables
        ResponseBase<List<BigInteger>> latestTables = topj.getLatestTables(firstAccount);
        System.out.println("latestTables info > " + JSON.toJSONString(latestTables.getData()));

    }

}

# Explorer

# 17. How to query account information from the TOP browser

Click here (opens new window) to go to TOPscan to query information.

# 18. How to query a transaction from the TOP browser

Click here (opens new window) to go to TOPscan to query transactions.