[幣嚴區塊鏈]交易所錢包系統如何實現USDT自動歸集操作


本文代碼應用場景:

每個用戶在交易所充值時,每個人都分配了獨立的USDT地址,而交易所需要將所有獨立的地址中USDT匯集到一個錢包地址(一般是冷錢包),從而實現資產歸集與安全保障。

 

注意:

理解以下代碼最好先搭建好一個USDT的節點,再在命令行中體驗以下RPC的調用效果。

 

package com.bizzan.col;
import com.googlecode.jsonrpc4j.JsonRpcHttpClient;
import org.apache.commons.codec.binary.Base64;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class UsdtCollect {
 
     private  String url = "http://127.0.0.1:18332";
     private  String username = "u";
     private  String password = "p";
    //outValue是總錢數,這個一般在充值記錄里面計算。我就不調用錢包去查詢了
    public String collectionUsdt( BigDecimal outValue) {
        JsonRpcHttpClient client = null;
        try {
            Map[] argsOne = new Map[1];
            Map[] args1 = new Map[1];
            String creb = Base64.encodeBase64String((username+":"+password).getBytes());
            Map<String,String> headers = new HashMap<>(2);
            headers.put("Authorization","Basic "+creb);
            headers.put("server", "1");
            client = new JsonRpcHttpClient(new URL(url), headers);
            List<Map> listunspent = (List<Map>) client.invoke("listunspent", new Object[]{}, Object.class);
            for (Map map : listunspent) {
                Double amount=(Double) map.get("amount");
                //這里是找一筆uxto的btc交易做橋梁
                if(amount>1){
                    String txId =(String) map.get("txid");
                    String scriptPubKey =(String) map.get("scriptPubKey");
                    int vout =(int) map.get("vout");
                    Map input = new HashMap<>();
                    input.put("txid", txId);
                    input.put("vout", vout);
                    args1[0] = input;
                    Map inputT = new HashMap<>();
                    inputT.put("txid", txId);
                    inputT.put("vout",vout);
                    inputT.put("scriptPubKey", scriptPubKey);
                    inputT.put("value", amount);
                    argsOne[0] = inputT;
                    break;
                }
            }
            //計算字節大小和費用(因為是歸集USDT 所以我用最小的輸入來降低手續費,如果你是BTC和USDT一起歸總那就要根據歸集的輸入來計算了)
            BigDecimal keyCount = calculationFee(1);
            //將聰換算成BTC
            BigDecimal transferFee = keyCount.divide(new BigDecimal("100000000"), 8, RoundingMode.HALF_UP);
            if (transferFee.compareTo(BigDecimal.ZERO) <= 0 || outValue.compareTo(transferFee) <= 0) {
                return null;
            }
            /**
             * 通過全節點構造原生交易
             */
            //創建BTC交易
            Map args2 = new HashMap<>();
            Object result = (Object) client.invoke("createrawtransaction", new Object[]{args1,args2 }, Object.class);
            String transaction = String.valueOf(result);
            /*//解鎖錢包
            client.invoke("walletpassphrase", new Object[]{"xxxx", 100}, Object.class);*/
            //創建Usdt交易
            String simplesendResult = (String) client.invoke("omni_createpayload_simplesend", new Object[]{ 1,outValue.toString() }, Object.class);
            //usdt交易附加到BTC交易上
            String opreturnResult = (String) client.invoke("omni_createrawtx_opreturn", new Object[]{transaction,simplesendResult}, Object.class);
            //設置歸總地址
            String reference = (String) client.invoke("omni_createrawtx_reference", new Object[]{opreturnResult,"歸總地址"}, Object.class);
            //填寫手續費及找零地址
            String changeResult = (String) client.invoke("omni_createrawtx_change", new Object[]{reference,argsOne,"找零地址",transferFee.toString()}, Object.class);
            //獲取原生交易hex
            Map signrawtransaction = (Map) client.invoke("signrawtransaction", new Object[]{changeResult}, Object.class);
            //廣播交易
            String txId = (String) client.invoke("sendrawtransaction", new Object[]{signrawtransaction.get("hex")}, Object.class);
            return txId;
        } catch (Exception e) {
            e.printStackTrace();
        } catch (Throwable e1) {
            e1.printStackTrace();
        }
        return null;
    }
 
    /**
     * 計算手續費
     *
     * @param inputCount
     * @return
     */
    private BigDecimal calculationFee( int inputCount) {
        //計算手續費獲取每個字節的手續費
        String url="bitcoinfees.earn.com";
        //計算字節大小和費用
        String resut=sendGet(url,null);
        //=====resut===>轉對象Model省略了,其實http請求都有公用的方法所以我隨便寫了。。
        BigDecimal keyCount = BigDecimal.valueOf((inputCount * 148 + 44) * Model.getHalfHourFee());
        //
        return keyCount;
 
    }
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打開和URL之間的連接
            URLConnection connection = realUrl.openConnection();
            // 設置通用的請求屬性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立實際的連接
            connection.connect();
            // 獲取所有響應頭字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍歷所有的響應頭字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定義 BufferedReader輸入流來讀取URL的響應
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("發送GET請求出現異常!" + e);
            e.printStackTrace();
        }
        // 使用finally塊來關閉輸入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
}

 

BIZZAN(幣嚴) 數字貨幣交易所官方網址:

www.bizzan.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM