Omni wallet钱包Java调用

下载最新的客户端 http://www.omnilayer.org/download.html


/**
 * usdt操作
 * @create 2017/10/27
 **/
@Service
public class CoinUsdtService {

    private String mainAddress = "n2qnt1Qr3N5amBx4WvfcALf4nTb3Qj6WhQ";
    private String url = "http://127.0.0.1:18332";
    private String username = "u";
    private String password = "p";
    //正式网络usdt=31,测试网络可以用2
    private static final int propertyid = 31;
    private static final int SKIP_COUNT = 100;

    private Logger log = Log.get();

    private final static String RESULT = "result";
    private final static String METHOD_SEND_TO_ADDRESS = "omni_send";
    //可以指定手续费地址
    private final static String METHOD_OMNI_FUNDED_SEND = "omni_funded_send";
    private final static String METHOD_GET_TRANSACTION = "omni_gettransaction";
    private final static String METHOD_GET_BLOCK_COUNT = "getblockcount";
    private final static String METHOD_NEW_ADDRESS = "getnewaddress";
    private final static String METHOD_GET_BALANCE = "omni_getbalance";
    private final static String METHOD_GET_LISTBLOCKTRANSACTIONS = "omni_listblocktransactions";
    private final static String METHOD_GET_LISTTRANSACTIONS = "omni_listtransactions";
    
    //前四个参数在USDT钱包conf文件中设置
    //钱包密码PASSWORD打开钱包后设置的密码

    /***
     * 取得钱包相关信息
     * 若获取失败,result为空,error信息为错误信息的编码
     * */
    public JSONObject getInfo() throws Exception {
        return doRequest("omni_getinfo");
    }
    
    /**
     * USDT产生地址
     * @return
     */
    public String getNewAddress(){
        JSONObject json = doRequest(METHOD_NEW_ADDRESS);
        if(isError(json)){
            log.error("获取USDT地址失败:{}",json.get("error"));
            return "";
        }
        return json.getString(RESULT);
    }

    /**
     * USDT查询余额
     * @return
     */
    public double getBalance(){
        JSONObject json = doRequest(METHOD_GET_BALANCE,mainAddress,propertyid);
        if(isError(json)){
            log.error("获取USDT余额:{}",json.get("error"));
            return 0;
        }
        return json.getJSONObject(RESULT).getDouble("balance");
    }

    /**
     * USDT转帐
     * @param toAddr
     * @param value
     * @return
     */
    public String send(String toAddr,double value){
        if(vailedAddress(toAddr)){
            JSONObject json = doRequest(METHOD_SEND_TO_ADDRESS,mainAddress,toAddr,propertyid,value);
            if(isError(json)){
                log.error("USDT 转帐给{} value:{}  失败 :",toAddr,amt,json.get("error"));
                return "";
            }else{
                log.info("USDT 转币给{} value:{} 成功",toAddr,value);
                return json.getString(RESULT);
            }
        }else{
            log.error("USDT接受地址不正确");
            return "";
        }
    }

    /**
     * 验证地址的有效性
     * @param address
     * @return
     * @throws Exception
     */
    public boolean vailedAddress(String address) {
        JSONObject json  = doRequest("validateaddress",address);
        if(isError(json)){
            log.error("USDT验证地址失败:",json.get("error"));
            return false;
        }else{
            return json.getJSONObject(RESULT).getBoolean("isvalid");
        }
    }

