当前位置: 代码网 > it编程>编程语言>Java > Java实现Tron(波场)区块链的开发实践(二)交易监控与转账

Java实现Tron(波场)区块链的开发实践(二)交易监控与转账

2024年08月01日 Java 我要评论
上一节我们具体讲到Java实现Tron波场链的开发部署:通过trident源码编译组件,使用RPC的方式链接Tron波场链,并进行了代码实现,还有如何创建离线钱包。-- 交易监控说白话就是在链接波场链的同时,监控波场链上的交易信息,再把这些交易信息检索和反编码,获取到真实TRX和TRC20所需交易。之所以交易监控放在最后,是因为本人在交易监控上做了很多很多的尝试,最后找到了JAVA实现自认为是最好的实例。-- 不变的是,监控一定以及肯定的是将监控到最后一个块的交易,也就是链上最后一笔交易。

上一节我们具体讲到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如何获取

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com