Omni扫块,和非原生归集

1 篇文章 0 订阅
1 篇文章 0 订阅

Omni扫块流程

首先需要拿到当前USDT高度(也可以去TokenView去查
通过grpc也好,封装的api也可以,我这里是通过client的方式

 currentHeigth = omniCoreClient.currentBlockHeight();

每次扫完要把当前高度存到数据库中,下次从DB中的高度继续扫描(这里我防止意外情况,又引入了Redis存放高度,每次扫先和DB的比较谁高用谁)

log.info("当前最新高度:{}",currentHeigth);
               log.info("DB中上次高度:{}",index);
               //这个标志位是为了跳出下面while用的
               boolean flag = true;
               Integer block = (Integer) redisTemplate.opsForValue().get("IN_BLOCK");
               if(block != null){
                   if(block > index){
                       log.info("redis中高度大 使用{}",block);
                       index = block;
                   }else{
                       log.info("数据库中高度大 使用{}",index);
                   }
               }else{
                   log.info("数据库中高度大 使用{}",index);
               }

然后就是扫块的方法

while (flag && index <= currentHeigth.intValue()-1){
                   List<Sha256Hash> sha256Hashes = omniCoreClient.getOmniClient().omniListBlockTransactions(index);
                   for (Sha256Hash txid : sha256Hashes) {
                       LinkedHashMap jsonObject = omniCoreClient.getOmniClient().send("omni_gettransaction",txid.toString().trim());
                       if(jsonObject==null){
                           continue;
                       }
                       if(jsonObject.get("propertyid")==null || !jsonObject.get("propertyid").equals(31)){
                           log.info("非USDT交易跳过 {}",txid.toString());
                           continue;
                       }
                       if(!(boolean)jsonObject.get("valid")){
                           log.info("并不是有效数据跳过 {}",txid.toString());
                           continue;
                       }
                       if((int)jsonObject.get("confirmations") <= 1 ){
                           flag = false;
                           log.info("确认数小于2 不增加高度等待下次扫描 {}",txid.toString());
                           break;
                       }
                       }}

每次要从DB或Redis的最新高度-1开始扫,也就是最低多扫两个高度。
解释一下上面为什么要确认小于2的跳过,因为如果确认只有1的话会有一定几率被退回,这样的话钱已经转入了,数据库的记录也有了,但是实际上钱并没有打进来,被退回了

jsonObject.get("referenceaddress")

接下来就可以去拿数据库中的地址去和扫到的地址比对,如果相同的,并且事务ID没有被记录过就开始自己的业务逻辑(加钱,插入记录等)

由于每次index会从-1开始扫,有概率会重复扫到,只凭地址是无法判断是否扫过了,这个时候就需要事务ID来记录(txid,hex)

if(index == currentHeigth.intValue()){
                    redisTemplate.opsForValue().set("BLOCK_HEIGHT",index-1);
                    operationExtendMapper.updateDbIndex(String.valueOf(index-1));
                    log.info("更新到高度{}",index-1);
                }else{
                    redisTemplate.opsForValue().set("BLOCK_HEIGHT",index);
                    operationExtendMapper.updateDbIndex(String.valueOf(index));
                    log.info("更新到高度{}",index);
                }

上面的全部结束之后就可以更新本次的高度了.

归集

由于这个API受到限制所以绝大部分都使用原生归集(下次说)
本次使用的归集方法是omni_funded_send方式,这个方法本身是有问题的,为什么这么说,看一下api的介绍

omni_funded_send
omni_funded_send调用创建并发送一个简单充值交易。

发送方发出的所有比特币都将被消耗掉,如果比特币来自指定的手续费 来源,那么找零将返回该来源地址。

没错,它每次都会把BTC耗空,也就是说用户连续充值多次,只有一次能够被归集成功,,其他的几次归集会全部失败,因为没有账户btc。
如果是每次都单笔充值的情况是没问题的,也不需要打0.00000546,用户充值会带进来一笔,并且需要一个代扣手续费的地址,这个地址一定要有足够的BTC

下面方法设置本次手续费(这个可以通过其他方式获取到全网平均手续费,太少了到账慢,太多了浪费)

omniClient.setTxFee();

接下来就等待归集完成,如果记录够全面的话,就可以连续查询到两笔转账记录,从外面转入内部地址,从内部地址转入(冷,热地址)汇集地址。

一般这个扫块作为定时服务存在程序里面,我设置是5分钟,你也可以设置其他时间,USDT每天会平均生成80个高度,每个高度150-1000+的交易记录,建议每次扫到就进行逻辑处理,不需要加事务,每次扫的速度取决于链上的交易笔数,越多则越慢

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值