mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2024-11-19 18:00:39 +01:00
Script: Deprecate the old matcher methods, move their Javadocs over to ScriptPattern and use only the equivalents in ScriptPattern.
This commit is contained in:
parent
8d98c3e1e2
commit
e44591a9b5
@ -24,6 +24,7 @@ import java.io.ObjectOutputStream;
|
||||
|
||||
import org.bitcoinj.params.Networks;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -74,7 +75,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(scriptPubKey.isPayToScriptHash(), "Not a P2SH script");
|
||||
checkArgument(ScriptPattern.isPayToScriptHash(scriptPubKey), "Not a P2SH script");
|
||||
return fromP2SHHash(params, scriptPubKey.getPubKeyHash());
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@ package org.bitcoinj.core;
|
||||
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptChunk;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@ -330,7 +332,7 @@ public class BloomFilter extends Message {
|
||||
if (!chunk.isPushData())
|
||||
continue;
|
||||
if (contains(chunk.data)) {
|
||||
boolean isSendingToPubKeys = script.isSentToRawPubKey() || script.isSentToMultiSig();
|
||||
boolean isSendingToPubKeys = ScriptPattern.isPayToPubKey(script) || ScriptPattern.isSentToMultisig(script);
|
||||
if (flag == BloomUpdate.UPDATE_ALL || (flag == BloomUpdate.UPDATE_P2PUBKEY_ONLY && isSendingToPubKeys))
|
||||
insert(output.getOutPointFor().unsafeBitcoinSerialize());
|
||||
found = true;
|
||||
|
@ -19,6 +19,7 @@ package org.bitcoinj.core;
|
||||
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.Script.VerifyFlag;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
import org.bitcoinj.store.BlockStoreException;
|
||||
import org.bitcoinj.store.FullPrunedBlockStore;
|
||||
import org.bitcoinj.utils.*;
|
||||
@ -269,7 +270,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
||||
// TODO: Check we're not spending the genesis transaction here. Bitcoin Core won't allow it.
|
||||
valueIn = valueIn.add(prevOut.getValue());
|
||||
if (verifyFlags.contains(VerifyFlag.P2SH)) {
|
||||
if (prevOut.getScript().isPayToScriptHash())
|
||||
if (ScriptPattern.isPayToScriptHash(prevOut.getScript()))
|
||||
sigOps += Script.getP2SHSigOpCount(in.getScriptBytes());
|
||||
if (sigOps > Block.MAX_BLOCK_SIGOPS)
|
||||
throw new VerificationException("Too many P2SH SigOps in block");
|
||||
@ -397,7 +398,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
||||
throw new VerificationException("Tried to spend coinbase at depth " + (newBlock.getHeight() - prevOut.getHeight()));
|
||||
valueIn = valueIn.add(prevOut.getValue());
|
||||
if (verifyFlags.contains(VerifyFlag.P2SH)) {
|
||||
if (prevOut.getScript().isPayToScriptHash())
|
||||
if (ScriptPattern.isPayToScriptHash(prevOut.getScript()))
|
||||
sigOps += Script.getP2SHSigOpCount(in.getScriptBytes());
|
||||
if (sigOps > Block.MAX_BLOCK_SIGOPS)
|
||||
throw new VerificationException("Too many P2SH SigOps in block");
|
||||
|
@ -200,7 +200,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
// filter. In case (1), we need to retransmit the filter to the connected peers. In case (2), we don't
|
||||
// and shouldn't, we should just recalculate and cache the new filter for next time.
|
||||
for (TransactionOutput output : tx.getOutputs()) {
|
||||
if (output.getScriptPubKey().isSentToRawPubKey() && output.isMine(wallet)) {
|
||||
if (ScriptPattern.isPayToPubKey(output.getScriptPubKey()) && output.isMine(wallet)) {
|
||||
if (tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
|
||||
recalculateFastCatchupAndFilter(FilterRecalculateMode.SEND_IF_CHANGED);
|
||||
else
|
||||
|
@ -24,6 +24,7 @@ import org.bitcoinj.script.ScriptBuilder;
|
||||
import org.bitcoinj.script.ScriptError;
|
||||
import org.bitcoinj.script.ScriptException;
|
||||
import org.bitcoinj.script.ScriptOpCodes;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
import org.bitcoinj.signers.TransactionSigner;
|
||||
import org.bitcoinj.utils.ExchangeRate;
|
||||
import org.bitcoinj.wallet.Wallet;
|
||||
@ -704,7 +705,7 @@ public class Transaction extends ChildMessage {
|
||||
final TransactionOutput connectedOutput = outpoint.getConnectedOutput();
|
||||
if (connectedOutput != null) {
|
||||
Script scriptPubKey = connectedOutput.getScriptPubKey();
|
||||
if (scriptPubKey.isSentToAddress() || scriptPubKey.isPayToScriptHash()) {
|
||||
if (ScriptPattern.isPayToPubKeyHash(scriptPubKey) || ScriptPattern.isPayToScriptHash(scriptPubKey)) {
|
||||
s.append(" hash160:");
|
||||
s.append(Utils.HEX.encode(scriptPubKey.getPubKeyHash()));
|
||||
}
|
||||
@ -819,9 +820,9 @@ public class Transaction extends ChildMessage {
|
||||
Sha256Hash hash = hashForSignature(inputs.size() - 1, scriptPubKey, sigHash, anyoneCanPay);
|
||||
ECKey.ECDSASignature ecSig = sigKey.sign(hash);
|
||||
TransactionSignature txSig = new TransactionSignature(ecSig, sigHash, anyoneCanPay);
|
||||
if (scriptPubKey.isSentToRawPubKey())
|
||||
if (ScriptPattern.isPayToPubKey(scriptPubKey))
|
||||
input.setScriptSig(ScriptBuilder.createInputScript(txSig));
|
||||
else if (scriptPubKey.isSentToAddress())
|
||||
else if (ScriptPattern.isPayToPubKeyHash(scriptPubKey))
|
||||
input.setScriptSig(ScriptBuilder.createInputScript(txSig, sigKey));
|
||||
else
|
||||
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Don't know how to sign for this kind of scriptPubKey: " + scriptPubKey);
|
||||
|
@ -141,10 +141,10 @@ public class TransactionOutPoint extends ChildMessage {
|
||||
TransactionOutput connectedOutput = getConnectedOutput();
|
||||
checkNotNull(connectedOutput, "Input is not connected so cannot retrieve key");
|
||||
Script connectedScript = connectedOutput.getScriptPubKey();
|
||||
if (connectedScript.isSentToAddress()) {
|
||||
if (ScriptPattern.isPayToPubKeyHash(connectedScript)) {
|
||||
byte[] addressBytes = connectedScript.getPubKeyHash();
|
||||
return keyBag.findKeyFromPubHash(addressBytes);
|
||||
} else if (connectedScript.isSentToRawPubKey()) {
|
||||
} else if (ScriptPattern.isPayToPubKey(connectedScript)) {
|
||||
byte[] pubkeyBytes = connectedScript.getPubKey();
|
||||
return keyBag.findKeyFromPubKey(pubkeyBytes);
|
||||
} else {
|
||||
@ -164,13 +164,13 @@ public class TransactionOutPoint extends ChildMessage {
|
||||
TransactionOutput connectedOutput = getConnectedOutput();
|
||||
checkNotNull(connectedOutput, "Input is not connected so cannot retrieve key");
|
||||
Script connectedScript = connectedOutput.getScriptPubKey();
|
||||
if (connectedScript.isSentToAddress()) {
|
||||
if (ScriptPattern.isPayToPubKeyHash(connectedScript)) {
|
||||
byte[] addressBytes = connectedScript.getPubKeyHash();
|
||||
return RedeemData.of(keyBag.findKeyFromPubHash(addressBytes), connectedScript);
|
||||
} else if (connectedScript.isSentToRawPubKey()) {
|
||||
} else if (ScriptPattern.isPayToPubKey(connectedScript)) {
|
||||
byte[] pubkeyBytes = connectedScript.getPubKey();
|
||||
return RedeemData.of(keyBag.findKeyFromPubKey(pubkeyBytes), connectedScript);
|
||||
} else if (connectedScript.isPayToScriptHash()) {
|
||||
} else if (ScriptPattern.isPayToScriptHash(connectedScript)) {
|
||||
byte[] scriptHash = connectedScript.getPubKeyHash();
|
||||
return keyBag.findRedeemDataFromScriptHash(scriptHash);
|
||||
} else {
|
||||
|
@ -130,7 +130,7 @@ public class TransactionOutput extends ChildMessage {
|
||||
*/
|
||||
@Nullable
|
||||
public Address getAddressFromP2PKHScript(NetworkParameters networkParameters) throws ScriptException{
|
||||
if (getScriptPubKey().isSentToAddress())
|
||||
if (ScriptPattern.isPayToPubKeyHash(getScriptPubKey()))
|
||||
return getScriptPubKey().getToAddress(networkParameters);
|
||||
|
||||
return null;
|
||||
@ -150,7 +150,7 @@ public class TransactionOutput extends ChildMessage {
|
||||
*/
|
||||
@Nullable
|
||||
public Address getAddressFromP2SH(NetworkParameters networkParameters) throws ScriptException{
|
||||
if (getScriptPubKey().isPayToScriptHash())
|
||||
if (ScriptPattern.isPayToScriptHash(getScriptPubKey()))
|
||||
return getScriptPubKey().getToAddress(networkParameters);
|
||||
|
||||
return null;
|
||||
@ -212,7 +212,7 @@ public class TransactionOutput extends ChildMessage {
|
||||
*/
|
||||
public boolean isDust() {
|
||||
// Transactions that are OP_RETURN can't be dust regardless of their value.
|
||||
if (getScriptPubKey().isOpReturn())
|
||||
if (ScriptPattern.isOpReturn(getScriptPubKey()))
|
||||
return false;
|
||||
return getValue().isLessThan(getMinNonDustValue());
|
||||
}
|
||||
@ -321,10 +321,10 @@ public class TransactionOutput extends ChildMessage {
|
||||
public boolean isMine(TransactionBag transactionBag) {
|
||||
try {
|
||||
Script script = getScriptPubKey();
|
||||
if (script.isSentToRawPubKey()) {
|
||||
if (ScriptPattern.isPayToPubKey(script)) {
|
||||
byte[] pubkey = script.getPubKey();
|
||||
return transactionBag.isPubKeyMine(pubkey);
|
||||
} if (script.isPayToScriptHash()) {
|
||||
} if (ScriptPattern.isPayToScriptHash(script)) {
|
||||
return transactionBag.isPayToScriptHashMine(script.getPubKeyHash());
|
||||
} else {
|
||||
byte[] pubkeyHash = script.getPubKeyHash();
|
||||
@ -346,11 +346,11 @@ public class TransactionOutput extends ChildMessage {
|
||||
Script script = getScriptPubKey();
|
||||
StringBuilder buf = new StringBuilder("TxOut of ");
|
||||
buf.append(Coin.valueOf(value).toFriendlyString());
|
||||
if (script.isSentToAddress() || script.isPayToScriptHash())
|
||||
if (ScriptPattern.isPayToPubKeyHash(script) || ScriptPattern.isPayToScriptHash(script))
|
||||
buf.append(" to ").append(script.getToAddress(params));
|
||||
else if (script.isSentToRawPubKey())
|
||||
else if (ScriptPattern.isPayToPubKey(script))
|
||||
buf.append(" to pubkey ").append(Utils.HEX.encode(script.getPubKey()));
|
||||
else if (script.isSentToMultiSig())
|
||||
else if (ScriptPattern.isSentToMultisig(script))
|
||||
buf.append(" to multisig");
|
||||
else
|
||||
buf.append(" (unknown type)");
|
||||
|
@ -226,22 +226,12 @@ public class Script {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* of operation being susceptible to man-in-the-middle attacks. It is still used in coinbase outputs and can be
|
||||
* useful more exotic types of transaction, but today most payments are to addresses.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isSentToRawPubKey() {
|
||||
return ScriptPattern.isPayToPubKey(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this script is of the form DUP HASH160 <pubkey hash> EQUALVERIFY CHECKSIG, ie, payment to an
|
||||
* address like 1VayNert3x1KzbpzMGt2qdqrAThiRovi8. This form was originally intended for the case where you wish
|
||||
* to send somebody money with a written code because their node is offline, but over time has become the standard
|
||||
* way to make payments due to the short and recognizable base58 form addresses come in.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isSentToAddress() {
|
||||
return ScriptPattern.isPayToPubKeyHash(this);
|
||||
}
|
||||
@ -259,9 +249,9 @@ public class Script {
|
||||
*
|
||||
*/
|
||||
public byte[] getPubKeyHash() throws ScriptException {
|
||||
if (isSentToAddress())
|
||||
if (ScriptPattern.isPayToPubKeyHash(this))
|
||||
return chunks.get(2).data;
|
||||
else if (isPayToScriptHash())
|
||||
else if (ScriptPattern.isPayToScriptHash(this))
|
||||
return chunks.get(1).data;
|
||||
else
|
||||
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Script not in the standard scriptPubKey form");
|
||||
@ -300,7 +290,7 @@ public class Script {
|
||||
* @throws ScriptException
|
||||
*/
|
||||
public byte[] getCLTVPaymentChannelSenderPubKey() throws ScriptException {
|
||||
if (!isSentToCLTVPaymentChannel()) {
|
||||
if (!ScriptPattern.isSentToCltvPaymentChannel(this)) {
|
||||
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Script not a standard CHECKLOCKTIMVERIFY transaction: " + this);
|
||||
}
|
||||
return chunks.get(8).data;
|
||||
@ -312,14 +302,14 @@ public class Script {
|
||||
* @throws ScriptException
|
||||
*/
|
||||
public byte[] getCLTVPaymentChannelRecipientPubKey() throws ScriptException {
|
||||
if (!isSentToCLTVPaymentChannel()) {
|
||||
if (!ScriptPattern.isSentToCltvPaymentChannel(this)) {
|
||||
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Script not a standard CHECKLOCKTIMVERIFY transaction: " + this);
|
||||
}
|
||||
return chunks.get(1).data;
|
||||
}
|
||||
|
||||
public BigInteger getCLTVPaymentChannelExpiry() {
|
||||
if (!isSentToCLTVPaymentChannel()) {
|
||||
if (!ScriptPattern.isSentToCltvPaymentChannel(this)) {
|
||||
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Script not a standard CHECKLOCKTIMEVERIFY transaction: " + this);
|
||||
}
|
||||
return castToBigInteger(chunks.get(4).data, 5, false);
|
||||
@ -350,11 +340,11 @@ public class Script {
|
||||
* showing addresses rather than pubkeys.
|
||||
*/
|
||||
public Address getToAddress(NetworkParameters params, boolean forcePayToPubKey) throws ScriptException {
|
||||
if (isSentToAddress())
|
||||
if (ScriptPattern.isPayToPubKeyHash(this))
|
||||
return new Address(params, getPubKeyHash());
|
||||
else if (isPayToScriptHash())
|
||||
else if (ScriptPattern.isPayToScriptHash(this))
|
||||
return Address.fromP2SHScript(params, this);
|
||||
else if (forcePayToPubKey && isSentToRawPubKey())
|
||||
else if (forcePayToPubKey && ScriptPattern.isPayToPubKey(this))
|
||||
return ECKey.fromPublicOnly(getPubKey()).toAddress(params);
|
||||
else
|
||||
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Cannot cast this script to a pay-to-address type");
|
||||
@ -435,12 +425,12 @@ public class Script {
|
||||
* It is expected that this program later on will be updated with proper signatures.
|
||||
*/
|
||||
public Script createEmptyInputScript(@Nullable ECKey key, @Nullable Script redeemScript) {
|
||||
if (isSentToAddress()) {
|
||||
if (ScriptPattern.isPayToPubKeyHash(this)) {
|
||||
checkArgument(key != null, "Key required to create pay-to-address input script");
|
||||
return ScriptBuilder.createInputScript(null, key);
|
||||
} else if (isSentToRawPubKey()) {
|
||||
} else if (ScriptPattern.isPayToPubKey(this)) {
|
||||
return ScriptBuilder.createInputScript(null);
|
||||
} else if (isPayToScriptHash()) {
|
||||
} else if (ScriptPattern.isPayToScriptHash(this)) {
|
||||
checkArgument(redeemScript != null, "Redeem script required to create P2SH input script");
|
||||
return ScriptBuilder.createP2SHMultiSigInputScript(null, redeemScript);
|
||||
} else {
|
||||
@ -454,12 +444,12 @@ public class Script {
|
||||
public Script getScriptSigWithSignature(Script scriptSig, byte[] sigBytes, int index) {
|
||||
int sigsPrefixCount = 0;
|
||||
int sigsSuffixCount = 0;
|
||||
if (isPayToScriptHash()) {
|
||||
if (ScriptPattern.isPayToScriptHash(this)) {
|
||||
sigsPrefixCount = 1; // OP_0 <sig>* <redeemScript>
|
||||
sigsSuffixCount = 1;
|
||||
} else if (isSentToMultiSig()) {
|
||||
} else if (ScriptPattern.isSentToMultisig(this)) {
|
||||
sigsPrefixCount = 1; // OP_0 <sig>*
|
||||
} else if (isSentToAddress()) {
|
||||
} else if (ScriptPattern.isPayToPubKeyHash(this)) {
|
||||
sigsSuffixCount = 1; // <sig> <pubkey>
|
||||
}
|
||||
return ScriptBuilder.updateScriptWithSignature(scriptSig, sigBytes, index, sigsPrefixCount, sigsSuffixCount);
|
||||
@ -511,7 +501,7 @@ public class Script {
|
||||
* @throws ScriptException if the script type is not understood or is pay to address or is P2SH (run this method on the "Redeem script" instead).
|
||||
*/
|
||||
public List<ECKey> getPubKeys() {
|
||||
if (!isSentToMultiSig())
|
||||
if (!ScriptPattern.isSentToMultisig(this))
|
||||
throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Only usable for multisig scripts.");
|
||||
|
||||
ArrayList<ECKey> result = Lists.newArrayList();
|
||||
@ -620,14 +610,14 @@ public class Script {
|
||||
* Returns number of signatures required to satisfy this script.
|
||||
*/
|
||||
public int getNumberOfSignaturesRequiredToSpend() {
|
||||
if (isSentToMultiSig()) {
|
||||
if (ScriptPattern.isSentToMultisig(this)) {
|
||||
// for N of M CHECKMULTISIG script we will need N signatures to spend
|
||||
ScriptChunk nChunk = chunks.get(0);
|
||||
return Script.decodeFromOpN(nChunk.opcode);
|
||||
} else if (isSentToAddress() || isSentToRawPubKey()) {
|
||||
} else if (ScriptPattern.isPayToPubKeyHash(this) || ScriptPattern.isPayToPubKey(this)) {
|
||||
// pay-to-address and pay-to-pubkey require single sig
|
||||
return 1;
|
||||
} else if (isPayToScriptHash()) {
|
||||
} else if (ScriptPattern.isPayToScriptHash(this)) {
|
||||
throw new IllegalStateException("For P2SH number of signatures depends on redeem script");
|
||||
} else {
|
||||
throw new IllegalStateException("Unsupported script type");
|
||||
@ -639,17 +629,17 @@ public class Script {
|
||||
* be required for certain types of script to estimate target size.
|
||||
*/
|
||||
public int getNumberOfBytesRequiredToSpend(@Nullable ECKey pubKey, @Nullable Script redeemScript) {
|
||||
if (isPayToScriptHash()) {
|
||||
if (ScriptPattern.isPayToScriptHash(this)) {
|
||||
// scriptSig: <sig> [sig] [sig...] <redeemscript>
|
||||
checkArgument(redeemScript != null, "P2SH script requires redeemScript to be spent");
|
||||
return redeemScript.getNumberOfSignaturesRequiredToSpend() * SIG_SIZE + redeemScript.getProgram().length;
|
||||
} else if (isSentToMultiSig()) {
|
||||
} else if (ScriptPattern.isSentToMultisig(this)) {
|
||||
// scriptSig: OP_0 <sig> [sig] [sig...]
|
||||
return getNumberOfSignaturesRequiredToSpend() * SIG_SIZE + 1;
|
||||
} else if (isSentToRawPubKey()) {
|
||||
} else if (ScriptPattern.isPayToPubKey(this)) {
|
||||
// scriptSig: <sig>
|
||||
return SIG_SIZE;
|
||||
} else if (isSentToAddress()) {
|
||||
} else if (ScriptPattern.isPayToPubKeyHash(this)) {
|
||||
// scriptSig: <sig> <pubkey>
|
||||
int uncompressedPubKeySize = 65;
|
||||
return SIG_SIZE + (pubKey != null ? pubKey.getPubKey().length : uncompressedPubKeySize);
|
||||
@ -658,30 +648,17 @@ public class Script {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <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
|
||||
* spending input to provide a program matching that hash. This rule is "soft enforced" by the network as it does
|
||||
* not exist in Bitcoin Core. It means blocks containing P2SH transactions that don't match
|
||||
* correctly are considered valid, but won't be mined upon, so they'll be rapidly re-orgd out of the chain. This
|
||||
* logic is defined by <a href="https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki">BIP 16</a>.</p>
|
||||
*
|
||||
* <p>bitcoinj does not support creation of P2SH transactions today. The goal of P2SH is to allow short addresses
|
||||
* even for complex scripts (eg, multi-sig outputs) so they are convenient to work with in things like QRcodes or
|
||||
* with copy/paste, and also to minimize the size of the unspent output set (which improves performance of the
|
||||
* Bitcoin system).</p>
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isPayToScriptHash() {
|
||||
return ScriptPattern.isPayToScriptHash(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this script matches the format used for multisig outputs: [n] [keys...] [m] CHECKMULTISIG
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isSentToMultiSig() {
|
||||
return ScriptPattern.isSentToMultisig(this);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isSentToCLTVPaymentChannel() {
|
||||
return ScriptPattern.isSentToCltvPaymentChannel(this);
|
||||
}
|
||||
@ -795,6 +772,7 @@ public class Script {
|
||||
return Utils.decodeMPI(Utils.reverseBytes(chunk), false);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isOpReturn() {
|
||||
return ScriptPattern.isOpReturn(this);
|
||||
}
|
||||
@ -1643,7 +1621,7 @@ public class Script {
|
||||
// overall scalability and performance.
|
||||
|
||||
// TODO: Check if we can take out enforceP2SH if there's a checkpoint at the enforcement block.
|
||||
if (verifyFlags.contains(VerifyFlag.P2SH) && scriptPubKey.isPayToScriptHash()) {
|
||||
if (verifyFlags.contains(VerifyFlag.P2SH) && ScriptPattern.isPayToScriptHash(scriptPubKey)) {
|
||||
for (ScriptChunk chunk : chunks)
|
||||
if (chunk.isOpCode() && chunk.opcode > OP_16)
|
||||
throw new ScriptException(ScriptError.SCRIPT_ERR_SIG_PUSHONLY, "Attempted to spend a P2SH scriptPubKey with a script that contained script ops");
|
||||
@ -1674,11 +1652,11 @@ public class Script {
|
||||
*/
|
||||
public ScriptType getScriptType() {
|
||||
ScriptType type = ScriptType.NO_TYPE;
|
||||
if (isSentToAddress()) {
|
||||
if (ScriptPattern.isPayToPubKeyHash(this)) {
|
||||
type = ScriptType.P2PKH;
|
||||
} else if (isSentToRawPubKey()) {
|
||||
} else if (ScriptPattern.isPayToPubKey(this)) {
|
||||
type = ScriptType.PUB_KEY;
|
||||
} else if (isPayToScriptHash()) {
|
||||
} else if (ScriptPattern.isPayToScriptHash(this)) {
|
||||
type = ScriptType.P2SH;
|
||||
}
|
||||
return type;
|
||||
|
@ -28,6 +28,12 @@ import static org.bitcoinj.script.ScriptOpCodes.*;
|
||||
* This is a Script pattern matcher with some typical script patterns
|
||||
*/
|
||||
public class ScriptPattern {
|
||||
/**
|
||||
* Returns true if this script is of the form DUP HASH160 <pubkey hash> EQUALVERIFY CHECKSIG, ie, payment to an
|
||||
* address like 1VayNert3x1KzbpzMGt2qdqrAThiRovi8. This form was originally intended for the case where you wish
|
||||
* to send somebody money with a written code because their node is offline, but over time has become the standard
|
||||
* way to make payments due to the short and recognizable base58 form addresses come in.
|
||||
*/
|
||||
public static boolean isPayToPubKeyHash(Script script) {
|
||||
List<ScriptChunk> chunks = script.chunks;
|
||||
return chunks.size() == 5 &&
|
||||
@ -39,6 +45,11 @@ public class ScriptPattern {
|
||||
chunks.get(4).equalsOpCode(OP_CHECKSIG);
|
||||
}
|
||||
|
||||
/**
|
||||
* <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
|
||||
* spending input to provide a program matching that hash.
|
||||
*/
|
||||
public static boolean isPayToScriptHash(Script script) {
|
||||
List<ScriptChunk> chunks = script.chunks;
|
||||
// We check for the effective serialized form because BIP16 defines a P2SH output using an exact byte
|
||||
@ -54,6 +65,12 @@ public class ScriptPattern {
|
||||
chunks.get(2).equalsOpCode(OP_EQUAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* of operation being susceptible to man-in-the-middle attacks. It is still used in coinbase outputs and can be
|
||||
* useful more exotic types of transaction, but today most payments are to addresses.
|
||||
*/
|
||||
public static boolean isPayToPubKey(Script script) {
|
||||
List<ScriptChunk> chunks = script.chunks;
|
||||
return chunks.size() == 2 &&
|
||||
@ -63,6 +80,9 @@ public class ScriptPattern {
|
||||
chunks.get(0).data.length > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this script matches the format used for multisig outputs: [n] [keys...] [m] CHECKMULTISIG
|
||||
*/
|
||||
public static boolean isSentToMultisig(Script script) {
|
||||
List<ScriptChunk> chunks = script.chunks;
|
||||
if (chunks.size() < 4) return false;
|
||||
|
@ -21,6 +21,7 @@ import org.bitcoinj.crypto.ChildNumber;
|
||||
import org.bitcoinj.crypto.TransactionSignature;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptException;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
import org.bitcoinj.wallet.KeyBag;
|
||||
import org.bitcoinj.wallet.RedeemData;
|
||||
import org.slf4j.Logger;
|
||||
@ -58,7 +59,7 @@ public abstract class CustomTransactionSigner extends StatelessTransactionSigner
|
||||
continue;
|
||||
}
|
||||
Script scriptPubKey = txOut.getScriptPubKey();
|
||||
if (!scriptPubKey.isPayToScriptHash()) {
|
||||
if (!ScriptPattern.isPayToScriptHash(scriptPubKey)) {
|
||||
log.warn("CustomTransactionSigner works only with P2SH transactions");
|
||||
return false;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import org.bitcoinj.core.TransactionInput;
|
||||
import org.bitcoinj.crypto.TransactionSignature;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptChunk;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
import org.bitcoinj.wallet.KeyBag;
|
||||
import org.bitcoinj.wallet.Wallet;
|
||||
import org.slf4j.Logger;
|
||||
@ -66,8 +67,8 @@ public class MissingSigResolutionSigner extends StatelessTransactionSigner {
|
||||
|
||||
Script scriptPubKey = txIn.getConnectedOutput().getScriptPubKey();
|
||||
Script inputScript = txIn.getScriptSig();
|
||||
if (scriptPubKey.isPayToScriptHash() || scriptPubKey.isSentToMultiSig()) {
|
||||
int sigSuffixCount = scriptPubKey.isPayToScriptHash() ? 1 : 0;
|
||||
if (ScriptPattern.isPayToScriptHash(scriptPubKey) || ScriptPattern.isSentToMultisig(scriptPubKey)) {
|
||||
int sigSuffixCount = ScriptPattern.isPayToScriptHash(scriptPubKey) ? 1 : 0;
|
||||
// all chunks except the first one (OP_0) and the last (redeem script) are signatures
|
||||
for (int j = 1; j < inputScript.getChunks().size() - sigSuffixCount; j++) {
|
||||
ScriptChunk scriptChunk = inputScript.getChunks().get(j);
|
||||
|
@ -236,7 +236,7 @@ public class KeyChainGroup implements KeyBag {
|
||||
DeterministicKeyChain chain = getActiveKeyChain();
|
||||
if (chain.isMarried()) {
|
||||
Script outputScript = chain.freshOutputScript(purpose);
|
||||
checkState(outputScript.isPayToScriptHash()); // Only handle P2SH for now
|
||||
checkState(ScriptPattern.isPayToScriptHash(outputScript)); // Only handle P2SH for now
|
||||
Address freshAddress = Address.fromP2SHScript(params, outputScript);
|
||||
maybeLookaheadScripts();
|
||||
currentAddresses.put(purpose, freshAddress);
|
||||
|
@ -19,6 +19,7 @@ package org.bitcoinj.wallet;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptException;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.slf4j.Logger;
|
||||
@ -61,9 +62,9 @@ public class KeyTimeCoinSelector implements CoinSelector {
|
||||
// We ignore any other kind of exotic output on the assumption we can't spend it ourselves.
|
||||
final Script scriptPubKey = output.getScriptPubKey();
|
||||
ECKey controllingKey;
|
||||
if (scriptPubKey.isSentToRawPubKey()) {
|
||||
if (ScriptPattern.isPayToPubKey(scriptPubKey)) {
|
||||
controllingKey = wallet.findKeyFromPubKey(scriptPubKey.getPubKey());
|
||||
} else if (scriptPubKey.isSentToAddress()) {
|
||||
} else if (ScriptPattern.isPayToPubKeyHash(scriptPubKey)) {
|
||||
controllingKey = wallet.findKeyFromPubHash(scriptPubKey.getPubKeyHash());
|
||||
} else {
|
||||
log.info("Skipping tx output {} because it's not of simple form.", output);
|
||||
|
@ -18,6 +18,7 @@ package org.bitcoinj.wallet;
|
||||
|
||||
import org.bitcoinj.core.ECKey;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -53,7 +54,7 @@ public class RedeemData {
|
||||
* to spend such inputs and provided program should be a proper CHECKSIG program.
|
||||
*/
|
||||
public static RedeemData of(ECKey key, Script program) {
|
||||
checkArgument(program.isSentToAddress() || program.isSentToRawPubKey());
|
||||
checkArgument(ScriptPattern.isPayToPubKeyHash(program) || ScriptPattern.isPayToPubKey(program));
|
||||
return key != null ? new RedeemData(Collections.singletonList(key), program) : null;
|
||||
}
|
||||
|
||||
|
@ -974,7 +974,7 @@ public class Wallet extends BaseTaggableObject
|
||||
try {
|
||||
List<Address> addresses = new LinkedList<>();
|
||||
for (Script script : watchedScripts)
|
||||
if (script.isSentToAddress())
|
||||
if (ScriptPattern.isPayToPubKeyHash(script))
|
||||
addresses.add(script.getToAddress(params));
|
||||
return addresses;
|
||||
} finally {
|
||||
@ -1078,13 +1078,13 @@ public class Wallet extends BaseTaggableObject
|
||||
for (TransactionOutput o : tx.getOutputs()) {
|
||||
try {
|
||||
Script script = o.getScriptPubKey();
|
||||
if (script.isSentToRawPubKey()) {
|
||||
if (ScriptPattern.isPayToPubKey(script)) {
|
||||
byte[] pubkey = script.getPubKey();
|
||||
keyChainGroup.markPubKeyAsUsed(pubkey);
|
||||
} else if (script.isSentToAddress()) {
|
||||
} else if (ScriptPattern.isPayToPubKeyHash(script)) {
|
||||
byte[] pubkeyHash = script.getPubKeyHash();
|
||||
keyChainGroup.markPubKeyHashAsUsed(pubkeyHash);
|
||||
} else if (script.isPayToScriptHash()) {
|
||||
} else if (ScriptPattern.isPayToScriptHash(script)) {
|
||||
Address a = Address.fromP2SHScript(tx.getParams(), script);
|
||||
keyChainGroup.markP2SHAddressAsUsed(a);
|
||||
}
|
||||
@ -3986,7 +3986,7 @@ public class Wallet extends BaseTaggableObject
|
||||
for (TransactionOutput output : req.tx.getOutputs()) {
|
||||
if (output.isDust())
|
||||
throw new DustySendRequested();
|
||||
if (output.getScriptPubKey().isOpReturn())
|
||||
if (ScriptPattern.isOpReturn(output.getScriptPubKey()))
|
||||
++opReturnCount;
|
||||
}
|
||||
if (opReturnCount > 1) // Only 1 OP_RETURN per transaction allowed.
|
||||
@ -4187,23 +4187,23 @@ public class Wallet extends BaseTaggableObject
|
||||
* false if the form of the script is not known or if the script is OP_RETURN.
|
||||
*/
|
||||
public boolean canSignFor(Script script) {
|
||||
if (script.isSentToRawPubKey()) {
|
||||
if (ScriptPattern.isPayToPubKey(script)) {
|
||||
byte[] pubkey = script.getPubKey();
|
||||
ECKey key = findKeyFromPubKey(pubkey);
|
||||
return key != null && (key.isEncrypted() || key.hasPrivKey());
|
||||
} if (script.isPayToScriptHash()) {
|
||||
} if (ScriptPattern.isPayToScriptHash(script)) {
|
||||
RedeemData data = findRedeemDataFromScriptHash(script.getPubKeyHash());
|
||||
return data != null && canSignFor(data.redeemScript);
|
||||
} else if (script.isSentToAddress()) {
|
||||
} else if (ScriptPattern.isPayToPubKeyHash(script)) {
|
||||
ECKey key = findKeyFromPubHash(script.getPubKeyHash());
|
||||
return key != null && (key.isEncrypted() || key.hasPrivKey());
|
||||
} else if (script.isSentToMultiSig()) {
|
||||
} else if (ScriptPattern.isSentToMultisig(script)) {
|
||||
for (ECKey pubkey : script.getPubKeys()) {
|
||||
ECKey key = findKeyFromPubKey(pubkey.getPubKey());
|
||||
if (key != null && (key.isEncrypted() || key.hasPrivKey()))
|
||||
return true;
|
||||
}
|
||||
} else if (script.isSentToCLTVPaymentChannel()) {
|
||||
} else if (ScriptPattern.isSentToCltvPaymentChannel(script)) {
|
||||
// Any script for which we are the recipient or sender counts.
|
||||
byte[] sender = script.getCLTVPaymentChannelSenderPubKey();
|
||||
ECKey senderKey = findKeyFromPubKey(sender);
|
||||
@ -4724,7 +4724,7 @@ public class Wallet extends BaseTaggableObject
|
||||
// Returns true if the output is one that won't be selected by a data element matching in the scriptSig.
|
||||
private boolean isTxOutputBloomFilterable(TransactionOutput out) {
|
||||
Script script = out.getScriptPubKey();
|
||||
boolean isScriptTypeSupported = script.isSentToRawPubKey() || script.isPayToScriptHash();
|
||||
boolean isScriptTypeSupported = ScriptPattern.isPayToPubKey(script) || ScriptPattern.isPayToScriptHash(script);
|
||||
return (isScriptTypeSupported && myUnspents.contains(out)) || watchedScripts.contains(script);
|
||||
}
|
||||
|
||||
@ -4981,10 +4981,10 @@ public class Wallet extends BaseTaggableObject
|
||||
Script script = output.getScriptPubKey();
|
||||
ECKey key = null;
|
||||
Script redeemScript = null;
|
||||
if (script.isSentToAddress()) {
|
||||
if (ScriptPattern.isPayToPubKeyHash(script)) {
|
||||
key = findKeyFromPubHash(script.getPubKeyHash());
|
||||
checkNotNull(key, "Coin selection includes unspendable outputs");
|
||||
} else if (script.isPayToScriptHash()) {
|
||||
} else if (ScriptPattern.isPayToScriptHash(script)) {
|
||||
redeemScript = findRedeemDataFromScriptHash(script.getPubKeyHash()).redeemScript;
|
||||
checkNotNull(redeemScript, "Coin selection includes unspendable outputs");
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import org.bitcoinj.crypto.TransactionSignature;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptBuilder;
|
||||
import org.bitcoinj.script.ScriptException;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
@ -1818,7 +1819,7 @@ public class FullBlockTestGenerator {
|
||||
input.setScriptSig(new ScriptBuilder().op(OP_1).build());
|
||||
} else {
|
||||
// Sign input
|
||||
checkState(prevOut.scriptPubKey.isSentToRawPubKey());
|
||||
checkState(ScriptPattern.isPayToPubKey(prevOut.scriptPubKey));
|
||||
Sha256Hash hash = t.hashForSignature(0, prevOut.scriptPubKey, SigHash.ALL, false);
|
||||
input.setScriptSig(ScriptBuilder.createInputScript(
|
||||
new TransactionSignature(coinbaseOutKey.sign(hash), SigHash.ALL, false))
|
||||
|
@ -18,6 +18,7 @@ package org.bitcoinj.protocols.channels;
|
||||
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.protocols.channels.PaymentChannelClient.VersionSelector;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
import org.bitcoinj.testing.TestWithWallet;
|
||||
import org.bitcoinj.utils.Threading;
|
||||
import org.bitcoinj.wallet.Wallet;
|
||||
@ -540,9 +541,9 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
newClientStates.deserializeWalletExtension(wallet, clientStoredChannels.serializeWalletExtension());
|
||||
broadcastTxPause.release();
|
||||
if (isMultiSigContract()) {
|
||||
assertTrue(broadcasts.take().getOutput(0).getScriptPubKey().isSentToMultiSig());
|
||||
assertTrue(ScriptPattern.isSentToMultisig(broadcasts.take().getOutput(0).getScriptPubKey()));
|
||||
} else {
|
||||
assertTrue(broadcasts.take().getOutput(0).getScriptPubKey().isPayToScriptHash());
|
||||
assertTrue(ScriptPattern.isPayToScriptHash(broadcasts.take().getOutput(0).getScriptPubKey()));
|
||||
}
|
||||
broadcastTxPause.release();
|
||||
assertEquals(TransactionConfidence.Source.SELF, broadcasts.take().getConfidence().getSource());
|
||||
|
@ -19,6 +19,7 @@ package org.bitcoinj.protocols.channels;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptBuilder;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
import org.bitcoinj.testing.TestWithWallet;
|
||||
import org.bitcoinj.wallet.SendRequest;
|
||||
import org.bitcoinj.wallet.Wallet;
|
||||
@ -255,12 +256,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(2, multisigContract.getOutputs().size()); // One multi-sig, one change.
|
||||
Script script = multisigContract.getOutput(0).getScriptPubKey();
|
||||
if (versionSelector == PaymentChannelClient.VersionSelector.VERSION_1) {
|
||||
assertTrue(script.isSentToMultiSig());
|
||||
assertTrue(ScriptPattern.isSentToMultisig(script));
|
||||
} else {
|
||||
assertTrue(script.isPayToScriptHash());
|
||||
assertTrue(ScriptPattern.isPayToScriptHash(script));
|
||||
}
|
||||
script = multisigContract.getOutput(1).getScriptPubKey();
|
||||
assertTrue(script.isSentToAddress());
|
||||
assertTrue(ScriptPattern.isPayToPubKeyHash(script));
|
||||
assertTrue(wallet.getPendingTransactions().contains(multisigContract));
|
||||
|
||||
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
||||
@ -380,12 +381,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(2, multisigContract.getOutputs().size()); // One multi-sig, one change.
|
||||
Script script = multisigContract.getOutput(0).getScriptPubKey();
|
||||
if (versionSelector == PaymentChannelClient.VersionSelector.VERSION_1) {
|
||||
assertTrue(script.isSentToMultiSig());
|
||||
assertTrue(ScriptPattern.isSentToMultisig(script));
|
||||
} else {
|
||||
assertTrue(script.isPayToScriptHash());
|
||||
assertTrue(ScriptPattern.isPayToScriptHash(script));
|
||||
}
|
||||
script = multisigContract.getOutput(1).getScriptPubKey();
|
||||
assertTrue(script.isSentToAddress());
|
||||
assertTrue(ScriptPattern.isPayToPubKeyHash(script));
|
||||
assertTrue(wallet.getPendingTransactions().contains(multisigContract));
|
||||
|
||||
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
||||
@ -856,12 +857,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(2, multisigContract.getOutputs().size()); // One multi-sig, one change.
|
||||
Script script = multisigContract.getOutput(0).getScriptPubKey();
|
||||
if (versionSelector == PaymentChannelClient.VersionSelector.VERSION_1) {
|
||||
assertTrue(script.isSentToMultiSig());
|
||||
assertTrue(ScriptPattern.isSentToMultisig(script));
|
||||
} else {
|
||||
assertTrue(script.isPayToScriptHash());
|
||||
assertTrue(ScriptPattern.isPayToScriptHash(script));
|
||||
}
|
||||
script = multisigContract.getOutput(1).getScriptPubKey();
|
||||
assertTrue(script.isSentToAddress());
|
||||
assertTrue(ScriptPattern.isPayToPubKeyHash(script));
|
||||
assertTrue(wallet.getPendingTransactions().contains(multisigContract));
|
||||
|
||||
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
||||
@ -950,12 +951,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(2, multisigContract.getOutputs().size()); // One multi-sig, one change.
|
||||
Script script = multisigContract.getOutput(0).getScriptPubKey();
|
||||
if (versionSelector == PaymentChannelClient.VersionSelector.VERSION_1) {
|
||||
assertTrue(script.isSentToMultiSig());
|
||||
assertTrue(ScriptPattern.isSentToMultisig(script));
|
||||
} else {
|
||||
assertTrue(script.isPayToScriptHash());
|
||||
assertTrue(ScriptPattern.isPayToScriptHash(script));
|
||||
}
|
||||
script = multisigContract.getOutput(1).getScriptPubKey();
|
||||
assertTrue(script.isSentToAddress());
|
||||
assertTrue(ScriptPattern.isPayToPubKeyHash(script));
|
||||
assertTrue(wallet.getPendingTransactions().contains(multisigContract));
|
||||
|
||||
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
||||
|
@ -87,13 +87,13 @@ public class ScriptTest {
|
||||
@Test
|
||||
public void testMultiSig() throws Exception {
|
||||
List<ECKey> keys = Lists.newArrayList(new ECKey(), new ECKey(), new ECKey());
|
||||
assertTrue(ScriptBuilder.createMultiSigOutputScript(2, keys).isSentToMultiSig());
|
||||
assertTrue(ScriptPattern.isSentToMultisig(ScriptBuilder.createMultiSigOutputScript(2, keys)));
|
||||
Script script = ScriptBuilder.createMultiSigOutputScript(3, keys);
|
||||
assertTrue(script.isSentToMultiSig());
|
||||
assertTrue(ScriptPattern.isSentToMultisig(script));
|
||||
List<ECKey> pubkeys = new ArrayList<>(3);
|
||||
for (ECKey key : keys) pubkeys.add(ECKey.fromPublicOnly(key.getPubKeyPoint()));
|
||||
assertEquals(script.getPubKeys(), pubkeys);
|
||||
assertFalse(ScriptBuilder.createOutputScript(new ECKey()).isSentToMultiSig());
|
||||
assertFalse(ScriptPattern.isSentToMultisig(ScriptBuilder.createOutputScript(new ECKey())));
|
||||
try {
|
||||
// Fail if we ask for more signatures than keys.
|
||||
Script.createMultiSigOutputScript(4, keys);
|
||||
@ -113,14 +113,14 @@ public class ScriptTest {
|
||||
@Test
|
||||
public void testP2SHOutputScript() throws Exception {
|
||||
Address p2shAddress = Address.fromBase58(MainNetParams.get(), "35b9vsyH1KoFT5a5KtrKusaCcPLkiSo1tU");
|
||||
assertTrue(ScriptBuilder.createOutputScript(p2shAddress).isPayToScriptHash());
|
||||
assertTrue(ScriptPattern.isPayToScriptHash(ScriptBuilder.createOutputScript(p2shAddress)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIp() throws Exception {
|
||||
byte[] bytes = HEX.decode("41043e96222332ea7848323c08116dddafbfa917b8e37f0bdf63841628267148588a09a43540942d58d49717ad3fabfe14978cf4f0a8b84d2435dad16e9aa4d7f935ac");
|
||||
Script s = new Script(bytes);
|
||||
assertTrue(s.isSentToRawPubKey());
|
||||
assertTrue(ScriptPattern.isPayToPubKey(s));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -432,7 +432,7 @@ public class ScriptTest {
|
||||
@Test
|
||||
public void testCLTVPaymentChannelOutput() {
|
||||
Script script = ScriptBuilder.createCLTVPaymentChannelOutput(BigInteger.valueOf(20), new ECKey(), new ECKey());
|
||||
assertTrue("script is locktime-verify", script.isSentToCLTVPaymentChannel());
|
||||
assertTrue("script is locktime-verify", ScriptPattern.isSentToCltvPaymentChannel(script));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -27,6 +27,7 @@ import org.bitcoinj.protocols.payments.PaymentProtocolException;
|
||||
import org.bitcoinj.protocols.payments.PaymentSession;
|
||||
import org.bitcoinj.script.ScriptBuilder;
|
||||
import org.bitcoinj.script.ScriptException;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
import org.bitcoinj.store.*;
|
||||
import org.bitcoinj.uri.BitcoinURI;
|
||||
import org.bitcoinj.uri.BitcoinURIParseException;
|
||||
@ -831,7 +832,7 @@ public class WalletTool {
|
||||
}
|
||||
TransactionOutput lockTimeVerifyOutput = null;
|
||||
for (TransactionOutput out : lockTimeVerify.getOutputs()) {
|
||||
if (out.getScriptPubKey().isSentToCLTVPaymentChannel()) {
|
||||
if (ScriptPattern.isSentToCltvPaymentChannel(out.getScriptPubKey())) {
|
||||
lockTimeVerifyOutput = out;
|
||||
}
|
||||
}
|
||||
@ -935,7 +936,7 @@ public class WalletTool {
|
||||
}
|
||||
TransactionOutput lockTimeVerifyOutput = null;
|
||||
for (TransactionOutput out : lockTimeVerify.getOutputs()) {
|
||||
if (out.getScriptPubKey().isSentToCLTVPaymentChannel()) {
|
||||
if (ScriptPattern.isSentToCltvPaymentChannel(out.getScriptPubKey())) {
|
||||
lockTimeVerifyOutput = out;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user