[币严区块链]交易所钱包系统如何实现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
[币严区块链]交易所钱包系统如何实现USDT自动归集操作的更多相关文章
- [币严区块链]BitcoinCash - BCH钱包地址生成与扫块充值监控(JAVA版)
本文的方案无需自建节点,因为BCH当前区块数据大小已经达到200G以上,BTC区块数据也已超过300G,若每个币都自建节点,对云服务器的消耗会非常大. 认识BitcoinCash(BCH) Bitco ...
- [币严区块链]数字货币交易所之比特币(BTC)钱包对接 | 自建节点JSON-RPC访问
BTC钱包对接流程 一. 部署BTC钱包节点 二. 分析BTC钱包的API 三. 通过JSON-RPC访问BTC钱包API 四. 部署测试 一.部署钱包节点 交易平台对接BTC之前,要 ...
- [币严区块链]数字货币交易所之以太坊(ETH)钱包对接(四) 使用web3j对接以太坊钱包
本文给大家介绍了 Web3j Java 版本的框架的基本使用,大家可根据本文的内容进行扩展性的练习,对其他 API 的使用进行尝试. 使用web3j对接以太坊钱包 一.开发准备事项 启动 Geth 此 ...
- [币严区块链]数字货币交易所之瑞波(XRP)钱包对接
对接Ripple(XRP),不需要本地部署钱包,直接访问Ripple API,本文包括访问Ripple API及如何免费获取测试的XRP. 对接流程 安装Ripple API Ripple API 接 ...
- [币严区块链]USDT钱包节点搭建
USDT是基于BTC发的稳定币,它是比特币的一条侧链,说简单点,就是在比特币区块数据的不可篡改性与区块唯一性的基础上,再封装了一层.具体原理可网上查资料.总之理解一点:USDT的钱包节点就是BTC的钱 ...
- [币严区块链]以太坊(ETH)Dapp开发入门教程之宠物商店领养游戏
阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是什么 除此之外,你最好还了解一些HTML及JavaScript知识. 本文通过实例教大家来开发去中心化应用,应用效果如图 ...
- [币严区块链]ETH搭建节点区块数据同步的三种模式:full、fast、light
ETH 全节点Archive(归档)模式数据量增长图 上述图表可通过链接查看:https://etherscan.io/chartsync/chainarchive 通过上表,可以看到截止2019年 ...
- [币严区块链]简单易懂的以太坊(ETH)智能合约开发入门教程
以太坊(Ethereum)是一提供个智能合约(smart contract)功能的公共区块链(BlockChain)平台. 本文介绍了一个简单的以太坊智能合约的开发过程. 开发环境 在以太坊上开发应用 ...
- 各大知名区块链交易所链接及API文档链接
区块链交易所链接 火币网(Huobi):https://www.huobi.br.com/zh-cn/ API文档:https://github.com/huobiapi/API_Docs/wiki ...
随机推荐
- python3从入门到精通之数据类型,布尔类型介绍
数据的类型 为了更充分的利用内存空间以及更有效率的管理内存,变量是有不同的类型的. Number(数字) int(整型) float(浮点型) complex(复数) bool(布尔) String( ...
- 最新 Flutter 团队工程师中文演讲 | Flutter 的性能测试和理论
本视频为 Google Flutter 团队的软件工程师 Xiao Yu 在 2018 谷歌开发者大会做的演讲,演讲题目是<Flutter 的性能测试和理论>. 这个视频里将会通过近半个小 ...
- 链表:如何实现LRU缓存淘汰算法?
缓存淘汰策略: FIFO:先入先出策略 LFU:最少使用策略 LRU:最近最少使用策略 链表的数据结构: 可以看到,数组需要连续的内存空间,当内存空间充足但不连续时,也会申请失败触发GC,链表则可 ...
- trec 2019 fair ranking track
trec 2019 fair ranking track 最近实验室要求参加trec 2019新出的track:fair ranking track.这里整理一下该任务的思想和要求.这次tra ...
- Java虚拟机日志与参数
虚拟机日志 打印GC日志可以使用参数-XX:+PrintGC /** * -Xmx10m -Xms10m -XX:PretenureSizeThreshold=10485760 * -XX:+Prin ...
- Kafka 0.8 Producer (0.9以前版本适用)
Kafka旧版本producer由scala编写,0.9以后已经废除,但是很多公司还在使用0.9以前的版本,所以总结如下: 要注意包Producer是 kafka.javaapi.producer.P ...
- 逆向破解之160个CrackMe —— 016
CrackMe —— 016 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...
- 后端开发实践系列之三——事件驱动架构(EDA)编码实践
在本系列的前两篇文章中,笔者分别讲到了后端项目的代码模板和DDD编码实践,在本文中,我将继续以编码实践的方式分享如何落地事件驱动架构. 单纯地讲事件驱动架构(Event Driven Architec ...
- vue父子组件通信高级用法
vue项目的一大亮点就是组件化.使用组件可以极大地提高项目中代码的复用率,减少代码量.但是使用组件最大的难点就是父子组件之间的通信. 子通信父 父组件 <template> <div ...
- RANSAC简史(一)——RANSAC之初
在开始正式的介绍之前,先做一个简单的定义,以免产生歧义: 1.本文中的“数据点”是指: 1)对于直线拟合.平面拟合等问题,即为相应的二维/三维坐标点: 2)对于从匹配点中估计基本矩阵.单应矩阵等问题, ...