由于已经不从事区块链相关项目,对疑惑的小伙伴提供一些帮助~~
1.主要是对区块链离线交易进行utxo上链。
2.对usdt地址下的全部币进行汇集交易,单独由btc进行手续费支付
一、对于如何查看一个unspent 交易:
1.调用钱包的 unspent接口
2.调用三方区块链浏览器的接口 例如:(blockchain : https://blockchain.info/unspent?active=35nNMpckrvuaryxFSiUd6jLvLGXJCWUyAY)
拿到钱包地址的unspentUTXO即可进行离线交易获取签名信息了 ,直接上代码:
org.bitcoinj
bitcoinj-tools
0.14.7
org.bitcoinj
bitcoinj-examples
0.14.7
org.bitcoinj
bitcoinj-core
0.14.7
UnspentUtxo:
package com.bscoin.coldwallet.cointype.common;
import java.io.Serializable;
public class UnSpentUtxo implements Serializable {
private static final long serialVersionUID = -7417428486644921613L;
private String hash; //未交易hash
private long txN;
private long value;//金额
private int height; //高度
private String script;//签名
private String address;//钱包地址
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public long getTxN() {
return txN;
}
public void setTxN(long txN) {
this.txN = txN;
}
public long getValue() {
return value;
}
public void setValue(long value) {
this.value = value;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getScript() {
return script;
}
public void setScript(String script) {
this.script = script;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
/**
* @Title: createRawTransaction
* @param @param privBtcKey btc私钥
* @param @param btcAddress 比特币地址
* @param @param privUsdtKey usdt私钥
* @param @param recevieUsdtAddr usdt接收地址
* @param @param fee 手续费
* @param @param omniHex - usdt hex
* @param @param unBtcUtxos - btc utxo
* @param @param unUsdtUtxos - usdt utxo
* @param @return 参数
* @return String 返回类型
* @throws
*/
public static String createRawTransaction(String privBtcKey, String btcAddress, String privUsdtKey, String recevieUsdtAddr, long fee, String omniHex, List unBtcUtxos, List unUsdtUtxos) {
List btcUtxos = new ArrayList();
List usdtUtxos = new ArrayList();
try {
if (!unBtcUtxos.isEmpty() && !unUsdtUtxos.isEmpty()) {
// find a btc eckey info
DumpedPrivateKey btcPrivateKey = DumpedPrivateKey.fromBase58(params, privBtcKey);
ECKey btcKey = btcPrivateKey.getKey();
// a usdt eckey info
DumpedPrivateKey usdtPrivateKey = DumpedPrivateKey.fromBase58(params, privUsdtKey);
ECKey usdtKey = usdtPrivateKey.getKey();
// receive address
Address receiveAddress = Address.fromBase58(params, recevieUsdtAddr);
// create a transaction
Transaction tx = new Transaction(params);
// odd address
Address oddAddress = Address.fromBase58(params, btcAddress);
// 如果需要找零 消费列表总金额 - 已经转账的金额 - 手续费
long value_btc = unBtcUtxos.stream().mapToLong(UnSpentUtxo::getValue).sum();
long value_usdt = unUsdtUtxos.stream().mapToLong(UnSpentUtxo::getValue).sum();
// 总输入 - 手续费 - 546 -546 = 找零金额
long leave = (value_btc + value_usdt) - fee - 1092;
if (leave > 0) {
tx.addOutput(Coin.valueOf(leave), oddAddress);
}
// usdt transaction
tx.addOutput(Coin.valueOf(546), new Script(Utils.HEX.decode(omniHex)));
// send to address
tx.addOutput(Coin.valueOf(546), receiveAddress);
// btc utxos is an array of inputs from my wallet
for (UnSpentUtxo unUtxo : unBtcUtxos) {
btcUtxos.add(new UTXO(Sha256Hash.wrap(unUtxo.getHash()), unUtxo.getTxN(), Coin.valueOf(unUtxo.getValue()), unUtxo.getHeight(), false, new Script(Utils.HEX.decode(unUtxo.getScript())), unUtxo.getAddress()));
}
// usdt utxos is an array of inputs from my wallet
for (UnSpentUtxo unUtxo : unUsdtUtxos) {
usdtUtxos.add(new UTXO(Sha256Hash.wrap(unUtxo.getHash()), unUtxo.getTxN(), Coin.valueOf(unUtxo.getValue()), unUtxo.getHeight(), false, new Script(Utils.HEX.decode(unUtxo.getScript())), unUtxo.getAddress()));
}
// create usdt utxo data
for (UTXO utxo : usdtUtxos) {
TransactionOutPoint outPoint = new TransactionOutPoint(params, utxo.getIndex(), utxo.getHash());
tx.addSignedInput(outPoint, utxo.getScript(), usdtKey, Transaction.SigHash.ALL, true);
}
// create btc utxo data
for (UTXO utxo : btcUtxos) {
TransactionOutPoint outPoint = new TransactionOutPoint(params, utxo.getIndex(), utxo.getHash());
tx.addSignedInput(outPoint, utxo.getScript(), btcKey, Transaction.SigHash.ALL, true);
}
Context context = new Context(params);
tx.getConfidence().setSource(TransactionConfidence.Source.NETWORK);
tx.setPurpose(Transaction.Purpose.USER_PAYMENT);
LOG.info("=== [USDT] sign success,hash is :{} ===", tx.getHashAsString());
return new String(Hex.encodeHex(tx.bitcoinSerialize()));
}
} catch (Exception e) {
LOG.info("=== com.bscoin.coldwallet.cointype.usdt.RawTransaction.createRawTransaction(String, String, String, String, String, long, String, List, List):{} ===",
e.getMessage(), e);
}
return null;
}
public static void main(String[] args) {
Map m = new HashMap();
List us = new ArrayList();
UnSpentUtxo u = new UnSpentUtxo();
u.setAddress("mvEtuEqYPMrLaKjJ5nTZ57vQAoYUtVmMaQ");
u.setHash("d235e908767d4bbf579e04ae768fa16298c8ccb2dc406f1cda90341477ccbb3f");
u.setHeight(1413239);
u.setScript("76a914a1806613a51a81966779e2fa1537013cf4cd2b1788ac");
u.setTxN(0);
u.setValue(300000);
UnSpentUtxo u1 = new UnSpentUtxo();
u1.setAddress("mvEtuEqYPMrLaKjJ5nTZ57vQAoYUtVmMaQ");
u1.setHash("d74b16fd8e548e467bd1f4ce1214037fc6087bb7bf4f15cfa684d03d1cb2eda4");
u1.setHeight(1413334);
u1.setScript("76a914a1806613a51a81966779e2fa1537013cf4cd2b1788ac");
u1.setTxN(1);
u1.setValue(300000);
us.add(u);
us.add(u1);
List us2 = new ArrayList();
UnSpentUtxo u3 = new UnSpentUtxo();
u3.setAddress("moUseQWZenTkU3a2bCZydth3CUUZqNY6Fk");
u3.setHash("bd6da7714f1eb5f36e62070bc8463f8d574b98083a0df872285d291417b3afe3");
u3.setHeight(1413334);
u3.setScript("76a914575c4b21030d58d02c434fc36f66a866142e74ce88ac");
u3.setTxN(1);
u3.setValue(546);
us2.add(u3);
m.put("btcUtxo", us);
m.put("usdtUtxo", us2);
m.put("omniHex", "6a146f6d6e6900000000000000010000000059682f00");
System.out.println("传输参数:" + JSON.toJSONString(m));
String c = createRawTransaction("cNRE3D1pbPPvGs9wpZd3X9NuLsuUQPzPa7ktQyF1nhqBabraocU9", "muY7H7zdguqRRdCA1CX152aBfFZ2q6RURx", "cMnUzSFXsXdeAq3RSfSTLCxB669VuXBzDC9oL2dQykPfj1P4ZxKP", "n21WGsyEXkrgEtM9ahx7e5pgQJYtagvKgo", 99454, "6a146f6d6e6900000000000000010000000059682f00", us, us2);
System.out.println(c);
}
获取OmniHex:
调用RPC: get_balance 、 omni_createpayload_simplesend 、 omni_createrawtx_opreturn