Script: Move getPubKey() to ScriptPattern.extractKeyFromPayToPubKey().

This commit is contained in:
Andreas Schildbach
2018-02-26 11:00:29 +01:00
parent 234384c87e
commit c6bbd947a0
8 changed files with 18 additions and 34 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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
*/

View File

@@ -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 {

View File

@@ -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)) {

View File

@@ -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());
}

View File

@@ -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