    /**
     * 区块高度
     * @return
     */
    public int getBlockCount(){
        JSONObject json = null;
        try {
            json = doRequest(METHOD_GET_BLOCK_COUNT);
            if(!isError(json)){
                return json.getInteger("result");
            }else{
                log.error(json.toString());
                return 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**************************第一种方式*********start******************/

    /**
     * 扫描区块数据
     **/
    public boolean parseBlock(int index) {
        //doRequest("omni_listblocktransactions",279007);
        //{"result":["63d7e22de0cf4c0b7fd60b4b2c9f4b4b781f7fdb8be4bcaed870a8b407b90cf1","6fb25ab84189d136b95d7f733b0659fa5fbd63f476fb1bca340fb4f93de6c912","d54213046d8be80c44258230dd3689da11fdcda5b167f7d10c4f169bd23d1c01"],"id":"1521454868826"}
        JSONObject jsonBlock = doRequest(METHOD_GET_LISTBLOCKTRANSACTIONS, index);
        if (isError(jsonBlock)) {
            log.error("访问USDT出错");
            return false;
        }
        JSONArray jsonArrayTx = jsonBlock.getJSONArray(RESULT);
        if (jsonArrayTx == null || jsonArrayTx.size() == 0) {
            //没有交易
            return true;
        }
        Iterator<Object> iteratorTxs = jsonArrayTx.iterator();
        while(iteratorTxs.hasNext()){
            String txid = (String) iteratorTxs.next();
            if (!parseTx(txid,null)) {
                return false;
            }
        }
        return true;
    }
    /**
     * 过滤数据
     * @param txid
     * @param userList 用户地址列表
     * @return
     */
    public boolean parseTx(String txid,List<UserCoinAddressEntity> userList){
        /**
         *{"result":{"amount":"50.00000000","divisible":true,"fee":"0.00000257",
         *"txid":"f76d51044f156e6ed84c11e6531db1d6d70799196522c07bd2a8870a21f90220","ismine":true,
         *"type":"Simple Send","confirmations":565,"version":0,"sendingaddress":"mh8tV2mfDa6yHK76t68N3paoGdSmangJDi",
         *"valid":true,"blockhash":"000000000000014cdef6ee8a095b58755efebf913b1ab13bb23adaa33b6f7b05",
         *"blocktime":1523528971,"positioninblock":189,"referenceaddress":"mg5yVUSwGNEJNhYKfyETV2udWok6Q4pgLx",
         *"block":1292526,"propertyid":2,"type_int":0},"id":"1523860978684"}
         */
        JSONObject jsonTransaction = doRequest(METHOD_GET_TRANSACTION, txid);
        if(isError(jsonTransaction)) {
            log.error("处理USDT tx出错");
            return true;
        }
        JSONObject jsonTResult = jsonTransaction.getJSONObject(RESULT);
        if (!jsonTResult.getBoolean("valid")) {
            log.info("不是有效数据");
            return true;
        }
        int propertyidResult = jsonTResult.getIntValue("propertyid");
        if (propertyidResult!=propertyid) {
            log.info("非USDT数据");
            return true;
        }
        int coinfirm = jsonTResult.getIntValue("confirmations");
        if (coinfirm <= 0) {
            log.info("交易未确认,txid:{}",txid);
            return false;
        }
        double value = jsonTResult.getDouble("amount");
        if(value >0) {
            String address = jsonTResult.getString("referenceaddress");
            for (UserCoinAddressEntity addressModel : userList) {
                //如果有地址是分配给用记的地址, 则说明用户在充值
                if (address.equals(addressModel.getAddress())) {
                    //添加充值记录
                    log.info("添加用户充值记录");
                    //归集
                    collUsdt(address,value);
                    return true;
                }
            }
        }
        return false;
    }

    /**************************第一种方式*********end******************/


    /**********推荐****************第二种方式*********start******************/

    public int parseBlockCount(int block,int skip){
        //omni_listtransactions "*" 1000(最多显示几条数据) 0(跳过几条事务) 543530(开始搜索块高度) 543530(结束搜索块高度)  详细描述请参考https://blog.csdn.net/wm609972715/article/details/82891064

        JSONObject jsonResult = doRequest(METHOD_GET_LISTTRANSACTIONS,"*",SKIP_COUNT,skip,block,block);
        if (isError(jsonResult)) {
            log.error("访问USDT出错");
            return -1;
        }
        JSONArray jsonArrayTx = jsonResult.getJSONArray(RESULT);
        //获取用户分配地址列表。请根据自己系统来!
        List<UserCoinAddressEntity> userList = userCoinService.getAllUserCoinAddress(CoinConstant.COIN_USDT);
        if(userList == null || userList.size() == 0){
            return 0;
        }
        Iterator<Object> iteratorTxs = jsonArrayTx.iterator();
        while(iteratorTxs.hasNext()){
            JSONObject tx = (JSONObject) iteratorTxs.next();
            if (!parseTx(tx,userList)) {
                return -1;
            }
        }
        return jsonArrayTx.size();
    }

    public boolean parseBlock(int index) {
        int skip = 0;
        do{
            int res = parseBlockCount(index,skip);
            if(res<0){
                return false;
            }
            if(res<SKIP_COUNT){
                return true;
            }
            skip = skip +100;
        }while(true);
        
        
    }


    /**
     * 过滤数据
     * @param userList 用户地址列表
     * @return
     */
    public boolean parseTx(JSONObject jsonTResult,List<UserCoinAddressEntity> userList){
        
        if (!jsonTResult.getBoolean("valid")) {
            log.info("不是有效数据");
            return true;
        }

        int propertyidResult = jsonTResult.getIntValue("propertyid");
        if (propertyidResult!=propertyid) {
            log.info("非USDT数据");
            return true;
        }
        String txid = jsonTResult.getString("txid");

        int coinfirm = jsonTResult.getIntValue("confirmations");
        if (coinfirm < 6) {
            log.info("交易确认不够,当前确认数:{}",coinfirm);
            return false;
        }
        double value = jsonTResult.getDouble("amount");
        if(value > 0) {
            String address = jsonTResult.getString("referenceaddress");

            for (UserCoinAddressEntity addressModel : userList) {
                //如果有地址是分配给用记的地址, 则说明用户在充值
                if (address.equals(addressModel.getAddress())) {
                    try {
                        //添加充值记录
                        if (rechargeParse(record)) {
                            //归集
                            collUsdt(address,value);
                            return true;
                        }
                    }catch (DuplicateKeyException e){
                        log.error("这个用户{}的充值已经处理了 币:{}",addressModel.getUserId(),CoinConstant.COIN_USDT);
                    }
                }
            }
        }
        return true;
    }

    /**************************第二种方式*********end******************/


    /**
     * 归集USDT
     */
    private void collUsdt(String fromAddress,double value){
        if(vailedAddress(fromAddress)){
            JSONObject json = doRequest(METHOD_OMNI_FUNDED_SEND,fromAddress,mainAddress,propertyid,value,mainAddress);
            if(isError(json)){
                log.error("USDT 归集 value:{}  失败 :",value,json.get("error"));
            }else{
                log.info("USDT 归集 value:{} 成功",value);
            }
        }else{
            log.error("USDT接受地址不正确");
        }
    }

    private boolean isError(JSONObject json){
        if( json == null || (StringUtils.isNotEmpty(json.getString("error")) && json.get("error") != "null")){
            return true;
        }
        return false;
    }

    private JSONObject doRequest(String method,Object... params){
        JSONObject param = new JSONObject();
        param.put("id",System.currentTimeMillis()+"");
        param.put("jsonrpc","2.0");
        param.put("method",method);
        if(params != null){
            param.put("params",params);
        }
        String creb = Base64.encodeBase64String((username+":"+password).getBytes());
        Map<String,String> headers = new HashMap<>(2);
        headers.put("Authorization","Basic "+creb);
        String resp = "";
        if (METHOD_GET_TRANSACTION.equals(method)){
            try{
                resp = HttpUtil.jsonPost(url,headers,param.toJSONString());
            }catch (Exception e){
                if (e instanceof IOException){
                    resp = "{}";
                }
            }
        }else{
            resp = HttpUtil.jsonPost(url,headers,param.toJSONString());
        }
        return JSON.parseObject(resp);
    }

    public static void main(String args[]) throws Exception{
        CoinUsdtService usdtUtils = new CoinUsdtService();
        System.out.println(usdtUtils.getInfo());
    }
}
 

再写一个自动任务,同步钱包高度,查看每个交易记录里的接受地址是否为分配给用户的地址,是的话就代表用户充值了。

/**
 * 区块扫描任务
 *
 * @author xhl
 * @create 2017/10/28
 **/
public class CoinScanJob {
    @Resource
    private CoinUsdtService coinUsdtService;

    public void run(){
            usdtJob();
    }
    /**
     * USDT处理
     */
    private void usdtJob(){
        //这一步获取自己系统存的钱包同步的高度
        int blockParseedCount = coinParseService.getBlockHeight(CoinConstant.COIN_USDT);
        if(blockParseedCount == 0)return;
        //获取钱包的高度
        int blockCount = coinUsdtService.getBlockCount();

        log.info("bte当前高度是:{} 处理记录高度:{}",blockCount,blockParseedCount);
        if(blockCount>blockParseedCount){
            //还有没有处理完的区块, 继续处理
            int index = blockParseedCount+1;
            while(index <= blockCount){
                try {
                    if(coinUsdtService.parseBlock(index)){
                        index++;
                    }else{
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(index == blockCount){
                //所有区块都已经处理完
                coinParseService.updateBlockRecord(CoinConstant.COIN_USDT, index);
            }else{
                coinParseService.updateBlockRecord(CoinConstant.COIN_USDT, index-1);
            }
        }
    }
}
 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值