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:
parent
626ff2fa2c
commit
4018af8d51
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user