diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java b/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java new file mode 100644 index 0000000..db62ff6 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java @@ -0,0 +1,60 @@ +package com.sparrowwallet.drongo.protocol; + +/** + * These constants are a part of a scriptSig signature on the inputs. They define the details of how a + * transaction can be redeemed, specifically, they control how the hash of the transaction is calculated. + */ +public enum SigHash { + ALL("All (Recommended)", 1), + NONE("None", 2), + SINGLE("Single", 3), + ANYONECANPAY("Anyone Can Pay", 0x80), // Caution: Using this type in isolation is non-standard. Treated similar to ANYONECANPAY_ALL. + ANYONECANPAY_ALL("All + Anyone Can Pay", 0x81), + ANYONECANPAY_NONE("None + Anyone Can Pay", 0x82), + ANYONECANPAY_SINGLE("Single + Anyone Can Pay", 0x83), + UNSET("Unset", 0); // Caution: Using this type in isolation is non-standard. Treated similar to ALL. + + private final String name; + public final int value; + + /** + * @param value + */ + private SigHash(final String name, final int value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + /** + * @return the value as a int + */ + public int intValue() { + return this.value; + } + + /** + * @return the value as a byte + */ + public byte byteValue() { + return (byte) this.value; + } + + public static SigHash fromInt(int sigHashInt) { + for(SigHash value : SigHash.values()) { + if(sigHashInt == value.intValue()) { + return value; + } + } + + throw new IllegalArgumentException("No defined sighash value for int " + sigHashInt); + } + + @Override + public String toString() { + return getName(); + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java index 25ca5d1..66090be 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java @@ -561,54 +561,6 @@ public class Transaction extends ChildMessage { return Sha256Hash.twiceOf(bos.toByteArray()); } - /** - * These constants are a part of a scriptSig signature on the inputs. They define the details of how a - * transaction can be redeemed, specifically, they control how the hash of the transaction is calculated. - */ - public enum SigHash { - ALL(1), - NONE(2), - SINGLE(3), - ANYONECANPAY(0x80), // Caution: Using this type in isolation is non-standard. Treated similar to ANYONECANPAY_ALL. - ANYONECANPAY_ALL(0x81), - ANYONECANPAY_NONE(0x82), - ANYONECANPAY_SINGLE(0x83), - UNSET(0); // Caution: Using this type in isolation is non-standard. Treated similar to ALL. - - public final int value; - - /** - * @param value - */ - private SigHash(final int value) { - this.value = value; - } - - /** - * @return the value as a int - */ - public int intValue() { - return this.value; - } - - /** - * @return the value as a byte - */ - public byte byteValue() { - return (byte) this.value; - } - - public static SigHash fromInt(int sigHashInt) { - for(SigHash value : SigHash.values()) { - if(sigHashInt == value.intValue()) { - return value; - } - } - - throw new IllegalArgumentException("No defined sighash value for int " + sigHashInt); - } - } - public static final void main(String[] args) throws NonStandardScriptException { String hex = "0100000002fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e0000000000ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac00000000"; byte[] transactionBytes = Utils.hexToBytes(hex); diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java index 0104c6c..d3491ec 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java @@ -17,7 +17,7 @@ public class TransactionSignature extends ECKey.ECDSASignature { /** Constructs a signature with the given components and SIGHASH_ALL. */ public TransactionSignature(BigInteger r, BigInteger s) { - this(r, s, Transaction.SigHash.ALL.value); + this(r, s, SigHash.ALL.value); } /** Constructs a signature with the given components and raw sighash flag bytes (needed for rule compatibility). */ @@ -27,7 +27,7 @@ public class TransactionSignature extends ECKey.ECDSASignature { } /** Constructs a transaction signature based on the ECDSA signature. */ - public TransactionSignature(ECKey.ECDSASignature signature, Transaction.SigHash mode, boolean anyoneCanPay) { + public TransactionSignature(ECKey.ECDSASignature signature, SigHash mode, boolean anyoneCanPay) { super(signature.r, signature.s); sighashFlags = calcSigHashValue(mode, anyoneCanPay); } @@ -44,13 +44,13 @@ public class TransactionSignature extends ECKey.ECDSASignature { } /** Calculates the byte used in the protocol to represent the combination of mode and anyoneCanPay. */ - public static int calcSigHashValue(Transaction.SigHash mode, boolean anyoneCanPay) { - if(Transaction.SigHash.ALL != mode && Transaction.SigHash.NONE != mode && Transaction.SigHash.SINGLE != mode) { // enforce compatibility since this code was made before the SigHash enum was updated + public static int calcSigHashValue(SigHash mode, boolean anyoneCanPay) { + if(SigHash.ALL != mode && SigHash.NONE != mode && SigHash.SINGLE != mode) { // enforce compatibility since this code was made before the SigHash enum was updated throw new IllegalArgumentException("Sighash mode must be one of ALL, NONE or SINGLE"); } int sighashFlags = mode.value; if (anyoneCanPay) - sighashFlags |= Transaction.SigHash.ANYONECANPAY.value; + sighashFlags |= SigHash.ANYONECANPAY.value; return sighashFlags; } @@ -76,8 +76,8 @@ public class TransactionSignature extends ECKey.ECDSASignature { if (signature.length < 9 || signature.length > 73) return false; - int hashType = (signature[signature.length-1] & 0xff) & ~Transaction.SigHash.ANYONECANPAY.value; // mask the byte to prevent sign-extension hurting us - if (hashType < Transaction.SigHash.ALL.value || hashType > Transaction.SigHash.SINGLE.value) + int hashType = (signature[signature.length-1] & 0xff) & ~SigHash.ANYONECANPAY.value; // mask the byte to prevent sign-extension hurting us + if (hashType < SigHash.ALL.value || hashType > SigHash.SINGLE.value) return false; // "wrong type" "wrong length marker" @@ -107,17 +107,17 @@ public class TransactionSignature extends ECKey.ECDSASignature { } public boolean anyoneCanPay() { - return (sighashFlags & Transaction.SigHash.ANYONECANPAY.value) != 0; + return (sighashFlags & SigHash.ANYONECANPAY.value) != 0; } - public Transaction.SigHash sigHashMode() { + public SigHash sigHashMode() { final int mode = sighashFlags & 0x1f; - if (mode == Transaction.SigHash.NONE.value) - return Transaction.SigHash.NONE; - else if (mode == Transaction.SigHash.SINGLE.value) - return Transaction.SigHash.SINGLE; + if (mode == SigHash.NONE.value) + return SigHash.NONE; + else if (mode == SigHash.SINGLE.value) + return SigHash.SINGLE; else - return Transaction.SigHash.ALL; + return SigHash.ALL; } /** diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 685c6f1..4018366 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -388,6 +388,26 @@ public class PSBT { return fee; } + public boolean hasSignatures() { + for(PSBTInput psbtInput : getPsbtInputs()) { + if(!psbtInput.getPartialSignatures().isEmpty() || psbtInput.getFinalScriptSig() != null || psbtInput.getFinalScriptWitness() != null) { + return true; + } + } + + return false; + } + + public boolean isSigned() { + for(PSBTInput psbtInput : getPsbtInputs()) { + if(!psbtInput.isSigned()) { + return false; + } + } + + return true; + } + public byte[] serialize() throws IOException { ByteArrayOutputStream transactionbaos = new ByteArrayOutputStream(); transaction.bitcoinSerializeToStream(transactionbaos); diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 13ccd28..ef3c67d 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -30,7 +30,7 @@ public class PSBTInput { private Transaction nonWitnessUtxo; private TransactionOutput witnessUtxo; private final Map partialSignatures = new LinkedHashMap<>(); - private Transaction.SigHash sigHash; + private SigHash sigHash; private Script redeemScript; private Script witnessScript; private final Map derivedPublicKeys = new LinkedHashMap<>(); @@ -47,7 +47,7 @@ public class PSBTInput { PSBTInput(ScriptType scriptType, Transaction transaction, int index, Transaction utxo, int utxoIndex, Script redeemScript, Script witnessScript, Map derivedPublicKeys, Map proprietary) { this.transaction = transaction; this.index = index; - sigHash = Transaction.SigHash.ALL; + sigHash = SigHash.ALL; if(Arrays.asList(ScriptType.WITNESS_TYPES).contains(scriptType)) { this.witnessUtxo = utxo.getOutputs().get(utxoIndex); @@ -118,7 +118,7 @@ public class PSBTInput { case PSBT_IN_SIGHASH_TYPE: entry.checkOneByteKey(); long sighashType = Utils.readUint32(entry.getData(), 0); - Transaction.SigHash sigHash = Transaction.SigHash.fromInt((int)sighashType); + SigHash sigHash = SigHash.fromInt((int)sighashType); this.sigHash = sigHash; log.debug("Found input sighash_type " + sigHash.toString()); break; @@ -211,10 +211,14 @@ public class PSBTInput { return partialSignatures.get(publicKey); } - public Transaction.SigHash getSigHash() { + public SigHash getSigHash() { return sigHash; } + public void setSigHash(SigHash sigHash) { + this.sigHash = sigHash; + } + public Script getRedeemScript() { return redeemScript; } @@ -261,18 +265,26 @@ public class PSBTInput { return proprietary; } - public boolean isSigned() throws NonStandardScriptException { - //All partial sigs are already verified - int reqSigs = getSigningScript().getNumRequiredSignatures(); - int sigs = getPartialSignatures().size(); - return sigs == reqSigs; + public boolean isSigned() { + if(!getPartialSignatures().isEmpty()) { + try { + //All partial sigs are already verified + int reqSigs = getSigningScript().getNumRequiredSignatures(); + int sigs = getPartialSignatures().size(); + return sigs == reqSigs; + } catch(NonStandardScriptException e) { + return false; + } + } else { + return getFinalScriptSig() != null; + } } boolean verifySignatures() throws PSBTParseException { - Transaction.SigHash localSigHash = getSigHash(); + SigHash localSigHash = getSigHash(); if(localSigHash == null) { //Assume SigHash.ALL - localSigHash = Transaction.SigHash.ALL; + localSigHash = SigHash.ALL; } if(getNonWitnessUtxo() != null || getWitnessUtxo() != null) { @@ -325,7 +337,7 @@ public class PSBTInput { return signingScript; } - private Sha256Hash getHashForSignature(Script connectedScript, Transaction.SigHash localSigHash) { + private Sha256Hash getHashForSignature(Script connectedScript, SigHash localSigHash) { Sha256Hash hash; if (getNonWitnessUtxo() != null) { hash = transaction.hashForSignature(index, connectedScript, localSigHash, false); diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 0ecbda6..11190f7 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -8,6 +8,8 @@ import com.sparrowwallet.drongo.crypto.Key; import com.sparrowwallet.drongo.policy.Policy; import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.*; +import com.sparrowwallet.drongo.psbt.PSBT; +import com.sparrowwallet.drongo.psbt.PSBTInput; import java.util.*; import java.util.stream.Collectors; @@ -251,6 +253,23 @@ public class Wallet { } } + public boolean isWalletOutputScript(Script outputScript) { + return getWalletOutputScripts().containsKey(outputScript); + } + + public Map getWalletOutputScripts() { + Map walletOutputScripts = new LinkedHashMap<>(); + getWalletOutputScripts(walletOutputScripts, getNode(KeyPurpose.RECEIVE)); + getWalletOutputScripts(walletOutputScripts, getNode(KeyPurpose.CHANGE)); + return walletOutputScripts; + } + + private void getWalletOutputScripts(Map walletOutputScripts, WalletNode purposeNode) { + for(WalletNode addressNode : purposeNode.getChildren()) { + walletOutputScripts.put(getOutputScript(addressNode), addressNode); + } + } + public boolean isWalletTxo(BlockTransactionHashIndex txo) { return getWalletTxos().containsKey(txo); } @@ -549,6 +568,27 @@ public class Wallet { return true; } + public boolean canSign(PSBT psbt) { + for(int inputIndex = 0; inputIndex < psbt.getTransaction().getInputs().size(); inputIndex++) { + TransactionInput txInput = psbt.getTransaction().getInputs().get(inputIndex); + PSBTInput psbtInput = psbt.getPsbtInputs().get(inputIndex); + + TransactionOutput utxo = psbtInput.getWitnessUtxo(); + if(utxo == null) { + utxo = psbtInput.getNonWitnessUtxo().getOutputs().get((int)txInput.getOutpoint().getIndex()); + } + + if(utxo != null) { + Script scriptPubKey = utxo.getScript(); + if(isWalletOutputScript(scriptPubKey)) { + return true; + } + } + } + + return false; + } + public BitcoinUnit getAutoUnit() { for(KeyPurpose keyPurpose : KeyPurpose.values()) { for(WalletNode addressNode : getNode(keyPurpose).getChildren()) { @@ -737,4 +777,8 @@ public class Wallet { } } + @Override + public String toString() { + return getName(); + } } diff --git a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java index 5155827..e848eb8 100644 --- a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java +++ b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java @@ -18,7 +18,7 @@ public class TransactionTest { Transaction transaction = new Transaction(Utils.hexToBytes(hex)); ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357")); - Sha256Hash hash = transaction.hashForWitnessSignature(1, ScriptType.P2PKH.getOutputScript(pubKey.getPubKeyHash()),600000000L, Transaction.SigHash.ALL, false); + Sha256Hash hash = transaction.hashForWitnessSignature(1, ScriptType.P2PKH.getOutputScript(pubKey.getPubKeyHash()),600000000L, SigHash.ALL, false); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee"), false, true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -29,7 +29,7 @@ public class TransactionTest { Transaction transaction = new Transaction(Utils.hexToBytes(hex)); ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873")); - Sha256Hash hash = transaction.hashForWitnessSignature(0, ScriptType.P2PKH.getOutputScript(pubKey.getPubKeyHash()),1000000000L, Transaction.SigHash.ALL, false); + Sha256Hash hash = transaction.hashForWitnessSignature(0, ScriptType.P2PKH.getOutputScript(pubKey.getPubKeyHash()),1000000000L, SigHash.ALL, false); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb01"), true, true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -41,7 +41,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880ae")); Script script = new Script(Utils.hexToBytes("21026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac")); - Sha256Hash hash = transaction.hashForWitnessSignature(1, script,4900000000L, Transaction.SigHash.SINGLE, false); + Sha256Hash hash = transaction.hashForWitnessSignature(1, script,4900000000L, SigHash.SINGLE, false); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e2703"), true, true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -53,7 +53,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98")); Script script = new Script(Utils.hexToBytes("68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac")); - Sha256Hash hash = transaction.hashForWitnessSignature(1, script,16777215L, Transaction.SigHash.SINGLE, true); + Sha256Hash hash = transaction.hashForWitnessSignature(1, script,16777215L, SigHash.SINGLE, true); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("30440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83"), true, true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -65,7 +65,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); - Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, Transaction.SigHash.ALL, false); + Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.ALL, false); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01"), true, true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -77,7 +77,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); - Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, Transaction.SigHash.NONE, false); + Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.NONE, false); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502"), true, true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -89,7 +89,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); - Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, Transaction.SigHash.SINGLE, false); + Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.SINGLE, false); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403"), true, true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -101,7 +101,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); - Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, Transaction.SigHash.ALL, true); + Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.ALL, true); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381"), true, true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -113,7 +113,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); - Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, Transaction.SigHash.NONE, true); + Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.NONE, true); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a0882"), true, true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -125,7 +125,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); - Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, Transaction.SigHash.SINGLE, true); + Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.SINGLE, true); TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("30440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783"), true, true); Assert.assertTrue(pubKey.verify(hash, signature)); } diff --git a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java index 6bb27f9..3a0eff2 100644 --- a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java +++ b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java @@ -3,7 +3,7 @@ package com.sparrowwallet.drongo.psbt; import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.protocol.NonStandardScriptException; -import com.sparrowwallet.drongo.protocol.Transaction; +import com.sparrowwallet.drongo.protocol.SigHash; import org.bouncycastle.util.encoders.Hex; import org.junit.Assert; import org.junit.Test; @@ -170,7 +170,7 @@ public class PSBTTest { public void validP2pkhWithSigHash() throws PSBTParseException { String psbt = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAQMEAQAAAAAAAA=="; PSBT psbt1 = PSBT.fromString(psbt); - Assert.assertEquals(Transaction.SigHash.ALL, psbt1.getPsbtInputs().get(0).getSigHash()); + Assert.assertEquals(SigHash.ALL, psbt1.getPsbtInputs().get(0).getSigHash()); Assert.assertEquals(301L, psbt1.getFee().longValue()); }