# 在交易所中添加 TOP
本文介绍如何在您的交易所中添加 TOP。
# 前置说明
关于分片:
- TOP 链有 64 个分片,每个分片叫做一个 Table,每个分片有一条的table链。
- 每个 Table 链有一个链地址,64 条 Table 链地的址范围为:Ta0000@0 - Ta0000@63,其中 0-63 也叫做 TableID。
- 账户地址和TABLE的映射关系。
- 账户地址平均映射到 64 个 Table 地址。
如何通过普通账号地址计算 TableID:
对普通账号地址(不带 @ 后缀)进行 hash64 计算
uint32_t account_index = get_index_from_account(account_addr); //hash whole account address
强制转换为uint16。
uint16_t ledger_sub_addr = (uint16_t)(account_index);
取模,强制转换为小于 64 的 TableID。
uint16_t tableID = (ledger_sub_addr &63);
说明:
hash64 使用的是 xxhash 开源库,C++ 版本,详情参见 GitHub (opens new window)。
关于交易:
- 交易分为 send 和 recv 两个阶段。
- send 阶段在交易的发送地址所在的 Table 分片上进行共识打包出块。
- recv 阶段在交易的接收地址所在的 Table 分片上进行共识打包出块。
# 搭建节点
建议您租用云服务器搭建节点,并在您的计算机上通过编译机(如 Xshell)远程访问该云服务器。
搭建节点主要分为以下几步:
# 1. 配置服务器
要搭建节点,首先需要创建一台用于运行 TOPIO 的服务器。
操作系统要求
运行环境操作系统要求:
操作系统 | 版本 |
---|---|
Linux | CentOS 7,64 位,内核 3.10 及以上版本(含 CentOS 8) |
Ubuntu 16.04,64 位,内核 4.4 及以上版本(含Ubuntu 22.04 LTS) |
源码编译节点程序操作系统要求:
操作系统 | 版本 |
---|---|
CentOS 7 | 64位 GCC4.8.5 |
服务器最低配置
对于交易所节点,最低配置如下:
节点类型 | 最低硬件配置 |
---|---|
交易所节点 | 2CPU/4GB mem 1TB SSD 200Mb/s |
编译环境准备
安装必要的软件包
命令:sudo yum install -y gcc-c++ git make which epel-release automake libgomp vim
安装CMake
- wget https://github.com/Kitware/CMake/releases/download/v3.24.3/cmake-3.24.3-linux-x86_64.sh
- chmod +x cmake-3.24.3-linux-x86_64.sh
- sudo ./cmake-3.24.3-linux-x86_64.sh --prefix=/usr --skip-license
安装Rust
curl https://sh.rustup.rs -sSf | sh
- 一路回车默认
source "$HOME/.cargo/env"
修改cargo配置文件
vim ~/.cargo/config.toml
[net] git-fetch-with-cli = true
Github设置
如果是全新的编译机器,需要生成可以访问Github的SSH key
ssh-keygen -t ed25519 -C "your_email@example.com"
将 ~/.ssh/id_ed25519.pub内容拷贝到Github SSH管理页面
# 2. 下载并编译代码
本节中的操作需在 Linux 的或其编译机(如 Xshell)中运行。
在编译机中执行以下命令将代码库克隆至本地。
git clone git@github.com:telosprotocol/TOP-chain.git
当前最新版本为 1.14.0,您也可以前往 TOP Chain GitHub 库 (opens new window),在页面右侧查看当前最新版本。
进入
TOP-chain/
目录,运行以下命令获取指定分支的 base。cd TOP-chain git submodule update --init --recursive
回到
TOP-chain
目录,运行以下命令进行编译。其中
noratelimit
用于关闭 RPC 流量控制,由于交易所节点查询较频繁,若存在流量控制会影响交易所节点的查询功能。sh build.sh release noratelimit
若执行成功,会生成如下文件:
cbuild_release/bin/Linux/topio
随后运行以下命令进行打包。
sh pack.sh release
若执行成功,会在
TOP-chain
目录下生成 TOPIO 安装包topio-1.14.0-release.tar.gz
。安装包的命名规则是topio-VERSION-release.tar.gz
。
# 3. 安装 TOPIO
说明:对于非 root 用户,需要先 添加管理员权限(root 用户无需添加)。
# 3.1 安装
在编译代码并生成 TOPIO 安装包后,运行以下命令安装 TOPIO。
tar zxvf topio-1.14.0-release.tar.gz && cd topio-1.14.0-release && sudo bash install.sh && source /etc/profile && bash set_topio.sh && source ~/.bashrc && ulimit -n 65535
# 3.2 验证是否安装成功
安装完成后,安装页面会打印以下信息:
install topio done, good luck
now run command to check md5: topio -v
now run command for help info: topio -h
此时执行 topio -v
来查看 TOPIO 版本信息,以验证 TOPIO 是否安装成功。
安装成功
如果输出 TOPIO 版本信息,证明安装成功。
topio version: 1.14.0
git commit info: d42d833c2
git submodule: xbase:4b3b8a4|xdepends/GSL:8e6d4e2|xdepends/boringssl:10fef972e|xdepends/googletest:ec44c6c1|xdepends/gperftools:bf8b714|xdepends/jemalloc:46c0af68|xdepends/libevent:5df3037d|xdepends/xquic:53a8708|
build date: Nov 17 2023 14:35:36
build options: release
MD5:47491e1e1e7d65b5335699b0ffda1121
注意
自己编译出来的可执行程序MD5和Github release页面中预编译好的节点客户端程序MD5会存在不一致的情况。但是务必确保git commit info以及submodule的commit信息和Github上的展示一致。
安装失败
如果输出以下信息,证明安装失败。
-bash: topio: 未找到命令
以上示例基于支持中文的 Linux 操作系统。
如安装失败,请重新执行安装命令。
# 3.3 配置环境变量(可选)
TOPIO 安装完成后,您可以执行以下命令配置环境变量,将以下命令中的 /opt/topnetwork
设置成您的权限目录。
echo "export TOPIO_HOME=/opt/topnetwork" >> ~/.bashrc && source ~/.bashrc
如不配置环境变量,您将使用系统默认目录作为 TOPIO 的工作目录:
- root 用户,默认目录为
/root/topnetwork
。 - 非 root 用户,默认目录为
/home/user/topnetwork
,其中user
是您登录服务器的用户名。
# 4. 注册节点与节点入网
# 4.1 创建账户
安装完 TOPIO 后,即可创建 TOP 账户。
在 TOPIO 中输入以下命令创建 TOP 账户(需要设置密码):
topio wallet createAccount
创建成功后,系统会返回您的账户地址以及公钥;公钥信息页可以从Keystore中找到。
Account Address: T800003126428b8a65aaad2e08ecbe4bd4a345645c8676
Owner public-Key: BBMZFRt4fcuJwuDwAmy8apKa9ru6n1ov8gCRghDwe3+23E+/oGGh1CliyiSAJOnUy0SBV6m5Klw4AWR53B4ap/U=
重要:
新创建的账户均为未激活状态,需要至少 0.1 TOP 方可激活,请联系工作人员为您转入 TOP。
账户余额大于 100 TOP 时可享受每日免费 gas,此时的链上操作均不收取 gas 费;余额少于 100 TOP 时,链上操作会消耗您的 TOP 余额。
# 4.2 注册节点
创建账户后,还需要设置默认账号,才能注册节点。在设置默认账号的过程中,需要交互式输入密码。
topio wallet setDefaultAccount Your_Account_Address
请记得为账号获取适量 TOP 后,才可注册节点。
在TOPIO中,所有注册节点的命令都归属在mining registerMiner类别。所以,注册交易所节点的命令如下:
topio mining registerMiner 0 exchange miner_name --miner_key Your_Miner_Public_Key
其中:
0
为所需保证金(TOP)数量,交易所节点所需的 TOP 为 0。exchange
为交易所节点。miner_name
为节点名,可自定义,4-16字符,支持字母、数字或下划线。Your_Miner_Public_Key
为Miner key公钥
如返回以下信息,证明节点注册成功。
Successfully registering to the mining pool.
# 4.3 节点入网
节点注册成功后,还需要设置Miner key(需要交互式需求密码)。
topio mining setMinerKey Your_Miner_Public_Key
完成设置后需要启动节点进程,让节点加入TOP AI Network网络。
执行以下命令启动节点进程:
topio node startNode
若返回以下信息,则成功启动节点进程。
Start node successfully.
查询是否入网
您可执行以下命令查询节点是否成功加入网络。
topio node isJoined
- 若返回
topio not ready
,说明 TOPIO 暂未准备好,请等待一分钟后再次运行命令重试。 - 若返回
YES
,则节点成功入网,进入节点候选池,等待选举。 - 返回
No
,则节点入网失败,可能因为网络故障,网络抖动。
# 升级节点
若 TOPIO 发布新版本,您需要升级至最新版 TOPIO。
运行以下命令结束旧版 TOPIO 进程。
ps -ef |grep topio|grep -v 'grep'|awk '{print $2}'|xargs kill -9
重新执行 搭建节点 中的的下载、编译代码、安装 TOPIO 的步骤。
安装成功后,执行
topio node startNode
重新启动节点即可。升完级后,CPU 占用率会达到 100% 并持续一段时间,导致在 TOPIO 中输入命令时发生卡顿,此时可稍等片刻再进行尝试。
# RPC API
您可 点击此处 查看 TOP AI Network 所有 RPC API 信息。
交易所节点主要通过以下 RPC API 与链进行互动:
# 查询交易信息
可根据指定的交易 hash,查询该交易的情信息。
请求方法
getTransaction
详情参见 查询账户交易信息。
# 查询区块信息
可根据账户地址及区块高度查询区块信息。
请求方法
getBlock
详情参见 查询区块信息。
# 查询最新区块高度
可查询 256 个 shard table 的高度。
请求方法
getLatestTables
详情参见 查询块高度。
# 发送交易
支持发送交易,包括转账、节点staking、节点注册、节点投票、节点领取奖励、调用合约等。
请求方式
sendTransaction
详情参见 发送交易。
# SDK
您可 点击此处 查看 TOP AI Network 所有 Java SDK。
常用 SDK 代码示例如下:
# 获取用户地址下的余额
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;
/**
* 获取指定帐户余额
*/
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);
// 请求失败每 5s 循环调用,最多 3 次 默认 topj.setTransactionReceiptProcessor(new NoOpProcessor());
topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
// 查询指定地址的帐户余额
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());
}
}
# 获取用户账户下的最新 nonce
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;
/**
* 获取指定帐户最新 nonce
*/
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);
// 请求失败每 5s 循环调用,最多 3 次 默认 topj.setTransactionReceiptProcessor(new NoOpProcessor());
topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
// 查询指定地址的帐户信息
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());
}
}
# 如何通过交易 Hash 查询对应的 Table 块
Self 交易为发送和接受均为自己的地址,所以 self 交易只有一个块,而非 self 交易每笔交易有 3 个块。
send block 对应发送交易的块。
recv block 对应接收交易的块。
confirm block 对应确认交易的块。
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;
/**
* 如何通过交易 Hash 查询对应的 Table 块
*/
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);
// 请求失败每 5s 循环调用,最多 3 次 默认 topj.setTransactionReceiptProcessor(new NoOpProcessor());
topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
Account account=new Account();
topj.passport(account);
// 正常发送交易每笔交易会有 3 个块
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));
}
}
# 如何计算交易手续费
交易手续费 = used_deposit
(send_block_info
) + used_deposit
(confirm_block_info
) + tx_fee
。其中:
used_deposit
是作为手续费而被扣除的 TOP,当免费的 Tgas 充足时,该值为 0。- 对于普通交易,扣除的是
send_block_info
下的used_deposit
;对于合约交易,扣除的是confirm_block_info
下的used_deposit
,详见下方代码示例。 tx_fee
是一部分系统合约交易的固定手续费(例如在注册节点时会扣除 100 TOP 手续费),对于普通转账交易,该值为 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"
}
# 查询用户账户所在的 Table 子链地址以及最新块高
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;
/**
* 查询用户账号所在的 Table 子链地址,以及最新块高
*/
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);
// 请求失败每 5s 循环调用,最多 3 次 默认 topj.setTransactionReceiptProcessor(new NoOpProcessor());
topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
// 离线获取指定地址对应的 table 子链 id[0,63]
int tableId = AccountUtils.getAddressTableId(account2.getAddress());
System.out.println("tableId::"+tableId);
// 查询帐户最新块高
ResponseBase<TableBlockResponse> lastTableBlock = topj.getLastTableBlock(account2,account2.getAddress());
System.out.println("Last Block info > "+ lastTableBlock.getData().getValue().getTableHeight());
}
}
# 查询指定 Table 子链下指定块高
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;
/**
* 查询指定帐户所属子链的块信息
*/
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);
// 请求失败每 5s 循环调用,最多 3 次 默认 topj.setTransactionReceiptProcessor(new NoOpProcessor());
topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
int height = 67;// 指定块高
String address = "T80000f4d41bf4035e972649a8168ba06a15fa19a15ded";//指定地址
Account account=new Account();
account.setAddress(address);
topj.passport(account);
// 指定帐户所在的子链地址
String targetTableAccount = AccountUtils.getAddressTable(account.getAddress());
// 查询指定 Table 子链下指定块高的块信息
ResponseBase<TableBlockResponse> subTableIdBlock = topj.getTableBlockByHeight(account, targetTableAccount,height);
System.out.println("Block info > "+ JSONObject.toJSONString(subTableIdBlock));
}
}
# 扫描指定 Table 子链下的最新块
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;
/**
* 查询指定 Table 子链最新的块信息
*/
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);
// 请求失败每 5s 循环调用,最多 3 次 默认 topj.setTransactionReceiptProcessor(new NoOpProcessor());
topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
int height = 67;// 指定块高
String address = "T80000f4d41bf4035e972649a8168ba06a15fa19a15ded";//指定地址
Account account=new Account();
account.setAddress(address);
topj.passport(account);
// 指定帐户所在的子链地址
String targetTableAccount = AccountUtils.getAddressTable(account.getAddress());
// 查询指定 Table 子链最新的块信息
ResponseBase<TableBlockResponse> subTableIdBlock = topj.getLastTableBlock(account, targetTableAccount);
System.out.println("Block info > "+ JSONObject.toJSONString(subTableIdBlock));
}
}
# 扫描所有的 Table 下指定高度的块
遍历 Ta0000@0 ~ Ta0000@63,扫描每一个 Table 子链中高度为 0 的块。
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;
/**
* 扫描所有子链的块
*/
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);
// 请求失败每 5s 循环调用,最多 3 次 默认 topj.setTransactionReceiptProcessor(new NoOpProcessor());
topj.setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(5000, 3));
Account account=new Account();
topj.passport(account);
// 扫描指定子链帐户下的块信息,height 从 0 开始 ,
// 扫描所有的 tabe 子链 [0-63],可以选择每个子链开启线程 height 从 0 开始扫描,最终到 latest height
int height = 0;
for (int i=0;i<64;i++){
// 子链地址
String targetTableAddress = TopjConfig.getShardingTableBlockAddr() + "@" + i;
ResponseBase<TableBlockResponse> subTableIdBlock = topj.getTableBlockByHeight(account, targetTableAddress,height);
System.out.println("Block info > table" +i +" >"+ JSONObject.toJSONString(subTableIdBlock));
}
}
}
# 查询所有 Table 子链的最新高度
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;
/**
* 如何查询所有 Table 子链的最新高度
*/
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));
// 构建随机帐户
Account firstAccount = new Account();
// 设置 identityToken
topj.passport(firstAccount);
// 获取 64 个 table 的最新高度
ResponseBase<List<BigInteger>> latestTables = topj.getLatestTables(firstAccount);
System.out.println("latestTables info > " + JSON.toJSONString(latestTables.getData()));
}
}
# FAQ
更多接入相关问题或代码示例,可查看 交易所 FAQ。