mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-01-30 23:02:15 +00:00
Add a TransactionInput.verify() method that checks signatures and use it from the basicSpending test to ensure we generate valid signatures/scripts.
This commit is contained in:
parent
2f0d4cdbd8
commit
671a5aec18
@ -875,7 +875,8 @@ public class Script {
|
||||
return Utils.decodeMPI(Utils.reverseBytes(chunk), false);
|
||||
}
|
||||
|
||||
private static void executeScript(Transaction txContainingThis, long index, Script script, LinkedList<byte[]> stack) throws ScriptException {
|
||||
private static void executeScript(Transaction txContainingThis, long index,
|
||||
Script script, LinkedList<byte[]> stack) throws ScriptException {
|
||||
int opCount = 0;
|
||||
int lastCodeSepLocation = 0;
|
||||
|
||||
@ -1479,19 +1480,24 @@ public class Script {
|
||||
|
||||
/**
|
||||
* Verifies that this script (interpreted as a scriptSig) correctly spends the given scriptPubKey.
|
||||
* @param txContainingThis The transaction in which this input scriptSig resides.
|
||||
* @param scriptSigIndex The index in txContainingThis of the scriptSig (note: NOT the index of the scriptPubKey).
|
||||
* @param scriptPubKey The connected scriptPubKey containing the conditions needed to claim the value.
|
||||
* @param enforceP2SH Whether "pay to script hash" rules should be enforced. If in doubt, set to true.
|
||||
* @throws VerificationException if this script does not correctly spend the scriptPubKey
|
||||
*/
|
||||
public void correctlySpends(Transaction txContainingThis, long index, Script scriptPubKey, boolean enforceP2SH) throws ScriptException {
|
||||
public void correctlySpends(Transaction txContainingThis, long scriptSigIndex, Script scriptPubKey,
|
||||
boolean enforceP2SH) throws ScriptException {
|
||||
if (program.length > 10000 || scriptPubKey.program.length > 10000)
|
||||
throw new ScriptException("Script larger than 10,000 bytes");
|
||||
|
||||
LinkedList<byte[]> stack = new LinkedList<byte[]>();
|
||||
LinkedList<byte[]> p2shStack = null;
|
||||
|
||||
executeScript(txContainingThis, index, this, stack);
|
||||
executeScript(txContainingThis, scriptSigIndex, this, stack);
|
||||
if (enforceP2SH)
|
||||
p2shStack = new LinkedList<byte[]>(stack);
|
||||
executeScript(txContainingThis, index, scriptPubKey, stack);
|
||||
executeScript(txContainingThis, scriptSigIndex, scriptPubKey, stack);
|
||||
|
||||
if (stack.size() == 0)
|
||||
throw new ScriptException("Stack empty at end of script execution.");
|
||||
@ -1520,7 +1526,7 @@ public class Script {
|
||||
byte[] scriptPubKeyBytes = p2shStack.pollLast();
|
||||
Script scriptPubKeyP2SH = new Script(params, scriptPubKeyBytes, 0, scriptPubKeyBytes.length);
|
||||
|
||||
executeScript(txContainingThis, index, scriptPubKeyP2SH, p2shStack);
|
||||
executeScript(txContainingThis, scriptSigIndex, scriptPubKeyP2SH, p2shStack);
|
||||
|
||||
if (p2shStack.size() == 0)
|
||||
throw new ScriptException("P2SH stack empty at end of script execution.");
|
||||
|
@ -340,4 +340,17 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
public boolean hasSequence() {
|
||||
return sequence != NO_SEQUENCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a connected transaction, runs the script against the connected pubkey and verifies they are correct.
|
||||
* @throws ScriptException if the script did not verify.
|
||||
*/
|
||||
public void verify() throws ScriptException {
|
||||
Preconditions.checkNotNull(getOutpoint().fromTx, "Not connected");
|
||||
long spendingIndex = getOutpoint().getIndex();
|
||||
Script pubKey = getOutpoint().fromTx.getOutputs().get((int) spendingIndex).getScriptPubKey();
|
||||
Script sig = getScriptSig();
|
||||
int myIndex = parentTransaction.getInputs().indexOf(this);
|
||||
sig.correctlySpends(parentTransaction, myIndex, pubKey, true);
|
||||
}
|
||||
}
|
||||
|
@ -89,8 +89,8 @@ public class WalletTest {
|
||||
assertEquals(destination, t2.getOutputs().get(0).getScriptPubKey().getToAddress());
|
||||
assertEquals(wallet.getChangeAddress(), t2.getOutputs().get(1).getScriptPubKey().getToAddress());
|
||||
assertEquals(toNanoCoins(0, 49), t2.getOutputs().get(1).getValue());
|
||||
|
||||
// We have NOT proven that the signature is correct!
|
||||
// Check the script runs and signatures verify.
|
||||
t2.getInputs().get(0).verify();
|
||||
|
||||
final LinkedList<Transaction> txns = Lists.newLinkedList();
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
|
Loading…
Reference in New Issue
Block a user