/** * <p>Calculates a signature hash, that is, a hash of a simplified form of the transaction. How exactly the transaction * is simplified is specified by the type and anyoneCanPay parameters.</p> * * <p>This is a low level API and when using the regular {@link Wallet} class you don't have to call this yourself. * When working with more complex transaction types and contracts, it can be necessary. When signing a P2SH output * the redeemScript should be the script encoded into the scriptSig field, for normal transactions, it's the * scriptPubKey of the output you're signing for.</p> * * @param inputIndex input the signature is being calculated for. Tx signatures are always relative to an input. * @param redeemScript the bytes that should be in the given input during signing. * @param type Should be SigHash.ALL * @param anyoneCanPay should be false. */ public Sha256Hash hashForSignature(int inputIndex, byte[] redeemScript, SigHash type, boolean anyoneCanPay) { byte sigHashType = (byte) TransactionSignature.calcSigHashValue(type, anyoneCanPay); return hashForSignature(inputIndex, redeemScript, sigHashType); }
/** * <p>Calculates a signature hash, that is, a hash of a simplified form of the transaction. How exactly the transaction * is simplified is specified by the type and anyoneCanPay parameters.</p> * * <p>This is a low level API and when using the regular {@link Wallet} class you don't have to call this yourself. * When working with more complex transaction types and contracts, it can be necessary. When signing a P2SH output * the redeemScript should be the script encoded into the scriptSig field, for normal transactions, it's the * scriptPubKey of the output you're signing for.</p> * * @param inputIndex input the signature is being calculated for. Tx signatures are always relative to an input. * @param redeemScript the bytes that should be in the given input during signing. * @param type Should be SigHash.ALL * @param anyoneCanPay should be false. */ public Sha256Hash hashForSignature(int inputIndex, byte[] redeemScript, SigHash type, boolean anyoneCanPay) { byte sigHashType = (byte) TransactionSignature.calcSigHashValue(type, anyoneCanPay); return hashForSignature(inputIndex, redeemScript, sigHashType); }
/** * <p>Calculates a signature hash, that is, a hash of a simplified form of the transaction. How exactly the transaction * is simplified is specified by the type and anyoneCanPay parameters.</p> * * <p>This is a low level API and when using the regular {@link Wallet} class you don't have to call this yourself. * When working with more complex transaction types and contracts, it can be necessary. When signing a P2SH output * the redeemScript should be the script encoded into the scriptSig field, for normal transactions, it's the * scriptPubKey of the output you're signing for.</p> * * @param inputIndex input the signature is being calculated for. Tx signatures are always relative to an input. * @param redeemScript the bytes that should be in the given input during signing. * @param type Should be SigHash.ALL * @param anyoneCanPay should be false. */ public Sha256Hash hashForSignature(int inputIndex, byte[] redeemScript, SigHash type, boolean anyoneCanPay) { byte sigHashType = (byte) TransactionSignature.calcSigHashValue(type, anyoneCanPay); return hashForSignature(inputIndex, redeemScript, sigHashType); }
/** * <p>Calculates a signature hash, that is, a hash of a simplified form of the transaction. How exactly the transaction * is simplified is specified by the type and anyoneCanPay parameters.</p> * * <p>This is a low level API and when using the regular {@link Wallet} class you don't have to call this yourself. * When working with more complex transaction types and contracts, it can be necessary. When signing a P2SH output * the redeemScript should be the script encoded into the scriptSig field, for normal transactions, it's the * scriptPubKey of the output you're signing for.</p> * * @param inputIndex input the signature is being calculated for. Tx signatures are always relative to an input. * @param redeemScript the bytes that should be in the given input during signing. * @param type Should be SigHash.ALL * @param anyoneCanPay should be false. */ public Sha256Hash hashForSignature( int inputIndex, byte[] redeemScript, SigHash type, boolean anyoneCanPay) { byte sigHashType = (byte) TransactionSignature.calcSigHashValue(type, anyoneCanPay); return hashForSignature(inputIndex, redeemScript, sigHashType); }
/** * Check signature. * * @param transaction the transaction * @param index the index * @param outputToSpend the output to spend * @param key the key * @param signature the signature * @return true, if successful */ public static boolean checkSignature (Transaction transaction, int index, TransactionOutput outputToSpend, ECKey key, byte[] signature) { Sha256Hash hash = transaction.hashForSignature(index, outputToSpend.getScriptBytes(), SigHash.ALL, false); return key.verify(hash, ECDSASignature.decodeFromDER(signature)); }
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. The key * must be usable for signing as-is: if the key is encrypted it must be decrypted first external to this method. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param aesKey The AES key to use for decryption of the private key. If null then no decryption is required. * @param redeemScript Byte-exact contents of the scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, @Nullable KeyParameter aesKey, byte[] redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript, hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash, aesKey), hashType, anyoneCanPay); }
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. The key * must be usable for signing as-is: if the key is encrypted it must be decrypted first external to this method. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param redeemScript Byte-exact contents of the scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, byte[] redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript, hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash), hashType, anyoneCanPay); }
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. The key * must be usable for signing as-is: if the key is encrypted it must be decrypted first external to this method. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param redeemScript Byte-exact contents of the scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, byte[] redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript, hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash), hashType, anyoneCanPay); } public TransactionSignature calculateWitnessSignature(
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. The key * must be usable for signing as-is: if the key is encrypted it must be decrypted first external to this method. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param redeemScript Byte-exact contents of the scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, byte[] redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript, hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash), hashType, anyoneCanPay); }
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. The key * must be usable for signing as-is: if the key is encrypted it must be decrypted first external to this method. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param redeemScript Byte-exact contents of the scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature( int inputIndex, ECKey key, byte[] redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript, hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash), hashType, anyoneCanPay); }
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param aesKey The AES key to use for decryption of the private key. If null then no decryption is required. * @param redeemScript The scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, @Nullable KeyParameter aesKey, Script redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript.getProgram(), hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash, aesKey), hashType, anyoneCanPay); }
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param aesKey The AES key to use for decryption of the private key. If null then no decryption is required. * @param redeemScript The scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature( int inputIndex, ECKey key, @Nullable KeyParameter aesKey, Script redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript.getProgram(), hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash, aesKey), hashType, anyoneCanPay); }
@Override public void checkSignatures (ECKey keyServer, ECKey keyClient, ChannelSignatures channelSignatures, Transaction channelTransaction, ChannelStatus status) { Sha256Hash hash1 = channelTransaction.hashForSignature(0, ScriptTools.getAnchorOutputScript(keyClient, keyServer), Transaction.SigHash.ALL, false); //We only have one anchor for now.. if (!keyClient.verify(hash1, channelSignatures.channelSignatures.get(0))) { throw new LNPaymentException("Anchor signature is not correct.."); } List<PaymentData> allPayments = new ArrayList<>(status.paymentList); List<Transaction> paymentTransactions = getPaymentTransactions(channelTransaction.getHash(), status, keyServer, keyClient); if (allPayments.size() != channelSignatures.paymentSignatures.size()) { throw new LNPaymentException("Size of payment signature list is incorrect"); } for (int i = 0; i < allPayments.size(); ++i) { Transaction transaction = paymentTransactions.get(i); TransactionSignature signature = channelSignatures.paymentSignatures.get(i); Script scriptPubKey = channelTransaction.getOutput(i + 2).getScriptPubKey(); Sha256Hash hash = transaction.hashForSignature(0, scriptPubKey, Transaction.SigHash.ALL, false); if (!keyClient.verify(hash, signature)) { throw new LNPaymentException("Payment Signature " + i + " is not correct.."); } } }
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param redeemScript The scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, Script redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript.getProgram(), hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash), hashType, anyoneCanPay); } public TransactionSignature calculateWitnessSignature(
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param redeemScript The scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, Script redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript.getProgram(), hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash), hashType, anyoneCanPay); }
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param redeemScript The scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, Script redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript.getProgram(), hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash), hashType, anyoneCanPay); }
/** * Calculates a signature that is valid for being inserted into the input at the given position. This is simply * a wrapper around calling {@link Transaction#hashForSignature(int, byte[], org.bitcoinj.core.Transaction.SigHash, boolean)} * followed by {@link ECKey#sign(Sha256Hash)} and then returning a new {@link TransactionSignature}. * * @param inputIndex Which input to calculate the signature for, as an index. * @param key The private key used to calculate the signature. * @param redeemScript The scriptPubKey that is being satisified, or the P2SH redeem script. * @param hashType Signing mode, see the enum for documentation. * @param anyoneCanPay Signing mode, see the SigHash enum for documentation. * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature( int inputIndex, ECKey key, Script redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript.getProgram(), hashType, anyoneCanPay); return new TransactionSignature(key.sign(hash), hashType, anyoneCanPay); }
public void run() { assertEquals(txNormalizedHash, tx.hashForSignature(0, new byte[0], Transaction.SigHash.ALL.byteValue()).toString()); } };
private void addOnlyInputToTransaction(Transaction t, TransactionOutPointWithValue prevOut, long sequence) throws ScriptException { TransactionInput input = new TransactionInput(params, t, new byte[]{}, prevOut.outpoint); input.setSequenceNumber(sequence); t.addInput(input); if (prevOut.scriptPubKey.getChunks().get(0).equalsOpCode(OP_TRUE)) { input.setScriptSig(new ScriptBuilder().op(OP_1).build()); } else { // Sign input checkState(prevOut.scriptPubKey.isSentToRawPubKey()); Sha256Hash hash = t.hashForSignature(0, prevOut.scriptPubKey, SigHash.ALL, false); input.setScriptSig(ScriptBuilder.createInputScript( new TransactionSignature(coinbaseOutKey.sign(hash), SigHash.ALL, false)) ); } }
/** * Ensure that hashForSignature() doesn't modify a transaction's data, which could wreak multithreading havoc. */ @Test public void testHashForSignatureThreadSafety() { Block genesis = UnitTestParams.get().getGenesisBlock(); Block block1 = genesis.createNextBlock(new ECKey().toAddress(UnitTestParams.get()), genesis.getTransactions().get(0).getOutput(0).getOutPointFor()); final Transaction tx = block1.getTransactions().get(1); final String txHash = tx.getHashAsString(); final String txNormalizedHash = tx.hashForSignature(0, new byte[0], Transaction.SigHash.ALL.byteValue()).toString(); for (int i = 0; i < 100; i++) { // ensure the transaction object itself was not modified; if it was, the hash will change assertEquals(txHash, tx.getHashAsString()); new Thread(){ public void run() { assertEquals(txNormalizedHash, tx.hashForSignature(0, new byte[0], Transaction.SigHash.ALL.byteValue()).toString()); } }; } }