Esempio n. 1
0
 /// <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);
 }
Esempio n. 2
0
 /// <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);
 }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        /// <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);
        }
Esempio n. 5
0
        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);
        }