Java Code Examples for org.bitcoinj.core.Transaction#getInputs()
The following examples show how to use
org.bitcoinj.core.Transaction#getInputs() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: WalletService.java From bisq-core with GNU Affero General Public License v3.0 | 6 votes |
protected List<TransactionOutput> getOutputsWithConnectedOutputs(Transaction tx) { List<TransactionOutput> transactionOutputs = tx.getOutputs(); List<TransactionOutput> connectedOutputs = new ArrayList<>(); // add all connected outputs from any inputs as well List<TransactionInput> transactionInputs = tx.getInputs(); for (TransactionInput transactionInput : transactionInputs) { TransactionOutput transactionOutput = transactionInput.getConnectedOutput(); if (transactionOutput != null) { connectedOutputs.add(transactionOutput); } } List<TransactionOutput> mergedOutputs = new ArrayList<>(); mergedOutputs.addAll(transactionOutputs); mergedOutputs.addAll(connectedOutputs); return mergedOutputs; }
Example 2
Source File: MemPooler.java From jelectrum with MIT License | 6 votes |
public boolean areSomeInputsPending(Transaction tx) { MemPoolInfo info = latest_info; if (info == null) return false; //Hard to say for(TransactionInput tx_in : tx.getInputs()) { if (!tx_in.isCoinBase()) { TransactionOutPoint tx_out = tx_in.getOutpoint(); Sha256Hash parent_hash = tx_out.getHash(); if (info.tx_set.contains(parent_hash)) return true; } } return false; }
Example 3
Source File: Importer.java From jelectrum with MIT License | 6 votes |
public void putTxOutSpents(Transaction tx) { LinkedList<String> tx_outs = new LinkedList<String>(); for(TransactionInput in : tx.getInputs()) { if (!in.isCoinBase()) { TransactionOutPoint out = in.getOutpoint(); String key = out.getHash().toString() + ":" + out.getIndex(); //file_db.addTxOutSpentByMap(key, tx.getHash()); tx_outs.add(key); } } }
Example 4
Source File: WalletService.java From bisq with GNU Affero General Public License v3.0 | 6 votes |
protected List<TransactionOutput> getOutputsWithConnectedOutputs(Transaction tx) { List<TransactionOutput> transactionOutputs = tx.getOutputs(); List<TransactionOutput> connectedOutputs = new ArrayList<>(); // add all connected outputs from any inputs as well List<TransactionInput> transactionInputs = tx.getInputs(); for (TransactionInput transactionInput : transactionInputs) { TransactionOutput transactionOutput = transactionInput.getConnectedOutput(); if (transactionOutput != null) { connectedOutputs.add(transactionOutput); } } List<TransactionOutput> mergedOutputs = new ArrayList<>(); mergedOutputs.addAll(transactionOutputs); mergedOutputs.addAll(connectedOutputs); return mergedOutputs; }
Example 5
Source File: TransactionAwareTrade.java From bisq with GNU Affero General Public License v3.0 | 6 votes |
boolean isDelayedPayoutTx(String txId) { Transaction transaction = btcWalletService.getTransaction(txId); if (transaction == null) return false; if (transaction.getLockTime() == 0) return false; if (transaction.getInputs() == null) return false; return transaction.getInputs().stream() .anyMatch(input -> { TransactionOutput connectedOutput = input.getConnectedOutput(); if (connectedOutput == null) { return false; } Transaction parentTransaction = connectedOutput.getParentTransaction(); if (parentTransaction == null) { return false; } return isDepositTx(parentTransaction.getHashAsString()); }); }
Example 6
Source File: RawTransactionInfo.java From consensusj with Apache License 2.0 | 6 votes |
/** * Construct from a bitcoinj transaction * @param transaction A bitcoinj confirmed or unconfirmed transaction */ public RawTransactionInfo(Transaction transaction) { this.hex = HexUtil.bytesToHexString(transaction.bitcoinSerialize()); this.txid = transaction.getTxId(); this.version = transaction.getVersion(); this.locktime = transaction.getLockTime(); this.blockhash = null; // For now this.confirmations = transaction.getConfidence().getDepthInBlocks(); this.time = 0; // TODO: block header time of block including transaction this.blocktime = this.time; // same as time (see API doc) vin = new VinList(); for (TransactionInput input : transaction.getInputs()) { vin.add(new Vin(txid, input.getOutpoint().getIndex(), input.getScriptSig().toString(), input.getSequenceNumber())); } vout = new VoutList(); for (TransactionOutput output : transaction.getOutputs()) { vout.add(new Vout(output.getValue(), output.getIndex(), output.getScriptPubKey().toString())); } }
Example 7
Source File: SWWallet.java From GreenBits with GNU General Public License v3.0 | 6 votes |
@Override public List<byte[]> signTransaction(final Transaction tx, final PreparedTransaction ptx, final List<Output> prevOuts) { final List<TransactionInput> txInputs = tx.getInputs(); final List<byte[]> sigs = new ArrayList<>(txInputs.size()); for (int i = 0; i < txInputs.size(); ++i) { final Output prevOut = prevOuts.get(i); final Script script = new Script(Wally.hex_to_bytes(prevOut.script)); final Sha256Hash hash; if (prevOut.scriptType.equals(GATx.P2SH_P2WSH_FORTIFIED_OUT)) hash = tx.hashForSignatureWitness(i, script.getProgram(), Coin.valueOf(prevOut.value), Transaction.SigHash.ALL, false); else hash = tx.hashForSignature(i, script.getProgram(), Transaction.SigHash.ALL, false); final SWWallet key = getMyKey(prevOut.subAccount).derive(prevOut.branch).derive(prevOut.pointer); final ECKey eckey = ECKey.fromPrivate(key.mRootKey.getPrivKey()); sigs.add(getTxSignature(eckey.sign(Sha256Hash.wrap(hash.getBytes())))); } return sigs; }
Example 8
Source File: ToolsTest.java From thunder with GNU Affero General Public License v3.0 | 6 votes |
private static Transaction shuffleTransaction (Transaction transaction) { Transaction shuffledTransaction = new Transaction(Constants.getNetwork()); List<TransactionInput> shuffledInputs = new ArrayList<>(transaction.getInputs()); List<TransactionOutput> shuffledOutputs = new ArrayList<>(transaction.getOutputs()); Collections.shuffle(shuffledInputs); Collections.shuffle(shuffledOutputs); for (TransactionInput input : shuffledInputs) { shuffledTransaction.addInput(input); } for (TransactionOutput output : shuffledOutputs) { shuffledTransaction.addOutput(output); } return shuffledTransaction; }
Example 9
Source File: GATx.java From GreenBits with GNU General Public License v3.0 | 5 votes |
public static List<Transaction> getPreviousTransactions(final GaService service, final Transaction tx) { final List<Transaction> previousTxs = new ArrayList<>(); try { for (final TransactionInput in : tx.getInputs()) { final String txhex = service.getRawOutputHex(in.getOutpoint().getHash()); previousTxs.add(GaService.buildTransaction(txhex, service.getNetworkParameters())); } } catch (final Exception e) { e.printStackTrace(); return null; } return previousTxs; }
Example 10
Source File: TransactionSummary.java From jelectrum with MIT License | 5 votes |
public TransactionSummary(Transaction tx, TXUtil tx_util, boolean confirmed, Map<Sha256Hash, Transaction> block_tx_map) { tx_hash = tx.getHash(); involved_scripthashes = new HashSet<>(); ins = new TreeMap<>(); outs = new TreeMap<>(); long total_out=0L; long total_in=0L; for(TransactionOutput tx_out : tx.getOutputs()) { TransactionOutSummary os = new TransactionOutSummary(tx_out, tx_util); outs.put( tx_out.getIndex(), os ); involved_scripthashes.add(os.getScriptHash()); total_out += os.getValue(); } int idx=0; for(TransactionInput tx_in : tx.getInputs()) { TransactionInSummary is = new TransactionInSummary(tx_in, tx_util, confirmed, block_tx_map); ByteString addr = is.getScriptHash(); if (addr != null) involved_scripthashes.add(addr); ins.put(idx, is); idx++; total_in += is.getValue(); } if (tx.isCoinBase()) { fee = 0L; } else { fee = total_in - total_out; } size = tx.getOptimalEncodingMessageSize(); }
Example 11
Source File: ChannelBlockchainWatcher.java From thundernetwork with GNU Affero General Public License v3.0 | 4 votes |
@Override public void start () { Transaction tx = blockchainHelper.getTransaction(channel.anchorTxHashClient); if (tx != null) { int depth = tx.getConfidence().getDepthInBlocks(); if (depth > 0) { confirmed = true; confirmations = depth; } } anchorSuccess = new OnTxCommand() { @Override public boolean compare (Transaction tx) { if (stopped) { return true; } else { return channel.getAnchorTxHashClient().equals(tx.getHash()); } } @Override public void execute (Transaction tx) { if (stopped) { return; } else if (LNEstablishProcessorImpl.MIN_CONFIRMATIONS == 0) { channelManager.onAnchorDone(channel); } } }; anchorEscape = new OnTxCommand() { @Override public boolean compare (Transaction tx) { if (stopped) { return true; } for (TransactionInput input : tx.getInputs()) { if (input.getOutpoint().getHash().equals(channel.anchorTxHashClient) || input.getOutpoint().getHash().equals(channel.anchorTxHashServer)) { return true; } } return false; } @Override public void execute (Transaction tx) { if (stopped) { return; } else { channelManager.onAnchorFailure(channel, new AnchorSpentChannelFailure(channel)); } } }; blockCommand = block -> { if (stopped) { return true; } if (!confirmed) { if (block.getTransactions().contains(tx)) { confirmed = true; } } if (confirmed) { confirmations++; } else { blockSince++; } if (confirmations >= LNEstablishProcessorImpl.MIN_CONFIRMATIONS) { channelManager.onAnchorDone(channel); return true; } else { if ((blockSince > LNEstablishProcessor.MAX_WAIT_FOR_OTHER_TX_IF_SEEN && seen) || (blockSince > LNEstablishProcessor.MAX_WAIT_FOR_OTHER_TX && !seen)) { channelManager.onAnchorFailure(channel, new AnchorNotFoundChannelFailure(channel)); } } return false; }; blockchainHelper.addBlockListener(this.blockCommand); blockchainHelper.addTxListener(this.anchorEscape); blockchainHelper.addTxListener(this.anchorSuccess); }
Example 12
Source File: ChannelBlockchainWatcher.java From thunder with GNU Affero General Public License v3.0 | 4 votes |
@Override public void start () { Transaction tx = blockchainHelper.getTransaction(channel.anchorTxHash); if (tx != null) { int depth = tx.getConfidence().getDepthInBlocks(); if (depth > 0) { confirmed = true; confirmations = depth; } } anchorSuccess = new OnTxCommand() { @Override public boolean compare (Transaction tx) { if (stopped) { return true; } else { return channel.anchorTxHash.equals(tx.getHash()); } } @Override public void execute (Transaction tx) { if (stopped) { return; } else if (LNEstablishProcessorImpl.MIN_CONFIRMATIONS == 0) { channelManager.onAnchorDone(channel); } } }; anchorEscape = new OnTxCommand() { @Override public boolean compare (Transaction tx) { if (stopped) { return true; } for (TransactionInput input : tx.getInputs()) { if (input.getOutpoint().getHash().equals(channel.anchorTxHash)) { return true; } } return false; } @Override public void execute (Transaction tx) { if (stopped) { return; } else { channelManager.onAnchorFailure(channel, new AnchorSpentChannelFailure(channel)); } } }; blockCommand = block -> { if (stopped) { return true; } if (!confirmed) { if (block != null && block.getTransactions() != null && block.getTransactions().contains(tx)) { confirmed = true; } } if (confirmed) { confirmations++; } else { blockSince++; } if (confirmations >= LNEstablishProcessorImpl.MIN_CONFIRMATIONS) { channelManager.onAnchorDone(channel); return true; } else { if ((blockSince > LNEstablishProcessor.MAX_WAIT_FOR_OTHER_TX_IF_SEEN && seen) || (blockSince > LNEstablishProcessor.MAX_WAIT_FOR_OTHER_TX && !seen)) { channelManager.onAnchorFailure(channel, new AnchorNotFoundChannelFailure(channel)); } } return false; }; blockchainHelper.addBlockListener(this.blockCommand); blockchainHelper.addTxListener(this.anchorEscape); blockchainHelper.addTxListener(this.anchorSuccess); }
Example 13
Source File: WalletService.java From bisq with GNU Affero General Public License v3.0 | 4 votes |
public static void removeSignatures(Transaction transaction) { for (TransactionInput input : transaction.getInputs()) { input.setScriptSig(new Script(new byte[]{})); } }
Example 14
Source File: BtcWalletService.java From bisq-core with GNU Affero General Public License v3.0 | 4 votes |
private Transaction addInputsForMinerFee(Transaction preparedTx, byte[] opReturnData) throws InsufficientMoneyException { // safety check counter to avoid endless loops int counter = 0; // estimated size of input sig final int sigSizePerInput = 106; // typical size for a tx with 3 inputs int txSizeWithUnsignedInputs = 300; final Coin txFeePerByte = feeService.getTxFeePerByte(); Address changeAddress = getFreshAddressEntry().getAddress(); checkNotNull(changeAddress, "changeAddress must not be null"); final BtcCoinSelector coinSelector = new BtcCoinSelector(walletsSetup.getAddressesByContext(AddressEntry.Context.AVAILABLE)); final List<TransactionInput> preparedBsqTxInputs = preparedTx.getInputs(); final List<TransactionOutput> preparedBsqTxOutputs = preparedTx.getOutputs(); int numInputs = preparedBsqTxInputs.size(); Transaction resultTx = null; boolean isFeeOutsideTolerance; do { counter++; if (counter >= 10) { checkNotNull(resultTx, "resultTx must not be null"); log.error("Could not calculate the fee. Tx=" + resultTx); break; } Transaction tx = new Transaction(params); preparedBsqTxInputs.forEach(tx::addInput); preparedBsqTxOutputs.forEach(tx::addOutput); SendRequest sendRequest = SendRequest.forTx(tx); sendRequest.shuffleOutputs = false; sendRequest.aesKey = aesKey; // signInputs needs to be false as it would try to sign all inputs (BSQ inputs are not in this wallet) sendRequest.signInputs = false; sendRequest.fee = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs); sendRequest.feePerKb = Coin.ZERO; sendRequest.ensureMinRequiredFee = false; sendRequest.coinSelector = coinSelector; sendRequest.changeAddress = changeAddress; wallet.completeTx(sendRequest); resultTx = sendRequest.tx; // add OP_RETURN output resultTx.addOutput(new TransactionOutput(params, resultTx, Coin.ZERO, ScriptBuilder.createOpReturnScript(opReturnData).getProgram())); numInputs = resultTx.getInputs().size(); txSizeWithUnsignedInputs = resultTx.bitcoinSerialize().length; final long estimatedFeeAsLong = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs).value; // calculated fee must be inside of a tolerance range with tx fee isFeeOutsideTolerance = Math.abs(resultTx.getFee().value - estimatedFeeAsLong) > 1000; } while (isFeeOutsideTolerance); return resultTx; }
Example 15
Source File: BtcWalletService.java From bisq with GNU Affero General Public License v3.0 | 4 votes |
private Transaction completePreparedProposalTx(Transaction feeTx, byte[] opReturnData, @Nullable Coin issuanceAmount, @Nullable Address issuanceAddress) throws TransactionVerificationException, WalletException, InsufficientMoneyException { // (BsqFee)tx has following structure: // inputs [1-n] BSQ inputs (fee) // outputs [0-1] BSQ request fee change output (>= 546 Satoshi) // preparedCompensationRequestTx has following structure: // inputs [1-n] BSQ inputs for request fee // inputs [1-n] BTC inputs for BSQ issuance and miner fee // outputs [1] Mandatory BSQ request fee change output (>= 546 Satoshi) // outputs [1] Potentially BSQ issuance output (>= 546 Satoshi) - in case of a issuance tx, otherwise that output does not exist // outputs [0-1] BTC change output from issuance and miner fee inputs (>= 546 Satoshi) // outputs [1] OP_RETURN with opReturnData and amount 0 // mining fee: BTC mining fee + burned BSQ fee Transaction preparedTx = new Transaction(params); // Copy inputs from BSQ fee tx feeTx.getInputs().forEach(preparedTx::addInput); int indexOfBtcFirstInput = feeTx.getInputs().size(); // Need to be first because issuance is not guaranteed to be valid and would otherwise burn change output! // BSQ change outputs from BSQ fee inputs. feeTx.getOutputs().forEach(preparedTx::addOutput); // For generic proposals there is no issuance output, for compensation and reimburse requests there is if (issuanceAmount != null && issuanceAddress != null) { // BSQ issuance output preparedTx.addOutput(issuanceAmount, issuanceAddress); } // safety check counter to avoid endless loops int counter = 0; // estimated size of input sig int sigSizePerInput = 106; // typical size for a tx with 3 inputs int txSizeWithUnsignedInputs = 300; Coin txFeePerByte = feeService.getTxFeePerByte(); Address changeAddress = getFreshAddressEntry().getAddress(); checkNotNull(changeAddress, "changeAddress must not be null"); BtcCoinSelector coinSelector = new BtcCoinSelector(walletsSetup.getAddressesByContext(AddressEntry.Context.AVAILABLE), preferences.getIgnoreDustThreshold()); List<TransactionInput> preparedBsqTxInputs = preparedTx.getInputs(); List<TransactionOutput> preparedBsqTxOutputs = preparedTx.getOutputs(); int numInputs = preparedBsqTxInputs.size(); Transaction resultTx = null; boolean isFeeOutsideTolerance; do { counter++; if (counter >= 10) { checkNotNull(resultTx, "resultTx must not be null"); log.error("Could not calculate the fee. Tx=" + resultTx); break; } Transaction tx = new Transaction(params); preparedBsqTxInputs.forEach(tx::addInput); preparedBsqTxOutputs.forEach(tx::addOutput); SendRequest sendRequest = SendRequest.forTx(tx); sendRequest.shuffleOutputs = false; sendRequest.aesKey = aesKey; // signInputs needs to be false as it would try to sign all inputs (BSQ inputs are not in this wallet) sendRequest.signInputs = false; sendRequest.fee = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs); sendRequest.feePerKb = Coin.ZERO; sendRequest.ensureMinRequiredFee = false; sendRequest.coinSelector = coinSelector; sendRequest.changeAddress = changeAddress; wallet.completeTx(sendRequest); resultTx = sendRequest.tx; // add OP_RETURN output resultTx.addOutput(new TransactionOutput(params, resultTx, Coin.ZERO, ScriptBuilder.createOpReturnScript(opReturnData).getProgram())); numInputs = resultTx.getInputs().size(); txSizeWithUnsignedInputs = resultTx.bitcoinSerialize().length; long estimatedFeeAsLong = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs).value; // calculated fee must be inside of a tolerance range with tx fee isFeeOutsideTolerance = Math.abs(resultTx.getFee().value - estimatedFeeAsLong) > 1000; } while (isFeeOutsideTolerance); // Sign all BTC inputs signAllBtcInputs(indexOfBtcFirstInput, resultTx); checkWalletConsistency(wallet); verifyTransaction(resultTx); // printTx("BTC wallet: Signed tx", resultTx); return resultTx; }
Example 16
Source File: BtcWalletService.java From bisq with GNU Affero General Public License v3.0 | 4 votes |
private Transaction addInputsForMinerFee(Transaction preparedTx, byte[] opReturnData) throws InsufficientMoneyException { // safety check counter to avoid endless loops int counter = 0; // estimated size of input sig int sigSizePerInput = 106; // typical size for a tx with 3 inputs int txSizeWithUnsignedInputs = 300; Coin txFeePerByte = feeService.getTxFeePerByte(); Address changeAddress = getFreshAddressEntry().getAddress(); checkNotNull(changeAddress, "changeAddress must not be null"); BtcCoinSelector coinSelector = new BtcCoinSelector(walletsSetup.getAddressesByContext(AddressEntry.Context.AVAILABLE), preferences.getIgnoreDustThreshold()); List<TransactionInput> preparedBsqTxInputs = preparedTx.getInputs(); List<TransactionOutput> preparedBsqTxOutputs = preparedTx.getOutputs(); int numInputs = preparedBsqTxInputs.size(); Transaction resultTx = null; boolean isFeeOutsideTolerance; do { counter++; if (counter >= 10) { checkNotNull(resultTx, "resultTx must not be null"); log.error("Could not calculate the fee. Tx=" + resultTx); break; } Transaction tx = new Transaction(params); preparedBsqTxInputs.forEach(tx::addInput); preparedBsqTxOutputs.forEach(tx::addOutput); SendRequest sendRequest = SendRequest.forTx(tx); sendRequest.shuffleOutputs = false; sendRequest.aesKey = aesKey; // signInputs needs to be false as it would try to sign all inputs (BSQ inputs are not in this wallet) sendRequest.signInputs = false; sendRequest.fee = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs); sendRequest.feePerKb = Coin.ZERO; sendRequest.ensureMinRequiredFee = false; sendRequest.coinSelector = coinSelector; sendRequest.changeAddress = changeAddress; wallet.completeTx(sendRequest); resultTx = sendRequest.tx; // add OP_RETURN output resultTx.addOutput(new TransactionOutput(params, resultTx, Coin.ZERO, ScriptBuilder.createOpReturnScript(opReturnData).getProgram())); numInputs = resultTx.getInputs().size(); txSizeWithUnsignedInputs = resultTx.bitcoinSerialize().length; final long estimatedFeeAsLong = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs).value; // calculated fee must be inside of a tolerance range with tx fee isFeeOutsideTolerance = Math.abs(resultTx.getFee().value - estimatedFeeAsLong) > 1000; } while (isFeeOutsideTolerance); return resultTx; }
Example 17
Source File: DumpTxList.java From jelectrum with MIT License | 4 votes |
public static void main(String args[]) throws Exception { Jelectrum jelly = new Jelectrum(new Config(args[0])); Scanner scan = new Scanner(new FileInputStream(args[1])); PrintStream pout = new PrintStream(new FileOutputStream(args[2], false)); TXUtil txutil = new TXUtil(jelly.getDB(), jelly.getNetworkParameters()); while(scan.hasNext()) { String hash = scan.next(); Transaction tx = jelly.getDB().getTransaction(new Sha256Hash(hash)).getTx(jelly.getNetworkParameters()); int in_idx =0; for(TransactionInput in : tx.getInputs()) { Address addr = in.getFromAddress(); byte[] h160 = addr.getHash160(); pout.println("txin:" + hash + ":" + in_idx + ":" + Hex.encodeHexString(h160)); in_idx++; /*System.out.println("Input: " + in); Script script = in.getScriptSig(); for(ScriptChunk chunk : script.getChunks()) { if (chunk.isOpCode()) { System.out.println(" op " + chunk.opcode); } if (chunk.isPushData() && (chunk.data != null)) { System.out.println(" data " + chunk.data.length); } }*/ } pout.println("tx:" + hash + ":" + txutil.getTXBlockHeight(tx, jelly.getBlockChainCache())); for(TransactionOutput out : tx.getOutputs()) { int idx = out.getIndex(); Script script = out.getScriptPubKey(); for(ScriptChunk chunk : script.getChunks()) { if (chunk.isOpCode()) { //System.out.println(" op " + chunk.opcode); } if (chunk.isPushData() && (chunk.data != null)) { pout.println("txout:" + hash + ":" + idx + ":" + Hex.encodeHexString(chunk.data)); } } } } pout.flush(); pout.close(); }
Example 18
Source File: BtcWalletService.java From bisq-core with GNU Affero General Public License v3.0 | 4 votes |
public Transaction completePreparedCompensationRequestTx(Coin issuanceAmount, Address issuanceAddress, Transaction feeTx, byte[] opReturnData) throws TransactionVerificationException, WalletException, InsufficientMoneyException { // (BsqFee)tx has following structure: // inputs [1-n] BSQ inputs (fee) // outputs [0-1] BSQ request fee change output (>= 546 Satoshi) // preparedCompensationRequestTx has following structure: // inputs [1-n] BSQ inputs for request fee // inputs [1-n] BTC inputs for BSQ issuance and miner fee // outputs [1] Mandatory BSQ request fee change output (>= 546 Satoshi) // outputs [1] Potentially BSQ issuance output (>= 546 Satoshi) // outputs [0-1] BTC change output from issuance and miner fee inputs (>= 546 Satoshi) // outputs [1] OP_RETURN with opReturnData and amount 0 // mining fee: BTC mining fee + burned BSQ fee Transaction preparedTx = new Transaction(params); // Copy inputs from BSQ fee tx feeTx.getInputs().forEach(preparedTx::addInput); int indexOfBtcFirstInput = feeTx.getInputs().size(); // Need to be first because issuance is not guaranteed to be valid and would otherwise burn change output! // BSQ change outputs from BSQ fee inputs. feeTx.getOutputs().forEach(preparedTx::addOutput); // BSQ issuance output preparedTx.addOutput(issuanceAmount, issuanceAddress); // safety check counter to avoid endless loops int counter = 0; // estimated size of input sig final int sigSizePerInput = 106; // typical size for a tx with 3 inputs int txSizeWithUnsignedInputs = 300; final Coin txFeePerByte = feeService.getTxFeePerByte(); Address changeAddress = getFreshAddressEntry().getAddress(); checkNotNull(changeAddress, "changeAddress must not be null"); final BtcCoinSelector coinSelector = new BtcCoinSelector(walletsSetup.getAddressesByContext(AddressEntry.Context.AVAILABLE)); final List<TransactionInput> preparedBsqTxInputs = preparedTx.getInputs(); final List<TransactionOutput> preparedBsqTxOutputs = preparedTx.getOutputs(); int numInputs = preparedBsqTxInputs.size(); Transaction resultTx = null; boolean isFeeOutsideTolerance; do { counter++; if (counter >= 10) { checkNotNull(resultTx, "resultTx must not be null"); log.error("Could not calculate the fee. Tx=" + resultTx); break; } Transaction tx = new Transaction(params); preparedBsqTxInputs.stream().forEach(tx::addInput); preparedBsqTxOutputs.stream().forEach(tx::addOutput); SendRequest sendRequest = SendRequest.forTx(tx); sendRequest.shuffleOutputs = false; sendRequest.aesKey = aesKey; // signInputs needs to be false as it would try to sign all inputs (BSQ inputs are not in this wallet) sendRequest.signInputs = false; sendRequest.fee = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs); sendRequest.feePerKb = Coin.ZERO; sendRequest.ensureMinRequiredFee = false; sendRequest.coinSelector = coinSelector; sendRequest.changeAddress = changeAddress; wallet.completeTx(sendRequest); resultTx = sendRequest.tx; // add OP_RETURN output resultTx.addOutput(new TransactionOutput(params, resultTx, Coin.ZERO, ScriptBuilder.createOpReturnScript(opReturnData).getProgram())); numInputs = resultTx.getInputs().size(); txSizeWithUnsignedInputs = resultTx.bitcoinSerialize().length; final long estimatedFeeAsLong = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs).value; // calculated fee must be inside of a tolerance range with tx fee isFeeOutsideTolerance = Math.abs(resultTx.getFee().value - estimatedFeeAsLong) > 1000; } while (isFeeOutsideTolerance); // Sign all BTC inputs signAllBtcInputs(indexOfBtcFirstInput, resultTx); checkWalletConsistency(wallet); verifyTransaction(resultTx); // printTx("BTC wallet: Signed tx", resultTx); return resultTx; }
Example 19
Source File: WalletService.java From bisq-core with GNU Affero General Public License v3.0 | 4 votes |
public static void removeSignatures(Transaction transaction) { for (TransactionInput input : transaction.getInputs()) { input.setScriptSig(new Script(new byte[]{})); } }