赞
踩
上一节我们具体讲到Java实现Tron波场链的开发部署:通过trident源码编译组件,使用RPC的方式链接Tron波场链,并进行了代码实现,还有如何创建离线钱包。
这一节我们通过部署好的项目环境,具体如何使用代码来实现波场链的交易监控和交易转账.
1. 所有的开端就是获取链的接通(ApiWrapper)
-
- private ApiWrapper getApiWrapper(String hexPrivateKey) {
- //配置是否是测试链还是正式链
- if (tronServiceConfig.getTronDomainOnline()) {
- // 正式环境需要到Tron申请一个apiKey进行使用
- // APIKEY获取往后会讲如何获取
- return ApiWrapper.ofMainnet(hexPrivateKey, tronServiceConfig.getApiKey());
- } else {
- // 测试环境不需要apikey
- return new ApiWrapper("grpc.nile.trongrid.io:50051", "grpc.nile.trongrid.io:50061", hexPrivateKey);
- }
- }
2. 查看Trc20(如USDT)余额
-
- /**
- * TRC20余额
- * @param address 我的钱包地址
- * @return 余额
- */
- public BigDecimal getTrc20Balance(String address) {
- ApiWrapper client = getApiWrapper(tronServiceConfig.getHexPrivateKey());
- // Trc20合约地址
- Contract contract = client.getContract(tronServiceConfig.getTrc20Address());
- Trc20Contract token = new Trc20Contract(contract, address, client);
- BigInteger balanceOf = token.balanceOf(address);
- BigDecimal divisor = new BigDecimal(tronServiceConfig.getTrc20Decimals());
- BigDecimal divide = new BigDecimal(balanceOf).divide(divisor, 4, RoundingMode.HALF_UP);
- client.close();
- return divide;
- }
3. 查看Trx余额
- /**
- * TRx余额
- * @param address
- * @return
- */
- @Override
- public BigDecimal getTRxBalance(String address) {
- ApiWrapper wrapper = getApiWrapper(tronServiceConfig.getHexPrivateKey());
- Long balance = wrapper.getAccountBalance(address);
- BigDecimal divisor = new BigDecimal(tronServiceConfig.getTrc20Decimals());
- BigDecimal divide = new BigDecimal(balance).divide(divisor, 4, RoundingMode.HALF_UP);
- wrapper.close();
- return divide;
- }
4. Trc20转账实现
- /**
- * TRC20 转账
- * @param fromAddress
- * @param toAddress
- * @param amount
- * @return
- */
- @Override
- public String transTrc20(String fromAddress, String toAddress, String amount) {
- try {
- ApiWrapper client = getApiWrapper(tronServiceConfig.getHexPrivateKey());
- // 获取合约地址信息
- Contract contract = client.getContract(tronServiceConfig.getTrc20Address());
- Trc20Contract token = new Trc20Contract(contract, fromAddress, client);
- String transfer;
- // 获取转账账户的TRX余额
- BigInteger trc20Value = token.balanceOf(fromAddress);
- // 获取想要转账的数额
- BigInteger sunAmountValue = Convert.toSun(amount, Convert.Unit.TRX).toBigInteger();
- // 进行比较
- if (trc20Value.compareTo(sunAmountValue) >= 0) {
- log.info("开始转账.........");
- // 设置最大矿工费用
- long feeLimit = Convert.toSun("100", Convert.Unit.TRX).longValue();
- //转账
- transfer = token.transfer(toAddress, sunAmountValue.longValue(), 0, "转账", feeLimit);
- } else {
- return "error_error";
- }
- if (StrUtil.isEmpty(transfer)) {
- return "error_error";
- }
- log.info("交易ID:{}", transfer);
- client.close();
- return transfer;
- } catch (Exception ex) {
- String message = ex.getMessage();
- return "error_" + message;
- }
- }
5. TRX转账
- /**
- * TRX转账
- * @param fromAddress 输入地址
- * @param toAddress 转账地址
- * @param amount 金额
- * @return
- */
- @Override
- public String transferTRX(String fromAddress, String toAddress, int amount) {
- ApiWrapper wrapper = getApiWrapper(tronServiceConfig.getHexPrivateKey());
- try {
- BigDecimal divisor = new BigDecimal(tronServiceConfig.getTrc20Decimals());
- Long rechangeAmount = new BigDecimal(String.valueOf(amount)).multiply(divisor).longValue();
- // 创建交易
- Response.TransactionExtention transaction = wrapper.transfer(fromAddress, toAddress, rechangeAmount);
- log.info("transaction:{}", transaction);
- log.info("transaction.Txid:{}", transaction.getTxid());
- // 签名交易
- Chain.Transaction signTransaction = wrapper.signTransaction(transaction);
- log.info("signTransaction:{}", signTransaction);
- // 计算交易所需要的宽带
- long byteSize = wrapper.estimateBandwidth(signTransaction);
- log.info("byteSize:{}", byteSize);
- // 广播交易
- String hashTx = wrapper.broadcastTransaction(signTransaction);
- log.info("hashTRX:{}", hashTx);
- return hashTx;
- } catch (Exception e) {
- log.error("TransactionService#transfer error: {}", e.getMessage());
- }
- wrapper.close();
- return null;
- }
6. 交易监控
之所以交易监控放在最后,是因为本人在交易监控上做了很多很多的尝试,最后找到了JAVA实现自认为是最好的实例。
-- 交易监控说白话就是在链接波场链的同时,监控波场链上的交易信息,再把这些交易信息检索和反编码,获取到真实TRX和TRC20所需交易。
-- 不管怎么做,首先的想法就是要获取当前交易到的区块,或者自己想要从哪个区块高度进行开始交易监控
-- 不变的是,监控一定以及肯定的是将监控到最后一个块的交易,也就是链上最后一笔交易
- // 获取目前最高交易块
- Long number = wrapper.getNowBlock().getBlockHeader().getRawData().getNumber();
-- 为了避免程序抖动或者检索交易错误,我采取交易块区间式的检索 --
也就是一次监控,监控的事一个块区间而不是一个最新块。
- // BLOCKS_20 后退区间高度数
- Response.BlockListExtention blockByLimitNext = wrapper.getBlockByLimitNext(endNum - BLOCKS_20, endNum);
- // 区间块列表
- List<Response.BlockExtention> blockList = blockByLimitNext.getBlockList();
- for (Response.BlockExtention blockExtention : blockList) {
- Long trc20_target_block_number = blockExtention.getBlockHeader().getRawData().getNumber();
- RedissonUtils.setBucket("EXCHANGE_LISTENER:TRC20", DateUtil.formatDateTime(new Date()) + " 区块高度:" + current_sync_block_number + " 扫描高度:" + trc20_target_block_number);
- // 处理块信息
- switchDataTransaction(blockExtention);
- }
- /**
- * 检索块信息,获取交易信息
- * @param blockExtention
- * @throws Throwable
- */
- public void switchDataTransaction(Response.BlockExtention blockExtention) throws Throwable {
- List<Response.TransactionExtention> transactionsList = blockExtention.getTransactionsList();
- for (Response.TransactionExtention transactionExtention : transactionsList) {
- List<Chain.Transaction.Contract> contractList = transactionExtention.getTransaction().getRawData().getContractList();
- for (Chain.Transaction.Contract contract : contractList) {
- Class a = Class.forName("org.tron.trident.proto.Contract$" + contract.getType());
- Message unpack = contract.getParameter().unpack(a);
- // TriggerSmartContract是合约, 按照不同的交易类型检索
- if (unpack instanceof Contract.TriggerSmartContract) {
- // 合约地址
- Contract.TriggerSmartContract contractStr = (Contract.TriggerSmartContract) unpack;
- ByteString contractAddress = contractStr.getContractAddress();
- String hex = ApiWrapper.toHex(contractAddress);
- String contractAddressStr = TronUtils.toViewAddress(hex);
- // 判断是否是自己需要监控的合约地址
- if (tronServiceConfig.getTrc20Address().equalsIgnoreCase(contractAddressStr)) {
- ByteString ownerAddress = contractStr.getOwnerAddress();
- String hex2 = ApiWrapper.toHex(ownerAddress);
- String fromAddress = TronUtils.toViewAddress(hex2);
- ByteString data = contractStr.getData();
- String hex1 = ApiWrapper.toHex(data);
- // 交易类型是转账
- String transferFunction = Hex.toHexString(new Keccak.Digest256().digest("transfer(address,uint256)".getBytes())).substring(0, 8);
- String funcId = hex1.substring(0, 8);
- if (!transferFunction.equals(funcId)) {
- continue;
- }
- String toAddress = hex1.substring(32, 72);
- String amount = hex1.substring(72, 136);
- try {
- Address address = (Address) TypeDecoder.instantiateType("address", toAddress);
- // 地址
- NumericType amountType = (NumericType) TypeDecoder.instantiateType("uint256", amount);
- // 金额
- BigDecimal trc20Decimals = new BigDecimal(tronServiceConfig.getTrc20Decimals());
- BigDecimal amountee = new BigDecimal(amountType.getValue()).divide(trc20Decimals, 6, RoundingMode.FLOOR);
-
- byte[] byteArray = transactionExtention.getTransaction().getRawData().toByteArray();
- byte[] bytes = Hash.sha256(byteArray);
- String txId = Hex.toHexString(bytes);
- // 后续处理
- // trc20.exchangeService.triggerSmartContract(address.getValue(), amountee, txId);
- } catch (Exception e) {
- log.error("TRON监控报错", e);
- continue;
- }
- }
- }
- }
- }
- }
监控通知定时循环任务发起,注意循环任务的发起
下一节:Tron波场链水龙头、web3、apikey如何获取
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。