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();
}
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);
}
}
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);
}
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;
}
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;
}
Aggregations