use of org.bitcoinj.crypto.TransactionSignature in project balzac by balzac-lang.
the class AbstractScriptBuilderWithVar method setAllSignatures.
/**
* Replace all the signatures placeholder with the actual signatures.
* Each placeholder is already associated with the key and the modifiers.
* @param tx the transaction to be signed
* @param inputIndex the index of the input that will contain this script
* @param outScript the redeemed output script
* @return a <b>copy</b> of this builder
* @throws KeyStoreException if an error occurs retrieving private keys
*/
@SuppressWarnings("unchecked")
public T setAllSignatures(ECKeyStore keystore, Transaction tx, int inputIndex, byte[] outScript) throws KeyStoreException {
List<ScriptChunk> newChunks = new ArrayList<>();
for (ScriptChunk chunk : getChunks()) {
ScriptBuilder2 sb = new ScriptBuilder2();
if (isSignature(chunk)) {
String mapKey = getMapKey(chunk);
SignatureUtil sig = this.signatures.get(mapKey);
checkState(keystore != null, "keystore must be set to retrieve the private keys");
checkState(keystore.containsKey(sig.keyID), "key " + sig.keyID + " not found on the specified keystore");
ECKey key = keystore.getKey(sig.keyID);
SigHash hashType = sig.hashType;
boolean anyoneCanPay = sig.anyoneCanPay;
// check the key is correct when P2PKH
// Script s = new Script(outScript);
// if (s.isSentToAddress()) {
// checkState(Arrays.equals(s.getPubKeyHash(), key.getPubKeyHash()));
// }
TransactionSignature txSig = tx.calculateSignature(inputIndex, key, outScript, hashType, anyoneCanPay);
Sha256Hash hash = tx.hashForSignature(inputIndex, outScript, (byte) txSig.sighashFlags);
boolean isValid = ECKey.verify(hash.getBytes(), txSig, key.getPubKey());
checkState(isValid);
checkState(txSig.isCanonical());
sb.data(txSig.encodeToBitcoin());
} else {
sb.addChunk(chunk);
}
newChunks.addAll(sb.getChunks());
}
super.getChunks().clear();
super.getChunks().addAll(newChunks);
this.signatures.clear();
return (T) this;
}
use of org.bitcoinj.crypto.TransactionSignature in project bisq-core by bisq-network.
the class TradeWalletService method emergencySignAndPublishPayoutTx.
// Emergency payout tool. Used only in cased when the payput from the arbitrator does not work because some data
// in the trade/dispute are messed up.
// We keep here arbitratorPayoutAmount just in case (requires cooperation from peer anyway)
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;
}
use of org.bitcoinj.crypto.TransactionSignature in project bisq-core by bisq-network.
the class TradeWalletService method signInput.
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);
}
}
use of org.bitcoinj.crypto.TransactionSignature in project samourai-wallet-android by Samourai-Wallet.
the class RBFTask method signTx.
private Transaction signTx(Transaction tx) {
HashMap<String, ECKey> keyBag = new HashMap<String, ECKey>();
HashMap<String, ECKey> keyBag49 = new HashMap<String, ECKey>();
HashMap<String, ECKey> keyBag84 = new HashMap<String, ECKey>();
HashMap<String, String> keys = rbf.getKeyBag();
for (String outpoint : keys.keySet()) {
ECKey ecKey = null;
String[] s = keys.get(outpoint).split("/");
Log.i("RBF", "path length:" + s.length);
if (s.length == 4) {
if (s[3].equals("84")) {
HD_Address addr = BIP84Util.getInstance(activity).getWallet().getAccount(0).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
ecKey = addr.getECKey();
} else {
HD_Address addr = BIP49Util.getInstance(activity).getWallet().getAccount(0).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
ecKey = addr.getECKey();
}
} else if (s.length == 3) {
HD_Address hd_address = AddressFactory.getInstance(activity).get(0, Integer.parseInt(s[1]), Integer.parseInt(s[2]));
String strPrivKey = hd_address.getPrivateKeyString();
DumpedPrivateKey pk = new DumpedPrivateKey(SamouraiWallet.getInstance().getCurrentNetworkParams(), strPrivKey);
ecKey = pk.getKey();
} else if (s.length == 2) {
try {
PaymentAddress address = BIP47Util.getInstance(activity).getReceiveAddress(new PaymentCode(s[0]), Integer.parseInt(s[1]));
ecKey = address.getReceiveECKey();
} catch (Exception e) {
;
}
} else {
;
}
Log.i("RBF", "outpoint:" + outpoint);
Log.i("RBF", "path:" + keys.get(outpoint));
if (ecKey != null) {
if (s.length == 4) {
if (s[3].equals("84")) {
keyBag84.put(outpoint, ecKey);
} else {
keyBag49.put(outpoint, ecKey);
}
} else {
keyBag.put(outpoint, ecKey);
}
} else {
throw new RuntimeException("ECKey error: cannot process private key");
// Log.i("ECKey error", "cannot process private key");
}
}
List<TransactionInput> inputs = tx.getInputs();
for (int i = 0; i < inputs.size(); i++) {
ECKey ecKey = null;
String address = null;
if (inputs.get(i).getValue() != null || keyBag49.containsKey(inputs.get(i).getOutpoint().toString()) || keyBag84.containsKey(inputs.get(i).getOutpoint().toString())) {
if (keyBag84.containsKey(inputs.get(i).getOutpoint().toString())) {
ecKey = keyBag84.get(inputs.get(i).getOutpoint().toString());
SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
address = segwitAddress.getBech32AsString();
} else {
ecKey = keyBag49.get(inputs.get(i).getOutpoint().toString());
SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
address = segwitAddress.getAddressAsString();
}
} else {
ecKey = keyBag.get(inputs.get(i).getOutpoint().toString());
address = ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
}
Log.d("RBF", "pubKey:" + Hex.toHexString(ecKey.getPubKey()));
Log.d("RBF", "address:" + address);
if (inputs.get(i).getValue() != null || keyBag49.containsKey(inputs.get(i).getOutpoint().toString()) || keyBag84.containsKey(inputs.get(i).getOutpoint().toString())) {
final SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
Script scriptPubKey = segwitAddress.segWitOutputScript();
final Script redeemScript = segwitAddress.segWitRedeemScript();
System.out.println("redeem script:" + Hex.toHexString(redeemScript.getProgram()));
final Script scriptCode = redeemScript.scriptCode();
System.out.println("script code:" + Hex.toHexString(scriptCode.getProgram()));
TransactionSignature sig = tx.calculateWitnessSignature(i, ecKey, scriptCode, Coin.valueOf(input_values.get(inputs.get(i).getOutpoint().toString())), Transaction.SigHash.ALL, false);
final TransactionWitness witness = new TransactionWitness(2);
witness.setPush(0, sig.encodeToBitcoin());
witness.setPush(1, ecKey.getPubKey());
tx.setWitness(i, witness);
if (!FormatsUtil.getInstance().isValidBech32(address) && Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
final ScriptBuilder sigScript = new ScriptBuilder();
sigScript.data(redeemScript.getProgram());
tx.getInput(i).setScriptSig(sigScript.build());
tx.getInput(i).getScriptSig().correctlySpends(tx, i, scriptPubKey, Coin.valueOf(input_values.get(inputs.get(i).getOutpoint().toString())), Script.ALL_VERIFY_FLAGS);
}
} else {
Log.i("RBF", "sign outpoint:" + inputs.get(i).getOutpoint().toString());
Log.i("RBF", "ECKey address from keyBag:" + ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString());
Log.i("RBF", "script:" + ScriptBuilder.createOutputScript(ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams())));
Log.i("RBF", "script:" + Hex.toHexString(ScriptBuilder.createOutputScript(ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams())).getProgram()));
TransactionSignature sig = tx.calculateSignature(i, ecKey, ScriptBuilder.createOutputScript(ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams())).getProgram(), Transaction.SigHash.ALL, false);
tx.getInput(i).setScriptSig(ScriptBuilder.createInputScript(sig, ecKey));
}
}
return tx;
}
use of org.bitcoinj.crypto.TransactionSignature in project samourai-wallet-android by Samourai-Wallet.
the class SendFactory method signTransaction.
private synchronized Transaction signTransaction(Transaction transaction, HashMap<String, ECKey> keyBag) throws ScriptException {
List<TransactionInput> inputs = transaction.getInputs();
TransactionInput input = null;
TransactionOutput connectedOutput = null;
byte[] connectedPubKeyScript = null;
TransactionSignature sig = null;
Script scriptPubKey = null;
ECKey key = null;
for (int i = 0; i < inputs.size(); i++) {
input = inputs.get(i);
key = keyBag.get(input.getOutpoint().toString());
connectedPubKeyScript = input.getOutpoint().getConnectedPubKeyScript();
connectedOutput = input.getOutpoint().getConnectedOutput();
scriptPubKey = connectedOutput.getScriptPubKey();
String script = Hex.toHexString(connectedPubKeyScript);
String address = null;
if (Bech32Util.getInstance().isBech32Script(script)) {
try {
address = Bech32Util.getInstance().getAddressFromScript(script);
} catch (Exception e) {
;
}
} else {
address = new Script(connectedPubKeyScript).getToAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
}
if (FormatsUtil.getInstance().isValidBech32(address) || Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
final SegwitAddress segwitAddress = new SegwitAddress(key.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
// System.out.println("pubKey:" + Hex.toHexString(key.getPubKey()));
// final Script scriptPubKey = p2shp2wpkh.segWitOutputScript();
// System.out.println("scriptPubKey:" + Hex.toHexString(scriptPubKey.getProgram()));
// System.out.println("to address from script:" + scriptPubKey.getToAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString());
final Script redeemScript = segwitAddress.segWitRedeemScript();
// System.out.println("redeem script:" + Hex.toHexString(redeemScript.getProgram()));
final Script scriptCode = redeemScript.scriptCode();
// System.out.println("script code:" + Hex.toHexString(scriptCode.getProgram()));
sig = transaction.calculateWitnessSignature(i, key, scriptCode, connectedOutput.getValue(), Transaction.SigHash.ALL, false);
final TransactionWitness witness = new TransactionWitness(2);
witness.setPush(0, sig.encodeToBitcoin());
witness.setPush(1, key.getPubKey());
transaction.setWitness(i, witness);
if (!FormatsUtil.getInstance().isValidBech32(address) && Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
final ScriptBuilder sigScript = new ScriptBuilder();
sigScript.data(redeemScript.getProgram());
transaction.getInput(i).setScriptSig(sigScript.build());
transaction.getInput(i).getScriptSig().correctlySpends(transaction, i, scriptPubKey, connectedOutput.getValue(), Script.ALL_VERIFY_FLAGS);
}
} else {
if (key != null && key.hasPrivKey() || key.isEncrypted()) {
sig = transaction.calculateSignature(i, key, connectedPubKeyScript, Transaction.SigHash.ALL, false);
} else {
// watch only ?
sig = TransactionSignature.dummy();
}
if (scriptPubKey.isSentToAddress()) {
input.setScriptSig(ScriptBuilder.createInputScript(sig, key));
} else if (scriptPubKey.isSentToRawPubKey()) {
input.setScriptSig(ScriptBuilder.createInputScript(sig));
} else {
throw new RuntimeException("Unknown script type: " + scriptPubKey);
}
}
}
return transaction;
}
Aggregations