예제 #1
0
        private static Block CalculateHeader(BlockTemplate blockTemplate, uint nonce, uint extraNonce, Networks network)
        {
            var transactions    = new List <BaseTransaction>();
            var coinBaseInTrans = blockTemplate.CoinBaseTx.TransactionIn[0] as TransactionInCoinbase;

            coinBaseInTrans.CoinBaseScript = BitConverter.GetBytes(extraNonce);
            transactions.Add(blockTemplate.CoinBaseTx);
            transactions.AddRange(blockTemplate.Transactions);
            var block = new Block(blockTemplate.PreviousBlockHash, blockTemplate.Bits, nonce, blockTemplate.Version);

            block.Transactions = transactions;
            var serialized = block.GetHashHeader();

            if (TargetHelper.IsValid(serialized, blockTemplate.Target))
            {
                var txOut       = blockTemplate.CoinBaseTx.TransactionOut;
                var firstTxOut  = txOut.First();
                var adr         = GenerateAdr(network);
                var minerScript = Script.CreateP2PKHScript(adr.PublicKeyHash);
                firstTxOut.Script = minerScript;
                return(block);
            }

            var difference = DateTime.UtcNow.ToUnixTimeUInt32() - blockTemplate.CurrentTime;

            if (difference >= blockTemplate.Expires) // EXPIRATION.
            {
                return(null);
            }

            if (nonce == uint.MaxValue)
            {
                nonce = 0;
                extraNonce++;
            }

            Thread.Sleep(100);
            nonce++;
            return(CalculateHeader(blockTemplate, nonce, extraNonce, network));
        }
예제 #2
0
        public void Check(Block block)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }

            var merkleRoot           = block.BlockHeader.MerkleRoot; // Check MERKLE-ROOT.
            var calculatedMerkleRoot = block.GetMerkleRoot();

            if (!merkleRoot.SequenceEqual(calculatedMerkleRoot))
            {
                throw new ValidationException(ErrorCodes.InvalidMerkleRoot);
            }

            var blockChain   = _blockChainStore.GetBlockChain(); // Check PREVIOUS BLOCK.
            var currentBlock = blockChain.GetCurrentBlock();

            if (!currentBlock.GetHashHeader().SequenceEqual(block.BlockHeader.PreviousBlockHeader))
            {
                throw new ValidationException(ErrorCodes.InvalidPreviousHashHeader);
            }

            var hash         = currentBlock.GetHashHeader();
            var currentNBits = Constants.DEFAULT_NBITS; // TODO : CALCULATE THE DEFAULT NBITS : https://bitcoin.org/en/developer-guide#proof-of-work
            var target       = TargetHelper.GetTarget(currentNBits);

            if (!TargetHelper.IsValid(hash, target))
            {
                throw new ValidationException(ErrorCodes.NotEnoughDifficult);
            }

            foreach (var transaction in block.Transactions) // Check ALL TRANSACTIONS.
            {
                _transactionValidator.Check(transaction);
            }
        }