/// <summary> /// 验证该区块是否合法 /// </summary> /// <param name="completely">是否同时验证区块中的每一笔交易</param> /// <returns>返回该区块的合法性,返回true即为合法,否则,非法。</returns> public bool Verify(bool completely) { if (!Verify()) { return(false); } if (completely) { if (NextMiner != Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(Transactions).ToArray())) { return(false); } foreach (Transaction tx in Transactions) { if (!tx.Verify()) { return(false); } } Transaction tx_gen = Transactions.FirstOrDefault(p => p.Type == TransactionType.MinerTransaction); if (tx_gen?.Outputs.Sum(p => p.Value) != CalculateNetFee(Transactions)) { return(false); } } return(true); }
/// <summary> /// 验证该区块是否合法 /// </summary> /// <param name="completely">是否同时验证区块中的每一笔交易</param> /// <returns>返回该区块的合法性,返回true即为合法,否则,非法。</returns> public bool Verify(bool completely) { if (!Verify()) { return(false); } if (Transactions[0].Type != TransactionType.MinerTransaction || Transactions.Skip(1).Any(p => p.Type == TransactionType.MinerTransaction)) { return(false); } if (completely) { if (NextConsensus != Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(Transactions).ToArray())) { return(false); } foreach (Transaction tx in Transactions) { if (!tx.Verify(Transactions.Where(p => !p.Hash.Equals(tx.Hash)))) { return(false); } } Transaction tx_gen = Transactions.FirstOrDefault(p => p.Type == TransactionType.MinerTransaction); if (tx_gen?.Outputs.Sum(p => p.Value) != CalculateNetFee(Transactions)) { return(false); } } return(true); }
public bool Verify(bool completely) { if (Hash == Blockchain.GenesisBlock.Hash) { return(true); } if (Blockchain.Default.ContainsBlock(Hash)) { return(true); } if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.TransactionIndexes) || !Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes)) { return(false); } Block prev_header = Blockchain.Default.GetHeader(PrevBlock); if (prev_header == null) { return(false); } if (prev_header.Height + 1 != Height) { return(false); } if (prev_header.Timestamp >= Timestamp) { return(false); } if (!this.VerifySignature()) { return(false); } if (NextMiner != Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(Transactions).ToArray())) { return(false); } if (completely) { foreach (Transaction tx in Transactions) { if (!tx.Verify()) { return(false); } } Transaction[] transactions = Transactions.Where(p => p.Type != TransactionType.MinerTransaction).ToArray(); Fixed8 amount_in = transactions.SelectMany(p => p.References.Values.Where(o => o.AssetId == Blockchain.AntCoin.Hash)).Sum(p => p.Value); Fixed8 amount_out = transactions.SelectMany(p => p.Outputs.Where(o => o.AssetId == Blockchain.AntCoin.Hash)).Sum(p => p.Value); Fixed8 amount_sysfee = transactions.Sum(p => p.SystemFee); Fixed8 amount_netfee = amount_in - amount_out - amount_sysfee; MinerTransaction tx_gen = Transactions.OfType <MinerTransaction>().FirstOrDefault(); if (tx_gen?.Outputs.Sum(p => p.Value) != amount_netfee) { return(false); } } return(true); }
/// <summary> /// 验证该区块头是否合法 /// </summary> /// <param name="completely">是否同时验证区块中的每一笔交易</param> /// <returns>返回该区块头的合法性,返回true即为合法,否则,非法。</returns> public bool Verify(bool completely) { if (Hash == Blockchain.GenesisBlock.Hash) { return(true); } if (Blockchain.Default.ContainsBlock(Hash)) { return(true); } if (completely && IsHeader) { return(false); } if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.TransactionIndexes) || !Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes)) { return(false); } Block prev_header = Blockchain.Default.GetHeader(PrevBlock); if (prev_header == null) { return(false); } if (prev_header.Height + 1 != Height) { return(false); } if (prev_header.Timestamp >= Timestamp) { return(false); } if (!this.VerifySignature()) { return(false); } if (completely) { if (NextMiner != Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(Transactions).ToArray())) { return(false); } foreach (Transaction tx in Transactions) { if (!tx.Verify()) { return(false); } } Transaction tx_gen = Transactions.FirstOrDefault(p => p.Type == TransactionType.MinerTransaction); if (tx_gen?.Outputs.Sum(p => p.Value) != CalculateNetFee(Transactions)) { return(false); } } return(true); }
public bool Verify(bool completely) { if (Hash == Blockchain.GenesisBlock.Hash) { return(true); } if (Blockchain.Default.ContainsBlock(Hash)) { return(true); } if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.TransactionIndexes) || !Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes)) { return(false); } Block prev_header = Blockchain.Default.GetHeader(PrevBlock); if (prev_header == null) { return(false); } if (prev_header.Height + 1 != Height) { return(false); } if (prev_header.Timestamp >= Timestamp) { return(false); } if (!this.VerifySignature()) { return(false); } if (NextMiner != Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(Transactions).ToArray())) { return(false); } if (completely) { if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.Statistics)) { return(false); } foreach (Transaction tx in Transactions) { if (!tx.Verify()) { return(false); } } var antshares = Blockchain.Default.GetUnspentAntShares().GroupBy(p => p.ScriptHash, (k, g) => new { ScriptHash = k, Amount = g.Sum(p => p.Value) }).OrderBy(p => p.Amount).ThenBy(p => p.ScriptHash).ToArray(); Transaction[] transactions = Transactions.Where(p => p.Type != TransactionType.GenerationTransaction).ToArray(); Fixed8 amount_in = transactions.SelectMany(p => p.References.Values.Where(o => o.AssetId == Blockchain.AntCoin.Hash)).Sum(p => p.Value); Fixed8 amount_out = transactions.SelectMany(p => p.Outputs.Where(o => o.AssetId == Blockchain.AntCoin.Hash)).Sum(p => p.Value); Fixed8 amount_sysfee = transactions.Sum(p => p.SystemFee); Fixed8 amount_netfee = amount_in - amount_out - amount_sysfee; Fixed8 quantity = Blockchain.Default.GetQuantityIssued(Blockchain.AntCoin.Hash); Fixed8 gen = Fixed8.Zero; if (Height % Blockchain.MintingInterval == 0 && antshares.Length > 0) { gen = Fixed8.FromDecimal((Blockchain.AntCoin.Amount - (quantity - amount_sysfee)).ToDecimal() * Blockchain.GenerationFactor); } GenerationTransaction tx_gen = Transactions.OfType <GenerationTransaction>().First(); if (tx_gen.Outputs.Sum(p => p.Value) != amount_netfee + gen) { return(false); } if (antshares.Length > 0) { ulong n = Nonce % (ulong)antshares.Sum(p => p.Amount).value; ulong line = 0; int i = -1; do { line += (ulong)antshares[++i].Amount.value; } while (line <= n); if (tx_gen.Outputs.Where(p => p.ScriptHash == antshares[i].ScriptHash).Sum(p => p.Value) < gen) { return(false); } } } return(true); }