diff --git a/core/src/main/java/org/bitcoinj/core/TransactionOutPoint.java b/core/src/main/java/org/bitcoinj/core/TransactionOutPoint.java index 1fc6eb42..643008db 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionOutPoint.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionOutPoint.java @@ -145,7 +145,7 @@ public class TransactionOutPoint extends ChildMessage { byte[] addressBytes = ScriptPattern.extractHashFromPayToPubKeyHash(connectedScript); return keyBag.findKeyFromPubHash(addressBytes); } else if (ScriptPattern.isPayToPubKey(connectedScript)) { - byte[] pubkeyBytes = connectedScript.getPubKey(); + byte[] pubkeyBytes = ScriptPattern.extractKeyFromPayToPubKey(connectedScript); return keyBag.findKeyFromPubKey(pubkeyBytes); } else { throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Could not understand form of connected output script: " + connectedScript); @@ -168,7 +168,7 @@ public class TransactionOutPoint extends ChildMessage { byte[] addressBytes = ScriptPattern.extractHashFromPayToPubKeyHash(connectedScript); return RedeemData.of(keyBag.findKeyFromPubHash(addressBytes), connectedScript); } else if (ScriptPattern.isPayToPubKey(connectedScript)) { - byte[] pubkeyBytes = connectedScript.getPubKey(); + byte[] pubkeyBytes = ScriptPattern.extractKeyFromPayToPubKey(connectedScript); return RedeemData.of(keyBag.findKeyFromPubKey(pubkeyBytes), connectedScript); } else if (ScriptPattern.isPayToScriptHash(connectedScript)) { byte[] scriptHash = ScriptPattern.extractHashFromPayToScriptHash(connectedScript); diff --git a/core/src/main/java/org/bitcoinj/core/TransactionOutput.java b/core/src/main/java/org/bitcoinj/core/TransactionOutput.java index 3760cdcf..8863aead 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionOutput.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionOutput.java @@ -322,8 +322,7 @@ public class TransactionOutput extends ChildMessage { try { Script script = getScriptPubKey(); if (ScriptPattern.isPayToPubKey(script)) { - byte[] pubkey = script.getPubKey(); - return transactionBag.isPubKeyMine(pubkey); + return transactionBag.isPubKeyMine(ScriptPattern.extractKeyFromPayToPubKey(script)); } if (ScriptPattern.isPayToScriptHash(script)) { return transactionBag.isPayToScriptHashMine(ScriptPattern.extractHashFromPayToScriptHash(script)); } else { @@ -349,7 +348,7 @@ public class TransactionOutput extends ChildMessage { if (ScriptPattern.isPayToPubKeyHash(script) || ScriptPattern.isPayToScriptHash(script)) buf.append(" to ").append(script.getToAddress(params)); else if (ScriptPattern.isPayToPubKey(script)) - buf.append(" to pubkey ").append(Utils.HEX.encode(script.getPubKey())); + buf.append(" to pubkey ").append(Utils.HEX.encode(ScriptPattern.extractKeyFromPayToPubKey(script))); else if (ScriptPattern.isSentToMultisig(script)) buf.append(" to multisig"); else diff --git a/core/src/main/java/org/bitcoinj/script/Script.java b/core/src/main/java/org/bitcoinj/script/Script.java index 2d8e936a..69b36372 100644 --- a/core/src/main/java/org/bitcoinj/script/Script.java +++ b/core/src/main/java/org/bitcoinj/script/Script.java @@ -257,27 +257,6 @@ public class Script { throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Script not in the standard scriptPubKey form"); } - /** - * Returns the public key in this script. If a script contains a constant and an OP_CHECKSIG opcode, the constant is returned as it is - * assumed to be a direct pay-to-key scriptPubKey (output) and the first constant is the public key. - * - * @throws ScriptException if the script is none of the named forms. - */ - public byte[] getPubKey() throws ScriptException { - if (chunks.size() != 2) { - throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Script not of right size, expecting 2 but got " + chunks.size()); - } - final ScriptChunk chunk0 = chunks.get(0); - final byte[] chunk0data = chunk0.data; - final ScriptChunk chunk1 = chunks.get(1); - if (chunk1.equalsOpCode(OP_CHECKSIG) && chunk0data != null && chunk0data.length > 2) { - // A large constant followed by an OP_CHECKSIG is the key. - return chunk0data; - } else { - throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Script did not match expected form: " + this); - } - } - /** * Retrieves the sender public key from a LOCKTIMEVERIFY transaction * @return the sender public key @@ -310,14 +289,14 @@ public class Script { } /** - * Gets the destination address from this script, if it's in the required form (see getPubKey). + * Gets the destination address from this script, if it's in the required form. */ public Address getToAddress(NetworkParameters params) throws ScriptException { return getToAddress(params, false); } /** - * Gets the destination address from this script, if it's in the required form (see getPubKey). + * Gets the destination address from this script, if it's in the required form. * * @param forcePayToPubKey * If true, allow payToPubKey to be casted to the corresponding address. This is useful if you prefer @@ -329,7 +308,7 @@ public class Script { else if (ScriptPattern.isPayToScriptHash(this)) return Address.fromP2SHScript(params, this); else if (forcePayToPubKey && ScriptPattern.isPayToPubKey(this)) - return Address.fromKey(params, ECKey.fromPublicOnly(getPubKey())); + return Address.fromKey(params, ECKey.fromPublicOnly(ScriptPattern.extractKeyFromPayToPubKey(this))); else throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Cannot cast this script to a pay-to-address type"); } diff --git a/core/src/main/java/org/bitcoinj/script/ScriptPattern.java b/core/src/main/java/org/bitcoinj/script/ScriptPattern.java index 48be7fbd..d6afe82f 100644 --- a/core/src/main/java/org/bitcoinj/script/ScriptPattern.java +++ b/core/src/main/java/org/bitcoinj/script/ScriptPattern.java @@ -88,6 +88,10 @@ public class ScriptPattern { chunks.get(0).data.length > 1; } + public static byte[] extractKeyFromPayToPubKey(Script script) { + return script.chunks.get(0).data; + } + /** * Returns whether this script matches the format used for multisig outputs: [n] [keys...] [m] CHECKMULTISIG */ diff --git a/core/src/main/java/org/bitcoinj/wallet/KeyTimeCoinSelector.java b/core/src/main/java/org/bitcoinj/wallet/KeyTimeCoinSelector.java index 2b178a62..33c52d9c 100644 --- a/core/src/main/java/org/bitcoinj/wallet/KeyTimeCoinSelector.java +++ b/core/src/main/java/org/bitcoinj/wallet/KeyTimeCoinSelector.java @@ -63,7 +63,7 @@ public class KeyTimeCoinSelector implements CoinSelector { final Script scriptPubKey = output.getScriptPubKey(); ECKey controllingKey; if (ScriptPattern.isPayToPubKey(scriptPubKey)) { - controllingKey = wallet.findKeyFromPubKey(scriptPubKey.getPubKey()); + controllingKey = wallet.findKeyFromPubKey(ScriptPattern.extractKeyFromPayToPubKey(scriptPubKey)); } else if (ScriptPattern.isPayToPubKeyHash(scriptPubKey)) { controllingKey = wallet.findKeyFromPubHash(ScriptPattern.extractHashFromPayToPubKeyHash(scriptPubKey)); } else { diff --git a/core/src/main/java/org/bitcoinj/wallet/Wallet.java b/core/src/main/java/org/bitcoinj/wallet/Wallet.java index 685e32bd..43ed36b7 100644 --- a/core/src/main/java/org/bitcoinj/wallet/Wallet.java +++ b/core/src/main/java/org/bitcoinj/wallet/Wallet.java @@ -1079,7 +1079,7 @@ public class Wallet extends BaseTaggableObject try { Script script = o.getScriptPubKey(); if (ScriptPattern.isPayToPubKey(script)) { - byte[] pubkey = script.getPubKey(); + byte[] pubkey = ScriptPattern.extractKeyFromPayToPubKey(script); keyChainGroup.markPubKeyAsUsed(pubkey); } else if (ScriptPattern.isPayToPubKeyHash(script)) { byte[] pubkeyHash = ScriptPattern.extractHashFromPayToPubKeyHash(script); @@ -4188,7 +4188,7 @@ public class Wallet extends BaseTaggableObject */ public boolean canSignFor(Script script) { if (ScriptPattern.isPayToPubKey(script)) { - byte[] pubkey = script.getPubKey(); + byte[] pubkey = ScriptPattern.extractKeyFromPayToPubKey(script); ECKey key = findKeyFromPubKey(pubkey); return key != null && (key.isEncrypted() || key.hasPrivKey()); } if (ScriptPattern.isPayToScriptHash(script)) { diff --git a/core/src/test/java/org/bitcoinj/script/ScriptTest.java b/core/src/test/java/org/bitcoinj/script/ScriptTest.java index e2d99427..1553c7b6 100644 --- a/core/src/test/java/org/bitcoinj/script/ScriptTest.java +++ b/core/src/test/java/org/bitcoinj/script/ScriptTest.java @@ -79,7 +79,7 @@ public class ScriptTest { byte[] pubkeyBytes = HEX.decode(pubkeyProg); Script pubkey = new Script(pubkeyBytes); assertEquals("DUP HASH160 PUSHDATA(20)[33e81a941e64cda12c6a299ed322ddbdd03f8d0e] EQUALVERIFY CHECKSIG", pubkey.toString()); - Address toAddr = new Address(PARAMS, pubkey.getPubKeyHash()); + Address toAddr = new Address(PARAMS, ScriptPattern.extractHashFromPayToPubKeyHash(pubkey)); assertEquals("mkFQohBpy2HDXrCwyMrYL5RtfrmeiuuPY2", toAddr.toString()); } diff --git a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java index 8b40ba8c..98e62d76 100644 --- a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java +++ b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java @@ -40,6 +40,7 @@ import org.bitcoinj.crypto.*; import org.bitcoinj.script.Script; import org.bitcoinj.script.ScriptBuilder; import org.bitcoinj.script.ScriptChunk; +import org.bitcoinj.script.ScriptPattern; import org.bitcoinj.signers.StatelessTransactionSigner; import org.bitcoinj.signers.TransactionSigner; import org.bitcoinj.store.BlockStoreException; @@ -2267,7 +2268,8 @@ public class WalletTest extends TestWithWallet { public void sendRequestP2PKTest() { ECKey key = new ECKey(); SendRequest req = SendRequest.to(PARAMS, key, SATOSHI.multiply(12)); - assertArrayEquals(key.getPubKey(), req.tx.getOutputs().get(0).getScriptPubKey().getPubKey()); + assertArrayEquals(key.getPubKey(), + ScriptPattern.extractKeyFromPayToPubKey(req.tx.getOutputs().get(0).getScriptPubKey())); } @Test