Search in sources :

Example 6 with TransactionVerificationException

use of io.bitsquare.btc.exceptions.TransactionVerificationException in project bitsquare by bitsquare.

the class TradeWalletService method takerSignsAndPublishesDepositTx.

/**
     * The taker signs the deposit transaction he received from the offerer and publishes it.
     *
     * @param takerIsSeller               The flag indicating if we are in the taker as seller role or the opposite.
     * @param contractHash                The hash of the contract to be added to the OP_RETURN output.
     * @param offerersDepositTxSerialized The prepared deposit transaction signed by the offerer.
     * @param buyerInputs                 The connected outputs for all inputs of the buyer.
     * @param sellerInputs                The connected outputs for all inputs of the seller.
     * @param buyerPubKey                 The public key of the buyer.
     * @param sellerPubKey                The public key of the seller.
     * @param arbitratorPubKey            The public key of the arbitrator.
     * @param callback                    Callback when transaction is broadcasted.
     * @throws SigningException
     * @throws TransactionVerificationException
     * @throws WalletException
     */
public Transaction takerSignsAndPublishesDepositTx(boolean takerIsSeller, byte[] contractHash, byte[] offerersDepositTxSerialized, List<RawTransactionInput> buyerInputs, List<RawTransactionInput> sellerInputs, byte[] buyerPubKey, byte[] sellerPubKey, byte[] arbitratorPubKey, FutureCallback<Transaction> callback) throws SigningException, TransactionVerificationException, WalletException {
    Transaction offerersDepositTx = new Transaction(params, offerersDepositTxSerialized);
    log.trace("signAndPublishDepositTx called");
    log.trace("takerIsSeller " + takerIsSeller);
    log.trace("offerersDepositTx " + offerersDepositTx.toString());
    log.trace("buyerConnectedOutputsForAllInputs " + buyerInputs.toString());
    log.trace("sellerConnectedOutputsForAllInputs " + sellerInputs.toString());
    log.trace("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString());
    log.trace("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString());
    log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());
    checkArgument(!buyerInputs.isEmpty());
    checkArgument(!sellerInputs.isEmpty());
    // Check if offerer's Multisig script is identical to the takers
    Script p2SHMultiSigOutputScript = getP2SHMultiSigOutputScript(buyerPubKey, sellerPubKey, arbitratorPubKey);
    if (!offerersDepositTx.getOutput(0).getScriptPubKey().equals(p2SHMultiSigOutputScript))
        throw new TransactionVerificationException("Offerer's p2SHMultiSigOutputScript does not match to takers p2SHMultiSigOutputScript");
    // The outpoints are not available from the serialized offerersDepositTx, so we cannot use that tx directly, but we use it to construct a new 
    // depositTx
    Transaction depositTx = new Transaction(params);
    if (takerIsSeller) {
        // We grab the signature from the offerersDepositTx and apply it to the new tx input
        for (int i = 0; i < buyerInputs.size(); i++) depositTx.addInput(getTransactionInput(depositTx, getScriptProgram(offerersDepositTx, i), buyerInputs.get(i)));
        // Add seller inputs 
        for (RawTransactionInput rawTransactionInput : sellerInputs) depositTx.addInput(getTransactionInput(depositTx, new byte[] {}, rawTransactionInput));
    } else {
        // Add buyer inputs and apply signature
        for (RawTransactionInput rawTransactionInput : buyerInputs) depositTx.addInput(getTransactionInput(depositTx, new byte[] {}, rawTransactionInput));
        // We grab the signature from the offerersDepositTx and apply it to the new tx input
        for (int i = buyerInputs.size(), k = 0; i < offerersDepositTx.getInputs().size(); i++, k++) depositTx.addInput(getTransactionInput(depositTx, getScriptProgram(offerersDepositTx, i), sellerInputs.get(k)));
    }
    // Check if OP_RETURN output with contract hash matches the one from the offerer
    TransactionOutput contractHashOutput = new TransactionOutput(params, offerersDepositTx, Coin.ZERO, ScriptBuilder.createOpReturnScript(contractHash).getProgram());
    log.debug("contractHashOutput " + contractHashOutput);
    TransactionOutput offerersContractHashOutput = offerersDepositTx.getOutputs().get(1);
    log.debug("offerersContractHashOutput " + offerersContractHashOutput);
    if (!offerersContractHashOutput.getScriptPubKey().equals(contractHashOutput.getScriptPubKey()))
        throw new TransactionVerificationException("Offerer's transaction output for the contract hash is not matching takers version.");
    // Add all outputs from offerersDepositTx to depositTx
    offerersDepositTx.getOutputs().forEach(depositTx::addOutput);
    //printTxWithInputs("offerersDepositTx", offerersDepositTx);
    // Sign inputs 
    int start = takerIsSeller ? buyerInputs.size() : 0;
    int end = takerIsSeller ? depositTx.getInputs().size() : buyerInputs.size();
    for (int i = start; i < end; i++) {
        TransactionInput input = depositTx.getInput(i);
        signInput(depositTx, input, i);
        checkScriptSig(depositTx, input, i);
    }
    printTxWithInputs("depositTx", depositTx);
    verifyTransaction(depositTx);
    checkWalletConsistency();
    // Broadcast depositTx
    checkNotNull(walletAppKit);
    ListenableFuture<Transaction> broadcastComplete = walletAppKit.peerGroup().broadcastTransaction(depositTx).future();
    Futures.addCallback(broadcastComplete, callback);
    return depositTx;
}
Also used : Script(org.bitcoinj.script.Script) TransactionVerificationException(io.bitsquare.btc.exceptions.TransactionVerificationException) RawTransactionInput(io.bitsquare.btc.data.RawTransactionInput) RawTransactionInput(io.bitsquare.btc.data.RawTransactionInput)

Aggregations

TransactionVerificationException (io.bitsquare.btc.exceptions.TransactionVerificationException)6 AddressFormatException (org.bitcoinj.core.AddressFormatException)3 AddressEntry (io.bitsquare.btc.AddressEntry)2 WalletException (io.bitsquare.btc.exceptions.WalletException)2 Popup (io.bitsquare.gui.main.overlays.popups.Popup)2 Transaction (org.bitcoinj.core.Transaction)2 FutureCallback (com.google.common.util.concurrent.FutureCallback)1 Dispute (io.bitsquare.arbitration.Dispute)1 RawTransactionInput (io.bitsquare.btc.data.RawTransactionInput)1 Timer (io.bitsquare.common.Timer)1 InputTextField (io.bitsquare.gui.components.InputTextField)1 FormBuilder.addLabelInputTextField (io.bitsquare.gui.util.FormBuilder.addLabelInputTextField)1 Contract (io.bitsquare.trade.Contract)1 Tradable (io.bitsquare.trade.Tradable)1 Trade (io.bitsquare.trade.Trade)1 Date (java.util.Date)1 Optional (java.util.Optional)1 Nullable (javax.annotation.Nullable)1 Script (org.bitcoinj.script.Script)1