Java Code Examples for org.bitcoinj.core.TransactionInput#setScriptSig()
The following examples show how to use
org.bitcoinj.core.TransactionInput#setScriptSig() .
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: TradeWalletService.java From bisq with GNU Affero General Public License v3.0 | 6 votes |
private void signInput(Transaction transaction, TransactionInput input, int inputIndex) throws SigningException { checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null"); Script scriptPubKey = input.getConnectedOutput().getScriptPubKey(); checkNotNull(wallet); ECKey sigKey = input.getOutpoint().getConnectedKey(wallet); checkNotNull(sigKey, "signInput: sigKey must not be null. input.getOutpoint()=" + input.getOutpoint().toString()); if (sigKey.isEncrypted()) { checkNotNull(aesKey); } Sha256Hash hash = transaction.hashForSignature(inputIndex, scriptPubKey, Transaction.SigHash.ALL, false); ECKey.ECDSASignature signature = sigKey.sign(hash, aesKey); TransactionSignature txSig = new TransactionSignature(signature, Transaction.SigHash.ALL, false); if (scriptPubKey.isSentToRawPubKey()) { input.setScriptSig(ScriptBuilder.createInputScript(txSig)); } else if (scriptPubKey.isSentToAddress()) { input.setScriptSig(ScriptBuilder.createInputScript(txSig, sigKey)); } else { throw new SigningException("Don't know how to sign for this kind of scriptPubKey: " + scriptPubKey); } }
Example 2
Source File: TradeWalletService.java From bisq-core with GNU Affero General Public License v3.0 | 6 votes |
private void signInput(Transaction transaction, TransactionInput input, int inputIndex) throws SigningException { checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null"); Script scriptPubKey = input.getConnectedOutput().getScriptPubKey(); checkNotNull(wallet); ECKey sigKey = input.getOutpoint().getConnectedKey(wallet); checkNotNull(sigKey, "signInput: sigKey must not be null. input.getOutpoint()=" + input.getOutpoint().toString()); if (sigKey.isEncrypted()) checkNotNull(aesKey); Sha256Hash hash = transaction.hashForSignature(inputIndex, scriptPubKey, Transaction.SigHash.ALL, false); ECKey.ECDSASignature signature = sigKey.sign(hash, aesKey); TransactionSignature txSig = new TransactionSignature(signature, Transaction.SigHash.ALL, false); if (scriptPubKey.isSentToRawPubKey()) { input.setScriptSig(ScriptBuilder.createInputScript(txSig)); } else if (scriptPubKey.isSentToAddress()) { input.setScriptSig(ScriptBuilder.createInputScript(txSig, sigKey)); } else { throw new SigningException("Don't know how to sign for this kind of scriptPubKey: " + scriptPubKey); } }
Example 3
Source File: TradeWalletService.java From bisq with GNU Affero General Public License v3.0 | 6 votes |
public Transaction finalizeDelayedPayoutTx(Transaction delayedPayoutTx, byte[] buyerPubKey, byte[] sellerPubKey, byte[] buyerSignature, byte[] sellerSignature) throws AddressFormatException, TransactionVerificationException, WalletException { Script redeemScript = get2of2MultiSigRedeemScript(buyerPubKey, sellerPubKey); ECKey.ECDSASignature buyerECDSASignature = ECKey.ECDSASignature.decodeFromDER(buyerSignature); ECKey.ECDSASignature sellerECDSASignature = ECKey.ECDSASignature.decodeFromDER(sellerSignature); TransactionSignature buyerTxSig = new TransactionSignature(buyerECDSASignature, Transaction.SigHash.ALL, false); TransactionSignature sellerTxSig = new TransactionSignature(sellerECDSASignature, Transaction.SigHash.ALL, false); Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(sellerTxSig, buyerTxSig), redeemScript); TransactionInput input = delayedPayoutTx.getInput(0); input.setScriptSig(inputScript); WalletService.printTx("finalizeDelayedPayoutTx", delayedPayoutTx); WalletService.verifyTransaction(delayedPayoutTx); WalletService.checkWalletConsistency(wallet); WalletService.checkScriptSig(delayedPayoutTx, input, 0); checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null"); input.verify(input.getConnectedOutput()); return delayedPayoutTx; }
Example 4
Source File: TradeWalletService.java From bisq with GNU Affero General Public License v3.0 | 5 votes |
public Transaction finalizeMediatedPayoutTx(Transaction depositTx, byte[] buyerSignature, byte[] sellerSignature, Coin buyerPayoutAmount, Coin sellerPayoutAmount, String buyerPayoutAddressString, String sellerPayoutAddressString, DeterministicKey multiSigKeyPair, byte[] buyerPubKey, byte[] sellerPubKey) throws AddressFormatException, TransactionVerificationException, WalletException { Transaction payoutTx = createPayoutTx(depositTx, buyerPayoutAmount, sellerPayoutAmount, buyerPayoutAddressString, sellerPayoutAddressString); // MS redeemScript Script redeemScript = get2of2MultiSigRedeemScript(buyerPubKey, sellerPubKey); // MS output from prev. tx is index 0 checkNotNull(multiSigKeyPair, "multiSigKeyPair must not be null"); TransactionSignature buyerTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(buyerSignature), Transaction.SigHash.ALL, false); TransactionSignature sellerTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(sellerSignature), Transaction.SigHash.ALL, false); // Take care of order of signatures. Need to be reversed here. See comment below at getMultiSigRedeemScript (seller, buyer) Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(sellerTxSig, buyerTxSig), redeemScript); TransactionInput input = payoutTx.getInput(0); input.setScriptSig(inputScript); WalletService.printTx("mediated payoutTx", payoutTx); WalletService.verifyTransaction(payoutTx); WalletService.checkWalletConsistency(wallet); WalletService.checkScriptSig(payoutTx, input, 0); checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null"); input.verify(input.getConnectedOutput()); return payoutTx; }
Example 5
Source File: TradeWalletService.java From bisq with GNU Affero General Public License v3.0 | 5 votes |
/** * Seller creates and signs payout transaction and adds signature of buyer to complete the transaction. * * @param depositTx deposit transaction * @param buyerSignature DER encoded canonical signature of buyer * @param buyerPayoutAmount payout amount for buyer * @param sellerPayoutAmount payout amount for seller * @param buyerPayoutAddressString address for buyer * @param sellerPayoutAddressString address for seller * @param multiSigKeyPair seller's key pair for MultiSig * @param buyerPubKey the public key of the buyer * @param sellerPubKey the public key of the seller * @return the payout transaction * @throws AddressFormatException if the buyer or seller base58 address doesn't parse or its checksum is invalid * @throws TransactionVerificationException if there was an unexpected problem with the payout tx or its signatures * @throws WalletException if the seller's wallet is null or structurally inconsistent */ public Transaction sellerSignsAndFinalizesPayoutTx(Transaction depositTx, byte[] buyerSignature, Coin buyerPayoutAmount, Coin sellerPayoutAmount, String buyerPayoutAddressString, String sellerPayoutAddressString, DeterministicKey multiSigKeyPair, byte[] buyerPubKey, byte[] sellerPubKey) throws AddressFormatException, TransactionVerificationException, WalletException { Transaction payoutTx = createPayoutTx(depositTx, buyerPayoutAmount, sellerPayoutAmount, buyerPayoutAddressString, sellerPayoutAddressString); // MS redeemScript Script redeemScript = get2of2MultiSigRedeemScript(buyerPubKey, sellerPubKey); // MS output from prev. tx is index 0 Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); checkNotNull(multiSigKeyPair, "multiSigKeyPair must not be null"); if (multiSigKeyPair.isEncrypted()) { checkNotNull(aesKey); } ECKey.ECDSASignature sellerSignature = multiSigKeyPair.sign(sigHash, aesKey).toCanonicalised(); TransactionSignature buyerTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(buyerSignature), Transaction.SigHash.ALL, false); TransactionSignature sellerTxSig = new TransactionSignature(sellerSignature, Transaction.SigHash.ALL, false); // Take care of order of signatures. Need to be reversed here. See comment below at getMultiSigRedeemScript (seller, buyer) Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(sellerTxSig, buyerTxSig), redeemScript); TransactionInput input = payoutTx.getInput(0); input.setScriptSig(inputScript); WalletService.printTx("payoutTx", payoutTx); WalletService.verifyTransaction(payoutTx); WalletService.checkWalletConsistency(wallet); WalletService.checkScriptSig(payoutTx, input, 0); checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null"); input.verify(input.getConnectedOutput()); return payoutTx; }
Example 6
Source File: GenerateLowSTests.java From green_android with GNU General Public License v3.0 | 5 votes |
private static void addOutputs(final Transaction outputTransaction, final KeyBag bag) throws ScriptException { int numInputs = outputTransaction.getInputs().size(); for (int i = 0; i < numInputs; i++) { TransactionInput txIn = outputTransaction.getInput(i); Script scriptPubKey = txIn.getConnectedOutput().getScriptPubKey(); RedeemData redeemData = txIn.getConnectedRedeemData(bag); checkNotNull(redeemData, "Transaction exists in wallet that we cannot redeem: %s", txIn.getOutpoint().getHash()); txIn.setScriptSig(scriptPubKey.createEmptyInputScript(redeemData.keys.get(0), redeemData.redeemScript)); } }
Example 7
Source File: GenerateLowSTests.java From GreenBits with GNU General Public License v3.0 | 5 votes |
private static void addOutputs(final Transaction outputTransaction, final KeyBag bag) throws ScriptException { int numInputs = outputTransaction.getInputs().size(); for (int i = 0; i < numInputs; i++) { TransactionInput txIn = outputTransaction.getInput(i); Script scriptPubKey = txIn.getConnectedOutput().getScriptPubKey(); RedeemData redeemData = txIn.getConnectedRedeemData(bag); checkNotNull(redeemData, "Transaction exists in wallet that we cannot redeem: %s", txIn.getOutpoint().getHash()); txIn.setScriptSig(scriptPubKey.createEmptyInputScript(redeemData.keys.get(0), redeemData.redeemScript)); } }
Example 8
Source File: GenerateLowSTests.java From GreenBits with GNU General Public License v3.0 | 4 votes |
public static void main(final String[] argv) throws NoSuchAlgorithmException, IOException { final NetworkParameters params = new MainNetParams(); final LocalTransactionSigner signer = new LocalTransactionSigner(); final SecureRandom secureRandom = SecureRandom.getInstanceStrong(); final ECKey key = new ECKey(secureRandom); final KeyBag bag = new KeyBag() { @Override public ECKey findKeyFromPubHash(byte[] pubkeyHash) { return key; } @Override public ECKey findKeyFromPubKey(byte[] pubkey) { return key; } @Override public RedeemData findRedeemDataFromScriptHash(byte[] scriptHash) { return null; } }; // Generate a fictional output transaction we take values from, and // an input transaction for the test case final Transaction outputTransaction = new Transaction(params); final Transaction inputTransaction = new Transaction(params); final TransactionOutput output = new TransactionOutput(params, inputTransaction, Coin.ZERO, key.toAddress(params)); inputTransaction.addOutput(output); outputTransaction.addInput(output); outputTransaction.addOutput(Coin.ZERO, new ECKey(secureRandom).toAddress(params)); addOutputs(outputTransaction, bag); // Sign the transaction final ProposedTransaction proposedTransaction = new ProposedTransaction(outputTransaction); signer.signInputs(proposedTransaction, bag); final TransactionInput input = proposedTransaction.partialTx.getInput(0); input.verify(output); input.getScriptSig().correctlySpends(outputTransaction, 0, output.getScriptPubKey(), EnumSet.of(Script.VerifyFlag.DERSIG, Script.VerifyFlag.P2SH)); final Script scriptSig = input.getScriptSig(); final TransactionSignature signature = TransactionSignature.decodeFromBitcoin(scriptSig.getChunks().get(0).data, true, false); // First output a conventional low-S transaction with the LOW_S flag, for the tx_valid.json set System.out.println("[\"A transaction with a low-S signature.\"],"); System.out.println("[[[\"" + inputTransaction.getHashAsString() + "\", " + output.getIndex() + ", \"" + scriptToString(output.getScriptPubKey()) + "\"]],\n" + "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \"" + Script.VerifyFlag.P2SH.name() + "," + Script.VerifyFlag.LOW_S.name() + "\"],"); final BigInteger highS = HIGH_S_DIFFERENCE.subtract(signature.s); final TransactionSignature highSig = new TransactionSignature(signature.r, highS); input.setScriptSig(new ScriptBuilder().data(highSig.encodeToBitcoin()).data(scriptSig.getChunks().get(1).data).build()); input.getScriptSig().correctlySpends(outputTransaction, 0, output.getScriptPubKey(), EnumSet.of(Script.VerifyFlag.P2SH)); // A high-S transaction without the LOW_S flag, for the tx_valid.json set System.out.println("[\"A transaction with a high-S signature.\"],"); System.out.println("[[[\"" + inputTransaction.getHashAsString() + "\", " + output.getIndex() + ", \"" + scriptToString(output.getScriptPubKey()) + "\"]],\n" + "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \"" + Script.VerifyFlag.P2SH.name() + "\"],"); // Lastly a conventional high-S transaction with the LOW_S flag, for the tx_invalid.json set System.out.println("[\"A transaction with a high-S signature.\"],"); System.out.println("[[[\"" + inputTransaction.getHashAsString() + "\", " + output.getIndex() + ", \"" + scriptToString(output.getScriptPubKey()) + "\"]],\n" + "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \"" + Script.VerifyFlag.P2SH.name() + "," + Script.VerifyFlag.LOW_S.name() + "\"],"); }
Example 9
Source File: TradeWalletService.java From bisq with GNU Affero General Public License v3.0 | 4 votes |
public void emergencySignAndPublishPayoutTxFrom2of2MultiSig(String depositTxHex, Coin buyerPayoutAmount, Coin sellerPayoutAmount, Coin txFee, String buyerAddressString, String sellerAddressString, String buyerPrivateKeyAsHex, String sellerPrivateKeyAsHex, String buyerPubKeyAsHex, String sellerPubKeyAsHex, TxBroadcaster.Callback callback) throws AddressFormatException, TransactionVerificationException, WalletException { byte[] buyerPubKey = ECKey.fromPublicOnly(Utils.HEX.decode(buyerPubKeyAsHex)).getPubKey(); byte[] sellerPubKey = ECKey.fromPublicOnly(Utils.HEX.decode(sellerPubKeyAsHex)).getPubKey(); Script p2SHMultiSigOutputScript = get2of2MultiSigOutputScript(buyerPubKey, sellerPubKey); Coin msOutput = buyerPayoutAmount.add(sellerPayoutAmount).add(txFee); TransactionOutput p2SHMultiSigOutput = new TransactionOutput(params, null, msOutput, p2SHMultiSigOutputScript.getProgram()); Transaction depositTx = new Transaction(params); depositTx.addOutput(p2SHMultiSigOutput); Transaction payoutTx = new Transaction(params); Sha256Hash spendTxHash = Sha256Hash.wrap(depositTxHex); payoutTx.addInput(new TransactionInput(params, depositTx, p2SHMultiSigOutputScript.getProgram(), new TransactionOutPoint(params, 0, spendTxHash), msOutput)); if (buyerPayoutAmount.isPositive()) { payoutTx.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString)); } if (sellerPayoutAmount.isPositive()) { payoutTx.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString)); } // take care of sorting! Script redeemScript = get2of2MultiSigRedeemScript(buyerPubKey, sellerPubKey); Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); ECKey buyerPrivateKey = ECKey.fromPrivate(Utils.HEX.decode(buyerPrivateKeyAsHex)); checkNotNull(buyerPrivateKey, "key must not be null"); ECKey.ECDSASignature buyerECDSASignature = buyerPrivateKey.sign(sigHash, aesKey).toCanonicalised(); ECKey sellerPrivateKey = ECKey.fromPrivate(Utils.HEX.decode(sellerPrivateKeyAsHex)); checkNotNull(sellerPrivateKey, "key must not be null"); ECKey.ECDSASignature sellerECDSASignature = sellerPrivateKey.sign(sigHash, aesKey).toCanonicalised(); TransactionSignature buyerTxSig = new TransactionSignature(buyerECDSASignature, Transaction.SigHash.ALL, false); TransactionSignature sellerTxSig = new TransactionSignature(sellerECDSASignature, Transaction.SigHash.ALL, false); Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(sellerTxSig, buyerTxSig), redeemScript); TransactionInput input = payoutTx.getInput(0); input.setScriptSig(inputScript); WalletService.printTx("payoutTx", payoutTx); WalletService.verifyTransaction(payoutTx); WalletService.checkWalletConsistency(wallet); broadcastTx(payoutTx, callback, 20); }
Example 10
Source File: TradeWalletService.java From bisq with GNU Affero General Public License v3.0 | 4 votes |
/** * A trader who got the signed tx from the arbitrator finalizes the payout tx. * * @param depositTxSerialized serialized deposit tx * @param arbitratorSignature DER encoded canonical signature of arbitrator * @param buyerPayoutAmount payout amount of the buyer * @param sellerPayoutAmount payout amount of the seller * @param buyerAddressString the address of the buyer * @param sellerAddressString the address of the seller * @param tradersMultiSigKeyPair the key pair for the MultiSig of the trader who calls that method * @param buyerPubKey the public key of the buyer * @param sellerPubKey the public key of the seller * @param arbitratorPubKey the public key of the arbitrator * @return the completed payout tx * @throws AddressFormatException if the buyer or seller base58 address doesn't parse or its checksum is invalid * @throws TransactionVerificationException if there was an unexpected problem with the payout tx or its signature * @throws WalletException if the trade wallet is null or structurally inconsistent */ public Transaction traderSignAndFinalizeDisputedPayoutTx(byte[] depositTxSerialized, byte[] arbitratorSignature, Coin buyerPayoutAmount, Coin sellerPayoutAmount, String buyerAddressString, String sellerAddressString, DeterministicKey tradersMultiSigKeyPair, byte[] buyerPubKey, byte[] sellerPubKey, byte[] arbitratorPubKey) throws AddressFormatException, TransactionVerificationException, WalletException { Transaction depositTx = new Transaction(params, depositTxSerialized); TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0); Transaction payoutTx = new Transaction(params); payoutTx.addInput(p2SHMultiSigOutput); if (buyerPayoutAmount.isPositive()) { payoutTx.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString)); } if (sellerPayoutAmount.isPositive()) { payoutTx.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString)); } // take care of sorting! Script redeemScript = get2of3MultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); checkNotNull(tradersMultiSigKeyPair, "tradersMultiSigKeyPair must not be null"); if (tradersMultiSigKeyPair.isEncrypted()) { checkNotNull(aesKey); } ECKey.ECDSASignature tradersSignature = tradersMultiSigKeyPair.sign(sigHash, aesKey).toCanonicalised(); TransactionSignature tradersTxSig = new TransactionSignature(tradersSignature, Transaction.SigHash.ALL, false); TransactionSignature arbitratorTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(arbitratorSignature), Transaction.SigHash.ALL, false); // Take care of order of signatures. See comment below at getMultiSigRedeemScript (sort order needed here: arbitrator, seller, buyer) Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(arbitratorTxSig, tradersTxSig), redeemScript); TransactionInput input = payoutTx.getInput(0); input.setScriptSig(inputScript); WalletService.printTx("disputed payoutTx", payoutTx); WalletService.verifyTransaction(payoutTx); WalletService.checkWalletConsistency(wallet); WalletService.checkScriptSig(payoutTx, input, 0); checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null"); input.verify(input.getConnectedOutput()); return payoutTx; }
Example 11
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 12
Source File: MissingSigResolutionSigner.java From GreenBits with GNU General Public License v3.0 | 4 votes |
@Override public boolean signInputs(ProposedTransaction propTx, KeyBag keyBag) { if (missingSigsMode == Wallet.MissingSigsMode.USE_OP_ZERO) return true; int numInputs = propTx.partialTx.getInputs().size(); byte[] dummySig = TransactionSignature.dummy().encodeToBitcoin(); for (int i = 0; i < numInputs; i++) { TransactionInput txIn = propTx.partialTx.getInput(i); if (txIn.getConnectedOutput() == null) { log.warn("Missing connected output, assuming input {} is already signed.", i); continue; } Script scriptPubKey = txIn.getConnectedOutput().getScriptPubKey(); Script inputScript = txIn.getScriptSig(); if (scriptPubKey.isPayToScriptHash() || scriptPubKey.isSentToMultiSig()) { int sigSuffixCount = scriptPubKey.isPayToScriptHash() ? 1 : 0; // all chunks except the first one (OP_0) and the last (redeem script) are signatures for (int j = 1; j < inputScript.getChunks().size() - sigSuffixCount; j++) { ScriptChunk scriptChunk = inputScript.getChunks().get(j); if (scriptChunk.equalsOpCode(0)) { if (missingSigsMode == Wallet.MissingSigsMode.THROW) { throw new MissingSignatureException(); } else if (missingSigsMode == Wallet.MissingSigsMode.USE_DUMMY_SIG) { txIn.setScriptSig(scriptPubKey.getScriptSigWithSignature(inputScript, dummySig, j - 1)); } } } } else { if (inputScript.getChunks().get(0).equalsOpCode(0)) { if (missingSigsMode == Wallet.MissingSigsMode.THROW) { throw new ECKey.MissingPrivateKeyException(); } else if (missingSigsMode == Wallet.MissingSigsMode.USE_DUMMY_SIG) { txIn.setScriptSig(scriptPubKey.getScriptSigWithSignature(inputScript, dummySig, 0)); } } } // TODO handle non-P2SH multisig } return true; }
Example 13
Source File: MissingSigResolutionSigner.java From bcm-android with GNU General Public License v3.0 | 4 votes |
@Override public boolean signInputs(ProposedTransaction propTx, KeyBag keyBag) { if (missingSigsMode == Wallet.MissingSigsMode.USE_OP_ZERO) return true; int numInputs = propTx.partialTx.getInputs().size(); byte[] dummySig = TransactionSignature.dummy().encodeToBitcoin(); for (int i = 0; i < numInputs; i++) { TransactionInput txIn = propTx.partialTx.getInput(i); if (txIn.getConnectedOutput() == null) { log.warn("Missing connected output, assuming input {} is already signed.", i); continue; } Script scriptPubKey = txIn.getConnectedOutput().getScriptPubKey(); Script inputScript = txIn.getScriptSig(); if (ScriptPattern.isPayToScriptHash(scriptPubKey) || ScriptPattern.isSentToMultisig(scriptPubKey)) { int sigSuffixCount = ScriptPattern.isPayToScriptHash(scriptPubKey) ? 1 : 0; // all chunks except the first one (OP_0) and the last (redeem script) are signatures for (int j = 1; j < inputScript.getChunks().size() - sigSuffixCount; j++) { ScriptChunk scriptChunk = inputScript.getChunks().get(j); if (scriptChunk.equalsOpCode(0)) { if (missingSigsMode == Wallet.MissingSigsMode.THROW) { throw new MissingSignatureException(); } else if (missingSigsMode == Wallet.MissingSigsMode.USE_DUMMY_SIG) { txIn.setScriptSig(scriptPubKey.getScriptSigWithSignature(inputScript, dummySig, j - 1)); } } } } else { if (inputScript.getChunks().get(0).equalsOpCode(0)) { if (missingSigsMode == Wallet.MissingSigsMode.THROW) { throw new ECKey.MissingPrivateKeyException(); } else if (missingSigsMode == Wallet.MissingSigsMode.USE_DUMMY_SIG) { txIn.setScriptSig(scriptPubKey.getScriptSigWithSignature(inputScript, dummySig, 0)); } } } // TODO handle non-P2SH multisig } return true; }
Example 14
Source File: MissingSigResolutionSigner.java From green_android with GNU General Public License v3.0 | 4 votes |
@Override public boolean signInputs(ProposedTransaction propTx, KeyBag keyBag) { if (missingSigsMode == Wallet.MissingSigsMode.USE_OP_ZERO) return true; int numInputs = propTx.partialTx.getInputs().size(); byte[] dummySig = TransactionSignature.dummy().encodeToBitcoin(); for (int i = 0; i < numInputs; i++) { TransactionInput txIn = propTx.partialTx.getInput(i); if (txIn.getConnectedOutput() == null) { log.warn("Missing connected output, assuming input {} is already signed.", i); continue; } Script scriptPubKey = txIn.getConnectedOutput().getScriptPubKey(); Script inputScript = txIn.getScriptSig(); if (scriptPubKey.isPayToScriptHash() || scriptPubKey.isSentToMultiSig()) { int sigSuffixCount = scriptPubKey.isPayToScriptHash() ? 1 : 0; // all chunks except the first one (OP_0) and the last (redeem script) are signatures for (int j = 1; j < inputScript.getChunks().size() - sigSuffixCount; j++) { ScriptChunk scriptChunk = inputScript.getChunks().get(j); if (scriptChunk.equalsOpCode(0)) { if (missingSigsMode == Wallet.MissingSigsMode.THROW) { throw new MissingSignatureException(); } else if (missingSigsMode == Wallet.MissingSigsMode.USE_DUMMY_SIG) { txIn.setScriptSig(scriptPubKey.getScriptSigWithSignature(inputScript, dummySig, j - 1)); } } } } else { if (inputScript.getChunks().get(0).equalsOpCode(0)) { if (missingSigsMode == Wallet.MissingSigsMode.THROW) { throw new ECKey.MissingPrivateKeyException(); } else if (missingSigsMode == Wallet.MissingSigsMode.USE_DUMMY_SIG) { txIn.setScriptSig(scriptPubKey.getScriptSigWithSignature(inputScript, dummySig, 0)); } } } // TODO handle non-P2SH multisig } return true; }
Example 15
Source File: GenerateLowSTests.java From green_android with GNU General Public License v3.0 | 4 votes |
public static void main(final String[] argv) throws NoSuchAlgorithmException, IOException { final NetworkParameters params = new MainNetParams(); final LocalTransactionSigner signer = new LocalTransactionSigner(); final SecureRandom secureRandom = SecureRandom.getInstanceStrong(); final ECKey key = new ECKey(secureRandom); final KeyBag bag = new KeyBag() { @Override public ECKey findKeyFromPubHash(byte[] pubkeyHash) { return key; } @Override public ECKey findKeyFromPubKey(byte[] pubkey) { return key; } @Override public RedeemData findRedeemDataFromScriptHash(byte[] scriptHash) { return null; } }; // Generate a fictional output transaction we take values from, and // an input transaction for the test case final Transaction outputTransaction = new Transaction(params); final Transaction inputTransaction = new Transaction(params); final TransactionOutput output = new TransactionOutput(params, inputTransaction, Coin.ZERO, key.toAddress(params)); inputTransaction.addOutput(output); outputTransaction.addInput(output); outputTransaction.addOutput(Coin.ZERO, new ECKey(secureRandom).toAddress(params)); addOutputs(outputTransaction, bag); // Sign the transaction final ProposedTransaction proposedTransaction = new ProposedTransaction(outputTransaction); signer.signInputs(proposedTransaction, bag); final TransactionInput input = proposedTransaction.partialTx.getInput(0); input.verify(output); input.getScriptSig().correctlySpends(outputTransaction, 0, output.getScriptPubKey(), EnumSet.of(Script.VerifyFlag.DERSIG, Script.VerifyFlag.P2SH)); final Script scriptSig = input.getScriptSig(); final TransactionSignature signature = TransactionSignature.decodeFromBitcoin(scriptSig.getChunks().get(0).data, true, false); // First output a conventional low-S transaction with the LOW_S flag, for the tx_valid.json set System.out.println("[\"A transaction with a low-S signature.\"],"); System.out.println("[[[\"" + inputTransaction.getHashAsString() + "\", " + output.getIndex() + ", \"" + scriptToString(output.getScriptPubKey()) + "\"]],\n" + "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \"" + Script.VerifyFlag.P2SH.name() + "," + Script.VerifyFlag.LOW_S.name() + "\"],"); final BigInteger highS = HIGH_S_DIFFERENCE.subtract(signature.s); final TransactionSignature highSig = new TransactionSignature(signature.r, highS); input.setScriptSig(new ScriptBuilder().data(highSig.encodeToBitcoin()).data(scriptSig.getChunks().get(1).data).build()); input.getScriptSig().correctlySpends(outputTransaction, 0, output.getScriptPubKey(), EnumSet.of(Script.VerifyFlag.P2SH)); // A high-S transaction without the LOW_S flag, for the tx_valid.json set System.out.println("[\"A transaction with a high-S signature.\"],"); System.out.println("[[[\"" + inputTransaction.getHashAsString() + "\", " + output.getIndex() + ", \"" + scriptToString(output.getScriptPubKey()) + "\"]],\n" + "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \"" + Script.VerifyFlag.P2SH.name() + "\"],"); // Lastly a conventional high-S transaction with the LOW_S flag, for the tx_invalid.json set System.out.println("[\"A transaction with a high-S signature.\"],"); System.out.println("[[[\"" + inputTransaction.getHashAsString() + "\", " + output.getIndex() + ", \"" + scriptToString(output.getScriptPubKey()) + "\"]],\n" + "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \"" + Script.VerifyFlag.P2SH.name() + "," + Script.VerifyFlag.LOW_S.name() + "\"],"); }
Example 16
Source File: TradeWalletService.java From bisq-core with GNU Affero General Public License v3.0 | 4 votes |
public Transaction emergencySignAndPublishPayoutTx(String depositTxHex, Coin buyerPayoutAmount, Coin sellerPayoutAmount, Coin arbitratorPayoutAmount, Coin txFee, String buyerAddressString, String sellerAddressString, String arbitratorAddressString, @Nullable String buyerPrivateKeyAsHex, @Nullable String sellerPrivateKeyAsHex, String arbitratorPrivateKeyAsHex, String buyerPubKeyAsHex, String sellerPubKeyAsHex, String arbitratorPubKeyAsHex, String P2SHMultiSigOutputScript, TxBroadcaster.Callback callback) throws AddressFormatException, TransactionVerificationException, WalletException { log.info("signAndPublishPayoutTx called"); log.info("depositTxHex " + depositTxHex); log.info("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString()); log.info("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString()); log.info("arbitratorPayoutAmount " + arbitratorPayoutAmount.toFriendlyString()); log.info("buyerAddressString " + buyerAddressString); log.info("sellerAddressString " + sellerAddressString); log.info("arbitratorAddressString " + arbitratorAddressString); log.info("buyerPrivateKeyAsHex (not displayed for security reasons)"); log.info("sellerPrivateKeyAsHex (not displayed for security reasons)"); log.info("arbitratorPrivateKeyAsHex (not displayed for security reasons)"); log.info("buyerPubKeyAsHex " + buyerPubKeyAsHex); log.info("sellerPubKeyAsHex " + sellerPubKeyAsHex); log.info("arbitratorPubKeyAsHex " + arbitratorPubKeyAsHex); log.info("P2SHMultiSigOutputScript " + P2SHMultiSigOutputScript); checkNotNull((buyerPrivateKeyAsHex != null || sellerPrivateKeyAsHex != null), "either buyerPrivateKeyAsHex or sellerPrivateKeyAsHex must not be null"); byte[] buyerPubKey = ECKey.fromPublicOnly(Utils.HEX.decode(buyerPubKeyAsHex)).getPubKey(); byte[] sellerPubKey = ECKey.fromPublicOnly(Utils.HEX.decode(sellerPubKeyAsHex)).getPubKey(); final byte[] arbitratorPubKey = ECKey.fromPublicOnly(Utils.HEX.decode(arbitratorPubKeyAsHex)).getPubKey(); Script p2SHMultiSigOutputScript = getP2SHMultiSigOutputScript(buyerPubKey, sellerPubKey, arbitratorPubKey); Coin msOutput = buyerPayoutAmount.add(sellerPayoutAmount).add(arbitratorPayoutAmount).add(txFee); TransactionOutput p2SHMultiSigOutput = new TransactionOutput(params, null, msOutput, p2SHMultiSigOutputScript.getProgram()); Transaction depositTx = new Transaction(params); depositTx.addOutput(p2SHMultiSigOutput); Transaction payoutTx = new Transaction(params); Sha256Hash spendTxHash = Sha256Hash.wrap(depositTxHex); payoutTx.addInput(new TransactionInput(params, depositTx, p2SHMultiSigOutputScript.getProgram(), new TransactionOutPoint(params, 0, spendTxHash), msOutput)); if (buyerPayoutAmount.isGreaterThan(Coin.ZERO)) payoutTx.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString)); if (sellerPayoutAmount.isGreaterThan(Coin.ZERO)) payoutTx.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString)); if (arbitratorPayoutAmount.isGreaterThan(Coin.ZERO)) payoutTx.addOutput(arbitratorPayoutAmount, Address.fromBase58(params, arbitratorAddressString)); // take care of sorting! Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); ECKey.ECDSASignature tradersSignature; if (buyerPrivateKeyAsHex != null && !buyerPrivateKeyAsHex.isEmpty()) { final ECKey buyerPrivateKey = ECKey.fromPrivate(Utils.HEX.decode(buyerPrivateKeyAsHex)); checkNotNull(buyerPrivateKey, "buyerPrivateKey must not be null"); tradersSignature = buyerPrivateKey.sign(sigHash, aesKey).toCanonicalised(); } else { checkNotNull(sellerPrivateKeyAsHex, "sellerPrivateKeyAsHex must not be null"); final ECKey sellerPrivateKey = ECKey.fromPrivate(Utils.HEX.decode(sellerPrivateKeyAsHex)); checkNotNull(sellerPrivateKey, "sellerPrivateKey must not be null"); tradersSignature = sellerPrivateKey.sign(sigHash, aesKey).toCanonicalised(); } final ECKey key = ECKey.fromPrivate(Utils.HEX.decode(arbitratorPrivateKeyAsHex)); checkNotNull(key, "key must not be null"); ECKey.ECDSASignature arbitratorSignature = key.sign(sigHash, aesKey).toCanonicalised(); TransactionSignature tradersTxSig = new TransactionSignature(tradersSignature, Transaction.SigHash.ALL, false); TransactionSignature arbitratorTxSig = new TransactionSignature(arbitratorSignature, Transaction.SigHash.ALL, false); // Take care of order of signatures. See comment below at getMultiSigRedeemScript (sort order needed here: arbitrator, seller, buyer) Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(arbitratorTxSig, tradersTxSig), redeemScript); TransactionInput input = payoutTx.getInput(0); input.setScriptSig(inputScript); WalletService.printTx("payoutTx", payoutTx); WalletService.verifyTransaction(payoutTx); WalletService.checkWalletConsistency(wallet); broadcastTx(payoutTx, callback, 20); return payoutTx; }
Example 17
Source File: TradeWalletService.java From bisq-core with GNU Affero General Public License v3.0 | 4 votes |
/** * A trader who got the signed tx from the arbitrator finalizes the payout tx * * @param depositTxSerialized Serialized deposit tx * @param arbitratorSignature DER encoded canonical signature of arbitrator * @param buyerPayoutAmount Payout amount of the buyer * @param sellerPayoutAmount Payout amount of the seller * @param buyerAddressString The address of the buyer. * @param sellerAddressString The address of the seller. * @param tradersMultiSigKeyPair The keypair for the MultiSig of the trader who calls that method * @param buyerPubKey The public key of the buyer. * @param sellerPubKey The public key of the seller. * @param arbitratorPubKey The public key of the arbitrator. * @return The completed payout tx * @throws AddressFormatException * @throws TransactionVerificationException * @throws WalletException */ public Transaction traderSignAndFinalizeDisputedPayoutTx(byte[] depositTxSerialized, byte[] arbitratorSignature, Coin buyerPayoutAmount, Coin sellerPayoutAmount, String buyerAddressString, String sellerAddressString, DeterministicKey tradersMultiSigKeyPair, byte[] buyerPubKey, byte[] sellerPubKey, byte[] arbitratorPubKey) throws AddressFormatException, TransactionVerificationException, WalletException { Transaction depositTx = new Transaction(params, depositTxSerialized); log.trace("signAndFinalizeDisputedPayoutTx called"); log.trace("depositTx " + depositTx); log.trace("arbitratorSignature r " + ECKey.ECDSASignature.decodeFromDER(arbitratorSignature).r.toString()); log.trace("arbitratorSignature s " + ECKey.ECDSASignature.decodeFromDER(arbitratorSignature).s.toString()); log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString()); log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString()); log.trace("buyerAddressString " + buyerAddressString); log.trace("sellerAddressString " + sellerAddressString); log.trace("tradersMultiSigKeyPair (not displayed for security reasons)"); log.info("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString()); log.info("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString()); log.info("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString()); TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0); Transaction payoutTx = new Transaction(params); payoutTx.addInput(p2SHMultiSigOutput); if (buyerPayoutAmount.isGreaterThan(Coin.ZERO)) payoutTx.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString)); if (sellerPayoutAmount.isGreaterThan(Coin.ZERO)) payoutTx.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString)); // take care of sorting! Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); checkNotNull(tradersMultiSigKeyPair, "tradersMultiSigKeyPair must not be null"); if (tradersMultiSigKeyPair.isEncrypted()) checkNotNull(aesKey); ECKey.ECDSASignature tradersSignature = tradersMultiSigKeyPair.sign(sigHash, aesKey).toCanonicalised(); TransactionSignature tradersTxSig = new TransactionSignature(tradersSignature, Transaction.SigHash.ALL, false); TransactionSignature arbitratorTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(arbitratorSignature), Transaction.SigHash.ALL, false); // Take care of order of signatures. See comment below at getMultiSigRedeemScript (sort order needed here: arbitrator, seller, buyer) Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(arbitratorTxSig, tradersTxSig), redeemScript); TransactionInput input = payoutTx.getInput(0); input.setScriptSig(inputScript); WalletService.printTx("disputed payoutTx", payoutTx); WalletService.verifyTransaction(payoutTx); WalletService.checkWalletConsistency(wallet); WalletService.checkScriptSig(payoutTx, input, 0); checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null"); input.verify(input.getConnectedOutput()); return payoutTx; }
Example 18
Source File: TradeWalletService.java From bisq-core with GNU Affero General Public License v3.0 | 4 votes |
/** * Buyer creates and signs payout transaction and adds signature of seller to complete the transaction * * @param depositTx Deposit transaction * @param buyerSignature DER encoded canonical signature of seller * @param buyerPayoutAmount Payout amount for buyer * @param sellerPayoutAmount Payout amount for seller * @param buyerPayoutAddressString Address for buyer * @param sellerPayoutAddressString Address for seller * @param multiSigKeyPair Buyer's keypair for MultiSig * @param buyerPubKey The public key of the buyer. * @param sellerPubKey The public key of the seller. * @param arbitratorPubKey The public key of the arbitrator. * @return The payout transaction * @throws AddressFormatException * @throws TransactionVerificationException * @throws WalletException */ public Transaction sellerSignsAndFinalizesPayoutTx(Transaction depositTx, byte[] buyerSignature, Coin buyerPayoutAmount, Coin sellerPayoutAmount, String buyerPayoutAddressString, String sellerPayoutAddressString, DeterministicKey multiSigKeyPair, byte[] buyerPubKey, byte[] sellerPubKey, byte[] arbitratorPubKey) throws AddressFormatException, TransactionVerificationException, WalletException { log.trace("buyerSignsAndFinalizesPayoutTx called"); log.trace("depositTx " + depositTx.toString()); log.trace("buyerSignature r " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).r.toString()); log.trace("buyerSignature s " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).s.toString()); log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString()); log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString()); log.trace("buyerPayoutAddressString " + buyerPayoutAddressString); log.trace("sellerPayoutAddressString " + sellerPayoutAddressString); log.trace("multiSigKeyPair (not displayed for security reasons)"); log.info("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString()); log.info("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString()); log.info("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString()); Transaction payoutTx = createPayoutTx(depositTx, buyerPayoutAmount, sellerPayoutAmount, buyerPayoutAddressString, sellerPayoutAddressString); // MS redeemScript Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); // MS output from prev. tx is index 0 Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); checkNotNull(multiSigKeyPair, "multiSigKeyPair must not be null"); if (multiSigKeyPair.isEncrypted()) checkNotNull(aesKey); ECKey.ECDSASignature sellerSignature = multiSigKeyPair.sign(sigHash, aesKey).toCanonicalised(); TransactionSignature buyerTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(buyerSignature), Transaction.SigHash.ALL, false); TransactionSignature sellerTxSig = new TransactionSignature(sellerSignature, Transaction.SigHash.ALL, false); // Take care of order of signatures. Need to be reversed here. See comment below at getMultiSigRedeemScript (arbitrator, seller, buyer) Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(sellerTxSig, buyerTxSig), redeemScript); TransactionInput input = payoutTx.getInput(0); input.setScriptSig(inputScript); WalletService.printTx("payoutTx", payoutTx); WalletService.verifyTransaction(payoutTx); WalletService.checkWalletConsistency(wallet); WalletService.checkScriptSig(payoutTx, input, 0); checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null"); input.verify(input.getConnectedOutput()); return payoutTx; }
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[]{})); } }