温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2022-01-06 16:42:13 来源:亿速云 阅读:612 作者:iii 栏目:互联网科技

这篇文章主要讲解了“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<UnSpentUtxo> unUtxos) {
		if(!unUtxos.isEmpty() && null != unUtxos){
			List<UTXO> utxos = new ArrayList<UTXO>();
			// 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<UnSpentUtxo> us = new ArrayList<UnSpentUtxo>();
		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离线签名交易这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI