diff --git a/core/src/main/java/org/bitcoinj/core/Address.java b/core/src/main/java/org/bitcoinj/core/Address.java index 0e43293f..ef455299 100644 --- a/core/src/main/java/org/bitcoinj/core/Address.java +++ b/core/src/main/java/org/bitcoinj/core/Address.java @@ -76,7 +76,7 @@ public class Address extends VersionedChecksummedBytes { /** Returns an Address that represents the script hash extracted from the given scriptPubKey */ public static Address fromP2SHScript(NetworkParameters params, Script scriptPubKey) { checkArgument(ScriptPattern.isPayToScriptHash(scriptPubKey), "Not a P2SH script"); - return fromP2SHHash(params, scriptPubKey.getPubKeyHash()); + return fromP2SHHash(params, ScriptPattern.extractHashFromPayToScriptHash(scriptPubKey)); } /** diff --git a/core/src/main/java/org/bitcoinj/core/Transaction.java b/core/src/main/java/org/bitcoinj/core/Transaction.java index 15824cc1..acabca84 100644 --- a/core/src/main/java/org/bitcoinj/core/Transaction.java +++ b/core/src/main/java/org/bitcoinj/core/Transaction.java @@ -705,9 +705,12 @@ public class Transaction extends ChildMessage { final TransactionOutput connectedOutput = outpoint.getConnectedOutput(); if (connectedOutput != null) { Script scriptPubKey = connectedOutput.getScriptPubKey(); - if (ScriptPattern.isPayToPubKeyHash(scriptPubKey) || ScriptPattern.isPayToScriptHash(scriptPubKey)) { + try { + byte[] pubKeyHash = scriptPubKey.getPubKeyHash(); s.append(" hash160:"); - s.append(Utils.HEX.encode(scriptPubKey.getPubKeyHash())); + s.append(Utils.HEX.encode(pubKeyHash)); + } catch (ScriptException x) { + // ignore } } if (in.hasSequence()) { diff --git a/core/src/main/java/org/bitcoinj/core/TransactionOutPoint.java b/core/src/main/java/org/bitcoinj/core/TransactionOutPoint.java index dfcb7047..1fc6eb42 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionOutPoint.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionOutPoint.java @@ -142,7 +142,7 @@ public class TransactionOutPoint extends ChildMessage { checkNotNull(connectedOutput, "Input is not connected so cannot retrieve key"); Script connectedScript = connectedOutput.getScriptPubKey(); if (ScriptPattern.isPayToPubKeyHash(connectedScript)) { - byte[] addressBytes = connectedScript.getPubKeyHash(); + byte[] addressBytes = ScriptPattern.extractHashFromPayToPubKeyHash(connectedScript); return keyBag.findKeyFromPubHash(addressBytes); } else if (ScriptPattern.isPayToPubKey(connectedScript)) { byte[] pubkeyBytes = connectedScript.getPubKey(); @@ -165,13 +165,13 @@ public class TransactionOutPoint extends ChildMessage { checkNotNull(connectedOutput, "Input is not connected so cannot retrieve key"); Script connectedScript = connectedOutput.getScriptPubKey(); if (ScriptPattern.isPayToPubKeyHash(connectedScript)) { - byte[] addressBytes = connectedScript.getPubKeyHash(); + byte[] addressBytes = ScriptPattern.extractHashFromPayToPubKeyHash(connectedScript); return RedeemData.of(keyBag.findKeyFromPubHash(addressBytes), connectedScript); } else if (ScriptPattern.isPayToPubKey(connectedScript)) { byte[] pubkeyBytes = connectedScript.getPubKey(); return RedeemData.of(keyBag.findKeyFromPubKey(pubkeyBytes), connectedScript); } else if (ScriptPattern.isPayToScriptHash(connectedScript)) { - byte[] scriptHash = connectedScript.getPubKeyHash(); + byte[] scriptHash = ScriptPattern.extractHashFromPayToScriptHash(connectedScript); return keyBag.findRedeemDataFromScriptHash(scriptHash); } else { throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Could not understand form of connected output script: " + connectedScript); diff --git a/core/src/main/java/org/bitcoinj/core/TransactionOutput.java b/core/src/main/java/org/bitcoinj/core/TransactionOutput.java index 5da8dbd4..3760cdcf 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionOutput.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionOutput.java @@ -325,7 +325,7 @@ public class TransactionOutput extends ChildMessage { byte[] pubkey = script.getPubKey(); return transactionBag.isPubKeyMine(pubkey); } if (ScriptPattern.isPayToScriptHash(script)) { - return transactionBag.isPayToScriptHashMine(script.getPubKeyHash()); + return transactionBag.isPayToScriptHashMine(ScriptPattern.extractHashFromPayToScriptHash(script)); } else { byte[] pubkeyHash = script.getPubKeyHash(); return transactionBag.isPubKeyHashMine(pubkeyHash); diff --git a/core/src/main/java/org/bitcoinj/script/Script.java b/core/src/main/java/org/bitcoinj/script/Script.java index 7230040b..4597a98d 100644 --- a/core/src/main/java/org/bitcoinj/script/Script.java +++ b/core/src/main/java/org/bitcoinj/script/Script.java @@ -250,9 +250,9 @@ public class Script { */ public byte[] getPubKeyHash() throws ScriptException { if (ScriptPattern.isPayToPubKeyHash(this)) - return chunks.get(2).data; + return ScriptPattern.extractHashFromPayToPubKeyHash(this); else if (ScriptPattern.isPayToScriptHash(this)) - return chunks.get(1).data; + return ScriptPattern.extractHashFromPayToScriptHash(this); else throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Script not in the standard scriptPubKey form"); } @@ -341,7 +341,7 @@ public class Script { */ public Address getToAddress(NetworkParameters params, boolean forcePayToPubKey) throws ScriptException { if (ScriptPattern.isPayToPubKeyHash(this)) - return new Address(params, getPubKeyHash()); + return new Address(params, ScriptPattern.extractHashFromPayToPubKeyHash(this)); else if (ScriptPattern.isPayToScriptHash(this)) return Address.fromP2SHScript(params, this); else if (forcePayToPubKey && ScriptPattern.isPayToPubKey(this)) diff --git a/core/src/main/java/org/bitcoinj/script/ScriptPattern.java b/core/src/main/java/org/bitcoinj/script/ScriptPattern.java index 1aaa209c..48be7fbd 100644 --- a/core/src/main/java/org/bitcoinj/script/ScriptPattern.java +++ b/core/src/main/java/org/bitcoinj/script/ScriptPattern.java @@ -45,6 +45,10 @@ public class ScriptPattern { chunks.get(4).equalsOpCode(OP_CHECKSIG); } + public static byte[] extractHashFromPayToPubKeyHash(Script script) { + return script.chunks.get(2).data; + } + /** *
Whether or not this is a scriptPubKey representing a pay-to-script-hash output. In such outputs, the logic that
* controls reclamation is not actually in the output at all. Instead there's just a hash, and it's up to the
@@ -65,6 +69,10 @@ public class ScriptPattern {
chunks.get(2).equalsOpCode(OP_EQUAL);
}
+ public static byte[] extractHashFromPayToScriptHash(Script script) {
+ return script.chunks.get(1).data;
+ }
+
/**
* Returns true if this script is of the form