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)); }
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); } }