mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-08-01 12:31:23 +00:00
Script: Extract the extraction of the P2PKH and P2SH hashes to ScriptPattern.
This commit is contained in:
@@ -76,7 +76,7 @@ public class Address extends VersionedChecksummedBytes {
|
|||||||
/** Returns an Address that represents the script hash extracted from the given scriptPubKey */
|
/** Returns an Address that represents the script hash extracted from the given scriptPubKey */
|
||||||
public static Address fromP2SHScript(NetworkParameters params, Script scriptPubKey) {
|
public static Address fromP2SHScript(NetworkParameters params, Script scriptPubKey) {
|
||||||
checkArgument(ScriptPattern.isPayToScriptHash(scriptPubKey), "Not a P2SH script");
|
checkArgument(ScriptPattern.isPayToScriptHash(scriptPubKey), "Not a P2SH script");
|
||||||
return fromP2SHHash(params, scriptPubKey.getPubKeyHash());
|
return fromP2SHHash(params, ScriptPattern.extractHashFromPayToScriptHash(scriptPubKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -705,9 +705,12 @@ public class Transaction extends ChildMessage {
|
|||||||
final TransactionOutput connectedOutput = outpoint.getConnectedOutput();
|
final TransactionOutput connectedOutput = outpoint.getConnectedOutput();
|
||||||
if (connectedOutput != null) {
|
if (connectedOutput != null) {
|
||||||
Script scriptPubKey = connectedOutput.getScriptPubKey();
|
Script scriptPubKey = connectedOutput.getScriptPubKey();
|
||||||
if (ScriptPattern.isPayToPubKeyHash(scriptPubKey) || ScriptPattern.isPayToScriptHash(scriptPubKey)) {
|
try {
|
||||||
|
byte[] pubKeyHash = scriptPubKey.getPubKeyHash();
|
||||||
s.append(" hash160:");
|
s.append(" hash160:");
|
||||||
s.append(Utils.HEX.encode(scriptPubKey.getPubKeyHash()));
|
s.append(Utils.HEX.encode(pubKeyHash));
|
||||||
|
} catch (ScriptException x) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (in.hasSequence()) {
|
if (in.hasSequence()) {
|
||||||
|
@@ -142,7 +142,7 @@ public class TransactionOutPoint extends ChildMessage {
|
|||||||
checkNotNull(connectedOutput, "Input is not connected so cannot retrieve key");
|
checkNotNull(connectedOutput, "Input is not connected so cannot retrieve key");
|
||||||
Script connectedScript = connectedOutput.getScriptPubKey();
|
Script connectedScript = connectedOutput.getScriptPubKey();
|
||||||
if (ScriptPattern.isPayToPubKeyHash(connectedScript)) {
|
if (ScriptPattern.isPayToPubKeyHash(connectedScript)) {
|
||||||
byte[] addressBytes = connectedScript.getPubKeyHash();
|
byte[] addressBytes = ScriptPattern.extractHashFromPayToPubKeyHash(connectedScript);
|
||||||
return keyBag.findKeyFromPubHash(addressBytes);
|
return keyBag.findKeyFromPubHash(addressBytes);
|
||||||
} else if (ScriptPattern.isPayToPubKey(connectedScript)) {
|
} else if (ScriptPattern.isPayToPubKey(connectedScript)) {
|
||||||
byte[] pubkeyBytes = connectedScript.getPubKey();
|
byte[] pubkeyBytes = connectedScript.getPubKey();
|
||||||
@@ -165,13 +165,13 @@ public class TransactionOutPoint extends ChildMessage {
|
|||||||
checkNotNull(connectedOutput, "Input is not connected so cannot retrieve key");
|
checkNotNull(connectedOutput, "Input is not connected so cannot retrieve key");
|
||||||
Script connectedScript = connectedOutput.getScriptPubKey();
|
Script connectedScript = connectedOutput.getScriptPubKey();
|
||||||
if (ScriptPattern.isPayToPubKeyHash(connectedScript)) {
|
if (ScriptPattern.isPayToPubKeyHash(connectedScript)) {
|
||||||
byte[] addressBytes = connectedScript.getPubKeyHash();
|
byte[] addressBytes = ScriptPattern.extractHashFromPayToPubKeyHash(connectedScript);
|
||||||
return RedeemData.of(keyBag.findKeyFromPubHash(addressBytes), connectedScript);
|
return RedeemData.of(keyBag.findKeyFromPubHash(addressBytes), connectedScript);
|
||||||
} else if (ScriptPattern.isPayToPubKey(connectedScript)) {
|
} else if (ScriptPattern.isPayToPubKey(connectedScript)) {
|
||||||
byte[] pubkeyBytes = connectedScript.getPubKey();
|
byte[] pubkeyBytes = connectedScript.getPubKey();
|
||||||
return RedeemData.of(keyBag.findKeyFromPubKey(pubkeyBytes), connectedScript);
|
return RedeemData.of(keyBag.findKeyFromPubKey(pubkeyBytes), connectedScript);
|
||||||
} else if (ScriptPattern.isPayToScriptHash(connectedScript)) {
|
} else if (ScriptPattern.isPayToScriptHash(connectedScript)) {
|
||||||
byte[] scriptHash = connectedScript.getPubKeyHash();
|
byte[] scriptHash = ScriptPattern.extractHashFromPayToScriptHash(connectedScript);
|
||||||
return keyBag.findRedeemDataFromScriptHash(scriptHash);
|
return keyBag.findRedeemDataFromScriptHash(scriptHash);
|
||||||
} else {
|
} else {
|
||||||
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Could not understand form of connected output script: " + connectedScript);
|
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Could not understand form of connected output script: " + connectedScript);
|
||||||
|
@@ -325,7 +325,7 @@ public class TransactionOutput extends ChildMessage {
|
|||||||
byte[] pubkey = script.getPubKey();
|
byte[] pubkey = script.getPubKey();
|
||||||
return transactionBag.isPubKeyMine(pubkey);
|
return transactionBag.isPubKeyMine(pubkey);
|
||||||
} if (ScriptPattern.isPayToScriptHash(script)) {
|
} if (ScriptPattern.isPayToScriptHash(script)) {
|
||||||
return transactionBag.isPayToScriptHashMine(script.getPubKeyHash());
|
return transactionBag.isPayToScriptHashMine(ScriptPattern.extractHashFromPayToScriptHash(script));
|
||||||
} else {
|
} else {
|
||||||
byte[] pubkeyHash = script.getPubKeyHash();
|
byte[] pubkeyHash = script.getPubKeyHash();
|
||||||
return transactionBag.isPubKeyHashMine(pubkeyHash);
|
return transactionBag.isPubKeyHashMine(pubkeyHash);
|
||||||
|
@@ -250,9 +250,9 @@ public class Script {
|
|||||||
*/
|
*/
|
||||||
public byte[] getPubKeyHash() throws ScriptException {
|
public byte[] getPubKeyHash() throws ScriptException {
|
||||||
if (ScriptPattern.isPayToPubKeyHash(this))
|
if (ScriptPattern.isPayToPubKeyHash(this))
|
||||||
return chunks.get(2).data;
|
return ScriptPattern.extractHashFromPayToPubKeyHash(this);
|
||||||
else if (ScriptPattern.isPayToScriptHash(this))
|
else if (ScriptPattern.isPayToScriptHash(this))
|
||||||
return chunks.get(1).data;
|
return ScriptPattern.extractHashFromPayToScriptHash(this);
|
||||||
else
|
else
|
||||||
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Script not in the standard scriptPubKey form");
|
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 {
|
public Address getToAddress(NetworkParameters params, boolean forcePayToPubKey) throws ScriptException {
|
||||||
if (ScriptPattern.isPayToPubKeyHash(this))
|
if (ScriptPattern.isPayToPubKeyHash(this))
|
||||||
return new Address(params, getPubKeyHash());
|
return new Address(params, ScriptPattern.extractHashFromPayToPubKeyHash(this));
|
||||||
else if (ScriptPattern.isPayToScriptHash(this))
|
else if (ScriptPattern.isPayToScriptHash(this))
|
||||||
return Address.fromP2SHScript(params, this);
|
return Address.fromP2SHScript(params, this);
|
||||||
else if (forcePayToPubKey && ScriptPattern.isPayToPubKey(this))
|
else if (forcePayToPubKey && ScriptPattern.isPayToPubKey(this))
|
||||||
|
@@ -45,6 +45,10 @@ public class ScriptPattern {
|
|||||||
chunks.get(4).equalsOpCode(OP_CHECKSIG);
|
chunks.get(4).equalsOpCode(OP_CHECKSIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] extractHashFromPayToPubKeyHash(Script script) {
|
||||||
|
return script.chunks.get(2).data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Whether or not this is a scriptPubKey representing a pay-to-script-hash output. In such outputs, the logic that
|
* <p>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
|
* 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);
|
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 <pubkey> OP_CHECKSIG. This form was originally intended for transactions
|
* Returns true if this script is of the form <pubkey> OP_CHECKSIG. This form was originally intended for transactions
|
||||||
* where the peers talked to each other directly via TCP/IP, but has fallen out of favor with time due to that mode
|
* where the peers talked to each other directly via TCP/IP, but has fallen out of favor with time due to that mode
|
||||||
|
@@ -65,7 +65,7 @@ public class KeyTimeCoinSelector implements CoinSelector {
|
|||||||
if (ScriptPattern.isPayToPubKey(scriptPubKey)) {
|
if (ScriptPattern.isPayToPubKey(scriptPubKey)) {
|
||||||
controllingKey = wallet.findKeyFromPubKey(scriptPubKey.getPubKey());
|
controllingKey = wallet.findKeyFromPubKey(scriptPubKey.getPubKey());
|
||||||
} else if (ScriptPattern.isPayToPubKeyHash(scriptPubKey)) {
|
} else if (ScriptPattern.isPayToPubKeyHash(scriptPubKey)) {
|
||||||
controllingKey = wallet.findKeyFromPubHash(scriptPubKey.getPubKeyHash());
|
controllingKey = wallet.findKeyFromPubHash(ScriptPattern.extractHashFromPayToPubKeyHash(scriptPubKey));
|
||||||
} else {
|
} else {
|
||||||
log.info("Skipping tx output {} because it's not of simple form.", output);
|
log.info("Skipping tx output {} because it's not of simple form.", output);
|
||||||
continue;
|
continue;
|
||||||
|
@@ -1082,7 +1082,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
byte[] pubkey = script.getPubKey();
|
byte[] pubkey = script.getPubKey();
|
||||||
keyChainGroup.markPubKeyAsUsed(pubkey);
|
keyChainGroup.markPubKeyAsUsed(pubkey);
|
||||||
} else if (ScriptPattern.isPayToPubKeyHash(script)) {
|
} else if (ScriptPattern.isPayToPubKeyHash(script)) {
|
||||||
byte[] pubkeyHash = script.getPubKeyHash();
|
byte[] pubkeyHash = ScriptPattern.extractHashFromPayToPubKeyHash(script);
|
||||||
keyChainGroup.markPubKeyHashAsUsed(pubkeyHash);
|
keyChainGroup.markPubKeyHashAsUsed(pubkeyHash);
|
||||||
} else if (ScriptPattern.isPayToScriptHash(script)) {
|
} else if (ScriptPattern.isPayToScriptHash(script)) {
|
||||||
Address a = Address.fromP2SHScript(tx.getParams(), script);
|
Address a = Address.fromP2SHScript(tx.getParams(), script);
|
||||||
@@ -4192,10 +4192,10 @@ public class Wallet extends BaseTaggableObject
|
|||||||
ECKey key = findKeyFromPubKey(pubkey);
|
ECKey key = findKeyFromPubKey(pubkey);
|
||||||
return key != null && (key.isEncrypted() || key.hasPrivKey());
|
return key != null && (key.isEncrypted() || key.hasPrivKey());
|
||||||
} if (ScriptPattern.isPayToScriptHash(script)) {
|
} if (ScriptPattern.isPayToScriptHash(script)) {
|
||||||
RedeemData data = findRedeemDataFromScriptHash(script.getPubKeyHash());
|
RedeemData data = findRedeemDataFromScriptHash(ScriptPattern.extractHashFromPayToScriptHash(script));
|
||||||
return data != null && canSignFor(data.redeemScript);
|
return data != null && canSignFor(data.redeemScript);
|
||||||
} else if (ScriptPattern.isPayToPubKeyHash(script)) {
|
} else if (ScriptPattern.isPayToPubKeyHash(script)) {
|
||||||
ECKey key = findKeyFromPubHash(script.getPubKeyHash());
|
ECKey key = findKeyFromPubHash(ScriptPattern.extractHashFromPayToPubKeyHash(script));
|
||||||
return key != null && (key.isEncrypted() || key.hasPrivKey());
|
return key != null && (key.isEncrypted() || key.hasPrivKey());
|
||||||
} else if (ScriptPattern.isSentToMultisig(script)) {
|
} else if (ScriptPattern.isSentToMultisig(script)) {
|
||||||
for (ECKey pubkey : script.getPubKeys()) {
|
for (ECKey pubkey : script.getPubKeys()) {
|
||||||
@@ -4982,10 +4982,10 @@ public class Wallet extends BaseTaggableObject
|
|||||||
ECKey key = null;
|
ECKey key = null;
|
||||||
Script redeemScript = null;
|
Script redeemScript = null;
|
||||||
if (ScriptPattern.isPayToPubKeyHash(script)) {
|
if (ScriptPattern.isPayToPubKeyHash(script)) {
|
||||||
key = findKeyFromPubHash(script.getPubKeyHash());
|
key = findKeyFromPubHash(ScriptPattern.extractHashFromPayToPubKeyHash(script));
|
||||||
checkNotNull(key, "Coin selection includes unspendable outputs");
|
checkNotNull(key, "Coin selection includes unspendable outputs");
|
||||||
} else if (ScriptPattern.isPayToScriptHash(script)) {
|
} else if (ScriptPattern.isPayToScriptHash(script)) {
|
||||||
redeemScript = findRedeemDataFromScriptHash(script.getPubKeyHash()).redeemScript;
|
redeemScript = findRedeemDataFromScriptHash(ScriptPattern.extractHashFromPayToScriptHash(script)).redeemScript;
|
||||||
checkNotNull(redeemScript, "Coin selection includes unspendable outputs");
|
checkNotNull(redeemScript, "Coin selection includes unspendable outputs");
|
||||||
}
|
}
|
||||||
size += script.getNumberOfBytesRequiredToSpend(key, redeemScript);
|
size += script.getNumberOfBytesRequiredToSpend(key, redeemScript);
|
||||||
|
Reference in New Issue
Block a user