java怎么实现区块链钱包BTC离线签名交易

这篇文章主要讲解了“java怎么实现区块链钱包BTC离线签名交易”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“java怎么实现区块链钱包BTC离线签名交易”吧!

公司主营业务:网站设计制作、网站制作、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联推出开阳免费做网站回馈大家。

对于离线交易不做过多解释~,说白了就是拿上一笔未发出交易记录进行私钥的签名然后广播到链上。

主要是对区块链离线交易进行utxo上链。

废话不多说 ,直接上代码:

UnspentUtxo交易查看:

 blockchain-testnet : https://testnet.blockchain.info/unspent?active=mifiHFYFPk5cri4oneXVsRZJZKovvdDcjo

 blockchain-mainnet : https://blockchain.info/unspent?active=地址
 

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;//hex
	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;
	}
	
}

离线签名:

import java.util.ArrayList;
import java.util.List;
 
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.configuration2.Configuration;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Context;
import org.bitcoinj.core.DumpedPrivateKey;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionOutPoint;
import org.bitcoinj.core.UTXO;
import org.bitcoinj.core.Utils;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.script.Script;
import org.omg.CORBA.UNKNOWN;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import com.alibaba.fastjson.JSON;
import com.bscoin.coldwallet.cointype.common.ConfigUtil;
import com.bscoin.coldwallet.cointype.common.UnSpentUtxo;
 
import org.bitcoinj.core.TransactionConfidence;
 
  
/**  
    * @ClassName: RawTransaction  
    * @author DHing  
    *    
*/  
public class RawTransaction {
	
	private static Logger LOG = LoggerFactory.getLogger(RawTransaction.class);
	static NetworkParameters params;
	
	static {
		try {
			Configuration config = ConfigUtil.getInstance();
			params = config.getBoolean("bitcoin.testnet") ? TestNet3Params.get() : MainNetParams.get();
			LOG.info("=== [BTC] bitcoin  client networkID:{} ===", params.getId());
		} catch (Exception e) {
			LOG.info("=== [BTC] com.bscoin.coldwallet.cointype.btc.rawtransaction:{} ===", e.getMessage(), e);
		}
	}
	
	  
	    /**  
	    * @Title: signTransaction
	    * @param @param privKey 私钥
	    * @param @param recevieAddr 收款地址
	    * @param @param formAddr 发送地址
	    * @param @param amount 金额
	    * @param @param fee 手续费(自定义 或者 默认)
	    * @param @param unUtxos 未交易的utxo
	    * @param @return    参数  
	    * @return char[]    返回类型  
	    * @throws  
	    */  
	public static String signTransaction(String privKey, String recevieAddr, String formAddr,
																		  long amount, long fee, 
																		  List unUtxos) {
		if(!unUtxos.isEmpty() && null != unUtxos){
			List utxos = new ArrayList();
			// String to a private key
			DumpedPrivateKey dumpedPrivateKey = DumpedPrivateKey.fromBase58(params, privKey);
			ECKey key = dumpedPrivateKey.getKey();
			// 接收地址
			Address receiveAddress = Address.fromBase58(params, recevieAddr);
			// 构建交易
			Transaction tx = new Transaction(params);
			tx.addOutput(Coin.valueOf(amount), receiveAddress); // 转出
			// 如果需要找零 消费列表总金额 - 已经转账的金额 - 手续费
			long value = unUtxos.stream().mapToLong(UnSpentUtxo::getValue).sum();
			Address toAddress = Address.fromBase58(params, formAddr);
			long leave  = value - amount - fee;
			if(leave > 0){
				tx.addOutput(Coin.valueOf(leave), toAddress);
			}
			// utxos is an array of inputs from my wallet
			for (UnSpentUtxo unUtxo : unUtxos) {
				utxos.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()));
			}
			for (UTXO utxo : utxos) {
				TransactionOutPoint outPoint = new TransactionOutPoint(params, utxo.getIndex(), utxo.getHash());
				// YOU HAVE TO CHANGE THIS
				tx.addSignedInput(outPoint, utxo.getScript(), key, Transaction.SigHash.ALL, true);
			}
			Context context = new Context(params);
			tx.getConfidence().setSource(TransactionConfidence.Source.NETWORK);
			tx.setPurpose(Transaction.Purpose.USER_PAYMENT);
			
			LOG.info("=== [BTC] sign success,hash is :{} ===",tx.getHashAsString());
			return new String(Hex.encodeHex(tx.bitcoinSerialize()));
		}
		return null;
	}
	
	public static void main(String[] args) {
		List us = new ArrayList();
		UnSpentUtxo u = new UnSpentUtxo();
		u.setAddress("mifiHFYFPk5cri4oneXVsRZJZKovvdDcjo");
		u.setHash("2bc6ac92468c2b4f1fcd2349822dc4663dfc0705b30131087a20ed8d17de8274");
		u.setHeight(	1413239);
		u.setScript("76a914a1806613a51a81966779e2fa1537013cf4cd2b1788ac");
		u.setTxN(1);
		u.setValue(100000);
		
		UnSpentUtxo u1 = new UnSpentUtxo();
		u1.setAddress("mvEtuEqYPMrLaKjJ5nTZ57vQAoYUtVmMaQ");
		u1.setHash("1893b6ff8ef2bd6f5d652937ffbaed5bb669c5d9ab450066253d6692f2d4d972");
		u1.setHeight(1413334);
		u1.setScript("76a914a1806613a51a81966779e2fa1537013cf4cd2b1788ac");
		u1.setTxN(1);
		u1.setValue(400000);
		us.add(u);
		us.add(u1);
				
		System.out.println(JSON.toJSONString(us));
		String c = signTransaction("cNRE3D1pbPPvGs9wpZd3X9NuLsuUQPzPa7ktQyF1nhqBabraocU9", "mifiHFYFPk5cri4oneXVsRZJZKovvdDcjo", "mvEtuEqYPMrLaKjJ5nTZ57vQAoYUtVmMaQ", 400000, 10000, us);
		System.out.println(c);
	}
}

签名成功返回Hex,使用https://live.blockcypher.com/btc-testnet/decodetx/ 进行解码查看交易详情:

java怎么实现区块链钱包BTC离线签名交易

感谢各位的阅读,以上就是“java怎么实现区块链钱包BTC离线签名交易”的内容了,经过本文的学习后,相信大家对java怎么实现区块链钱包BTC离线签名交易这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!


当前名称:java怎么实现区块链钱包BTC离线签名交易
链接地址:http://ybzwz.com/article/jjhsjj.html