溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java怎么實現(xiàn)區(qū)塊鏈錢包BTC離線簽名交易

發(fā)布時間:2022-01-06 16:42:13 來源:億速云 閱讀:648 作者:iii 欄目:互聯(lián)網(wǎng)科技

這篇文章主要講解了“java怎么實現(xiàn)區(qū)塊鏈錢包BTC離線簽名交易”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“java怎么實現(xiàn)區(qū)塊鏈錢包BTC離線簽名交易”吧!

對于離線交易不做過多解釋~,說白了就是拿上一筆未發(fā)出交易記錄進(jìn)行私鑰的簽名然后廣播到鏈上。

主要是對區(qū)塊鏈離線交易進(jìn)行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;//區(qū)塊高度
	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 發(fā)送地址
	    * @param @param amount 金額
	    * @param @param fee 手續(xù)費(fèi)(自定義 或者 默認(rèn))
	    * @param @param unUtxos 未交易的utxo
	    * @param @return    參數(shù)  
	    * @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);
			// 構(gòu)建交易
			Transaction tx = new Transaction(params);
			tx.addOutput(Coin.valueOf(amount), receiveAddress); // 轉(zhuǎn)出
			// 如果需要找零 消費(fèi)列表總金額 - 已經(jīng)轉(zhuǎn)賬的金額 - 手續(xù)費(fèi)
			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/ 進(jìn)行解碼查看交易詳情:

java怎么實現(xiàn)區(qū)塊鏈錢包BTC離線簽名交易

感謝各位的閱讀,以上就是“java怎么實現(xiàn)區(qū)塊鏈錢包BTC離線簽名交易”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對java怎么實現(xiàn)區(qū)塊鏈錢包BTC離線簽名交易這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI