Search in sources :

Example 86 with Transaction

use of org.bitcoinj.core.Transaction in project bisq-core by bisq-network.

the class TradeWalletService method arbitratorSignsDisputedPayoutTx.

// /////////////////////////////////////////////////////////////////////////////////////////
// Dispute
// /////////////////////////////////////////////////////////////////////////////////////////
/**
 * That arbitrator signs the payout transaction
 *
 * @param depositTxSerialized Serialized deposit tx
 * @param buyerPayoutAmount   The payout amount of the buyer.
 * @param sellerPayoutAmount  The payout amount of the seller.
 * @param buyerAddressString  The address of the buyer.
 * @param sellerAddressString The address of the seller.
 * @param arbitratorKeyPair   The keypair of the arbitrator.
 * @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 DER encoded canonical signature of arbitrator
 * @throws AddressFormatException
 * @throws TransactionVerificationException
 */
public byte[] arbitratorSignsDisputedPayoutTx(byte[] depositTxSerialized, Coin buyerPayoutAmount, Coin sellerPayoutAmount, String buyerAddressString, String sellerAddressString, DeterministicKey arbitratorKeyPair, byte[] buyerPubKey, byte[] sellerPubKey, byte[] arbitratorPubKey) throws AddressFormatException, TransactionVerificationException {
    Transaction depositTx = new Transaction(params, depositTxSerialized);
    log.trace("signDisputedPayoutTx called");
    log.trace("depositTx " + depositTx.toString());
    log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString());
    log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString());
    log.trace("buyerAddressString " + buyerAddressString);
    log.trace("sellerAddressString " + sellerAddressString);
    log.trace("arbitratorKeyPair (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());
    // Our MS is index 0
    TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0);
    Transaction preparedPayoutTx = new Transaction(params);
    preparedPayoutTx.addInput(p2SHMultiSigOutput);
    if (buyerPayoutAmount.isGreaterThan(Coin.ZERO))
        preparedPayoutTx.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString));
    if (sellerPayoutAmount.isGreaterThan(Coin.ZERO))
        preparedPayoutTx.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString));
    // take care of sorting!
    Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey);
    Sha256Hash sigHash = preparedPayoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false);
    checkNotNull(arbitratorKeyPair, "arbitratorKeyPair must not be null");
    if (arbitratorKeyPair.isEncrypted())
        checkNotNull(aesKey);
    ECKey.ECDSASignature arbitratorSignature = arbitratorKeyPair.sign(sigHash, aesKey).toCanonicalised();
    WalletService.verifyTransaction(preparedPayoutTx);
    return arbitratorSignature.encodeToDER();
}
Also used : Script(org.bitcoinj.script.Script) TransactionOutput(org.bitcoinj.core.TransactionOutput) Transaction(org.bitcoinj.core.Transaction) Sha256Hash(org.bitcoinj.core.Sha256Hash) ECKey(org.bitcoinj.core.ECKey)

Example 87 with Transaction

use of org.bitcoinj.core.Transaction in project bisq-core by bisq-network.

the class MyBlindVoteListService method publishBlindVote.

public void publishBlindVote(Coin stake, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
    try {
        SecretKey secretKey = BlindVoteConsensus.createSecretKey();
        BallotList sortedBallotList = BlindVoteConsensus.getSortedBallotList(ballotListService);
        byte[] encryptedVotes = getEncryptedVotes(sortedBallotList, secretKey);
        byte[] opReturnData = getOpReturnData(encryptedVotes);
        Coin blindVoteFee = BlindVoteConsensus.getFee(bsqStateService, bsqStateService.getChainHeight());
        Transaction blindVoteTx = getBlindVoteTx(stake, blindVoteFee, opReturnData);
        String blindVoteTxId = blindVoteTx.getHashAsString();
        byte[] encryptedMeritList = getEncryptedMeritList(blindVoteTxId, secretKey);
        // We prefer to not wait for the tx broadcast as if the tx broadcast would fail we still prefer to have our
        // blind vote stored and broadcasted to the p2p network. The tx might get re-broadcasted at a restart and
        // in worst case if it does not succeed the blind vote will be ignored anyway.
        // Inconsistently propagated blind votes in the p2p network could have potentially worse effects.
        BlindVote blindVote = new BlindVote(encryptedVotes, blindVoteTxId, stake.value, encryptedMeritList);
        addBlindVoteToList(blindVote);
        addToP2PNetwork(blindVote, errorMessage -> {
            log.error(errorMessage);
            exceptionHandler.handleException(new PublishToP2PNetworkException(errorMessage));
        });
        // We store our source data for the blind vote in myVoteList
        myVoteListService.createAndAddMyVote(sortedBallotList, secretKey, blindVote);
        publishTx(resultHandler, exceptionHandler, blindVoteTx);
    } catch (CryptoException | TransactionVerificationException | InsufficientMoneyException | WalletException | IOException exception) {
        exceptionHandler.handleException(exception);
    }
}
Also used : WalletException(bisq.core.btc.exceptions.WalletException) TransactionVerificationException(bisq.core.btc.exceptions.TransactionVerificationException) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException) IOException(java.io.IOException) BallotList(bisq.core.dao.governance.ballot.BallotList) Coin(org.bitcoinj.core.Coin) SecretKey(javax.crypto.SecretKey) Transaction(org.bitcoinj.core.Transaction) CryptoException(bisq.common.crypto.CryptoException) PublishToP2PNetworkException(bisq.core.dao.exceptions.PublishToP2PNetworkException)

Example 88 with Transaction

use of org.bitcoinj.core.Transaction in project bisq-core by bisq-network.

the class BaseProposalService method createProposalWithTransaction.

protected ProposalWithTransaction createProposalWithTransaction(String name, String link) throws ValidationException, InsufficientMoneyException, TxException {
    this.name = name;
    this.link = link;
    // As we don't know the txId yes we create a temp proposal with txId set to an empty string.
    R proposal = createProposalWithoutTxId();
    proposalValidator.validateDataFields(proposal);
    Transaction transaction = createTransaction(proposal);
    final Proposal proposalWithTxId = proposal.cloneProposalAndAddTxId(transaction.getHashAsString());
    return new ProposalWithTransaction(proposalWithTxId, transaction);
}
Also used : Transaction(org.bitcoinj.core.Transaction)

Example 89 with Transaction

use of org.bitcoinj.core.Transaction in project bisq-core by bisq-network.

the class TradeWalletService method sellerSignsAndFinalizesPayoutTx.

/**
 * 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;
}
Also used : Script(org.bitcoinj.script.Script) Transaction(org.bitcoinj.core.Transaction) Sha256Hash(org.bitcoinj.core.Sha256Hash) ECKey(org.bitcoinj.core.ECKey) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) RawTransactionInput(bisq.core.btc.data.RawTransactionInput) TransactionInput(org.bitcoinj.core.TransactionInput)

Example 90 with Transaction

use of org.bitcoinj.core.Transaction in project bisq-core by bisq-network.

the class LockupService method getLockupTx.

private Transaction getLockupTx(Coin lockupAmount, byte[] opReturnData) throws InsufficientMoneyException, WalletException, TransactionVerificationException {
    Transaction preparedTx = bsqWalletService.getPreparedLockupTx(lockupAmount);
    Transaction txWithBtcFee = btcWalletService.completePreparedBsqTx(preparedTx, true, opReturnData);
    final Transaction transaction = bsqWalletService.signTx(txWithBtcFee);
    log.info("Lockup tx: " + transaction);
    return transaction;
}
Also used : Transaction(org.bitcoinj.core.Transaction)

Aggregations

Transaction (org.bitcoinj.core.Transaction)214 Coin (org.bitcoinj.core.Coin)71 TransactionInput (org.bitcoinj.core.TransactionInput)48 TransactionOutput (org.bitcoinj.core.TransactionOutput)42 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)38 Address (org.bitcoinj.core.Address)35 ECKey (org.bitcoinj.core.ECKey)32 Script (org.bitcoinj.script.Script)32 ArrayList (java.util.ArrayList)31 HashMap (java.util.HashMap)29 SendRequest (org.bitcoinj.wallet.SendRequest)25 Wallet (org.bitcoinj.wallet.Wallet)25 IOException (java.io.IOException)24 List (java.util.List)24 InsufficientMoneyException (org.bitcoinj.core.InsufficientMoneyException)20 MyTransactionOutPoint (com.samourai.wallet.send.MyTransactionOutPoint)19 AddressFormatException (org.bitcoinj.core.AddressFormatException)19 Sha256Hash (org.bitcoinj.core.Sha256Hash)19 UTXO (com.samourai.wallet.send.UTXO)17 Nullable (javax.annotation.Nullable)17