public static void ValidateBlock(Block block)
        {
            // first validate the Nonce matches the difficulty mask
            string mineHash = Sha256Hash.Hash(BitConverter.GetBytes(block.Nonce), block.PreviousBlockHash);

            if (!Regex.IsMatch(mineHash, block.DifficultyMask))
            {
                throw new Exception("Nonce does not match difficulty mask");
            }

            for (int i = 0; i < block.Transactions.Count; i++)
            {
                Transaction t = block.Transactions[i];
                TransactionValidatorService.ValidateTransaction(t);
            }
        }
        public static void ValidateTransaction(Transaction transaction)
        {
            bool isCoinbase = transaction.Inputs.Count == 0;

            decimal
                totalInput  = 0,
                totalOutput = 0;

            // verify the inputs are able to be spent with the public key the transaction is signed with
            for (int i = 0; i < transaction.Inputs.Count; i++)
            {
                TransactionInput txIn = transaction.Inputs[i];

                Transaction       lastTxInTrans  = TransactionFactory.TransactionFromTxInput(txIn);
                TransactionOutput lastTxInOutput = lastTxInTrans.Outputs.ElementAt((int)txIn.PreviousTransactionOutIndex);

                if (!transaction.VerifySignature(lastTxInOutput.To))
                {
                    throw new Exception("Transaction sign chain is invalid");
                }

                TransactionValidatorService.ValidateTransaction(lastTxInTrans);

                totalInput += lastTxInOutput.Amount;
            }

            if (isCoinbase)
            {
                if (transaction.Inputs.Count != 1 && transaction.Outputs.Count != 1)
                {
                    throw new Exception("Coinbase transaction must have one input and one output");
                }

                return;
            }

            for (int i = 0; i < transaction.Outputs.Count; i++)
            {
                TransactionOutput txOut = transaction.Outputs[i];
                totalOutput += txOut.Amount;
            }

            if (!isCoinbase && totalOutput > totalInput)
            {
                throw new Exception("Output must not exceed input");
            }
        }