var prevBlockHeader = prevBlockCursor.BlockHeader;
- // TODO: proof-of-work/proof-of-stake verification
uint nHeight = prevBlockCursor.nHeight + 1;
// Check timestamp against prev
return false; // rejected by checkpoint lock-in
}
- // TODO: Enforce rule that the coinbase starts with serialized block height
+ // Enforce rule that the coinbase starts with serialized block height
+ var expect = new CScript();
+ expect.AddNumber((int)nHeight);
+
+ byte[] expectBytes = expect;
+ byte[] scriptSig = block.vtx[0].vin[0].scriptSig;
+
+ if (!expectBytes.SequenceEqual(scriptSig.Take(expectBytes.Length)))
+ {
+ return false; // coinbase doesn't start with serialized height.
+ }
// Write block to file.
var itemTemplate = new CBlockStoreItem()
if (block.IsProofOfStake)
{
- // TODO: proof-of-stake validation
-
uint256 hashProofOfStake = 0, targetProofOfStake = 0;
if (!StakeModifier.CheckProofOfStake(block.vtx[1], block.header.nBits, out hashProofOfStake, out targetProofOfStake))
{
using System.Text;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
+using System.Numerics;
namespace Novacoin
{
}
/// <summary>
+ /// Add serialized number to instructions list.
+ /// </summary>
+ /// <param name="n">Number to add.</param>
+ public void AddNumber(int n)
+ {
+ if (n == -1 || (n >= 1 && n <= 16))
+ {
+ codeBytes.Add((byte)ScriptCode.EncodeOP_N(n, true));
+ }
+ else
+ {
+ BigInteger bn = n;
+ PushData(bn.ToByteArray());
+ }
+ }
+
+ /// <summary>
/// Adds specified operation to instruction list
/// </summary>
- /// <param name="opcode"></param>
+ /// <param name="opcode">Instruction to add.</param>
public void AddInstruction(instruction opcode)
{
Contract.Requires<ArgumentException>(opcode >= instruction.OP_0 && opcode <= instruction.OP_INVALIDOPCODE, "Invalid instruction.");