3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-14 11:15:51 +00:00

Implement a Transaction.verify() to mimic Satoshi CheckTransaction

This commit is contained in:
Matt Corallo 2012-07-11 02:37:51 +02:00 committed by Mike Hearn
parent 626ff2fa2c
commit 4018af8d51
3 changed files with 42 additions and 2 deletions

View File

@ -712,7 +712,9 @@ public class Block extends Message {
checkTransactions();
checkMerkleRoot();
checkSigOps();
}
for (Transaction transaction : transactions)
transaction.verify();
}
/**
* Verifies both the header and that the transactions hash to the merkle root.
@ -869,7 +871,7 @@ public class Block extends Message {
//
// Here we will do things a bit differently so a new address isn't needed every time. We'll put a simple
// counter in the scriptSig so every transaction has a different hash.
coinbase.addInput(new TransactionInput(params, coinbase, new byte[]{(byte) txCounter++}));
coinbase.addInput(new TransactionInput(params, coinbase, new byte[]{(byte) txCounter++, (byte) 1}));
coinbase.addOutput(new TransactionOutput(params, coinbase, Script.createOutputScript(pubKeyTo),
Utils.toNanoCoins(50, 0)));
transactions.add(coinbase);

View File

@ -24,6 +24,7 @@ import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import static com.google.bitcoin.core.Utils.COIN;
import static com.google.common.base.Preconditions.checkState;
// TODO: Refactor this after we stop supporting serialization compatibility to use subclasses and singletons.
@ -151,6 +152,11 @@ public class NetworkParameters implements Serializable {
public static final int TARGET_TIMESPAN = 14 * 24 * 60 * 60; // 2 weeks per difficulty cycle, on average.
public static final int TARGET_SPACING = 10 * 60; // 10 minutes per block.
public static final int INTERVAL = TARGET_TIMESPAN / TARGET_SPACING;
/**
* The maximum money to be generated
*/
public final BigInteger MAX_MONEY = new BigInteger("21000000", 10).multiply(COIN);
/** Sets up the given Networkparemets with testnet3 values. */
private static NetworkParameters createTestNet3(NetworkParameters n) {

View File

@ -882,4 +882,36 @@ public class Transaction extends ChildMessage implements Serializable {
sigOps += Script.getSigOpCount(output.getScriptBytes());
return sigOps;
}
/**
* Checks the transaction contents for sanity, in ways that can be done in a standalone manner.
* Does <b>not</b> perform all checks on a transaction such as whether the inputs are already spent.
*
* @throws VerificationException
*/
public void verify() throws VerificationException {
maybeParse();
if (inputs.size() == 0 || outputs.size() == 0)
throw new VerificationException("Transaction had no inputs or no outputs.");
if (this.getMessageSize() > Block.MAX_BLOCK_SIZE)
throw new VerificationException("Transaction larger than MAX_BLOCK_SIZE");
BigInteger valueOut = BigInteger.ZERO;
for (TransactionOutput output : outputs) {
if (output.getValue().compareTo(BigInteger.ZERO) < 0)
throw new VerificationException("Transaction output negative");
valueOut = valueOut.add(output.getValue());
}
if (valueOut.compareTo(params.MAX_MONEY) > 0)
throw new VerificationException("Total transaction output value greater than possible");
if (isCoinBase()) {
if (inputs.get(0).getScriptBytes().length < 2 || inputs.get(0).getScriptBytes().length > 100)
throw new VerificationException("Coinbase script size out of range");
} else {
for (TransactionInput input : inputs)
if (input.isCoinBase())
throw new VerificationException("Coinbase input as input in non-coinbase transaction");
}
}
}