Exemplo n.º 1
0
 /// <summary>
 /// 验证交易
 /// </summary>
 /// <returns>返回验证后的结果</returns>
 public override bool Verify(IEnumerable <Transaction> mempool)
 {
     if (!base.Verify(mempool))
     {
         return(false);
     }
     TransactionResult[] results = GetTransactionResults()?.Where(p => p.Amount < Fixed8.Zero).ToArray();
     if (results == null)
     {
         return(false);
     }
     foreach (TransactionResult r in results)
     {
         RegisterTransaction tx = Blockchain.Default.GetTransaction(r.AssetId) as RegisterTransaction;
         if (tx == null)
         {
             return(false);
         }
         if (tx.Amount < Fixed8.Zero)
         {
             continue;
         }
         if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.Statistics))
         {
             return(false);
         }
         Fixed8 quantity_issued = Blockchain.Default.GetQuantityIssued(r.AssetId);
         quantity_issued += mempool.OfType <IssueTransaction>().SelectMany(p => p.Outputs).Where(p => p.AssetId == r.AssetId).Sum(p => p.Value);
         if (tx.Amount - quantity_issued < -r.Amount)
         {
             return(false);
         }
     }
     return(true);
 }
Exemplo n.º 2
0
 /// <summary>
 /// 验证交易
 /// </summary>
 /// <returns>返回验证后的结果</returns>
 public override bool Verify()
 {
     if (!base.Verify())
     {
         return(false);
     }
     TransactionResult[] results = GetTransactionResults()?.Where(p => p.Amount < Fixed8.Zero).ToArray();
     if (results == null)
     {
         return(false);
     }
     foreach (TransactionResult r in results)
     {
         RegisterTransaction tx = Blockchain.Default.GetTransaction(r.AssetId) as RegisterTransaction;
         if (tx == null)
         {
             return(false);
         }
         if (tx.Amount < Fixed8.Zero)
         {
             continue;
         }
         if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.Statistics))
         {
             return(false);
         }
         Fixed8 quantity_issued = Blockchain.Default.GetQuantityIssued(r.AssetId); //TODO: 已发行量是否应考虑内存池内未被写入区块链的交易,以防止“双重发行”
         if (tx.Amount - quantity_issued < -r.Amount)
         {
             return(false);
         }
     }
     return(true);
 }
Exemplo n.º 3
0
 private void button1_Click(object sender, EventArgs e)
 {
     RegisterTransaction antshare = new RegisterTransaction
     {
         AssetType = AssetType.AntShare,
         Name = "[{'lang':'zh-CN','name':'小蚁股'},{'lang':'en','name':'AntShare'}]",
         Amount = Fixed8.FromDecimal(numericUpDown1.Value),
         Issuer = textBox1.Text.ToScriptHash(),
         Admin = textBox2.Text.ToScriptHash(),
         Inputs = new TransactionInput[0],
         Outputs = new TransactionOutput[0]
     };
     SignatureContext context = new SignatureContext(antshare);
     InformationBox.Show(context.ToString(), "小蚁股签名上下文");
 }
Exemplo n.º 4
0
        /// <summary>
        /// 获取需要校验的脚本散列值
        /// </summary>
        /// <returns>返回需要校验的脚本散列值</returns>
        public override UInt160[] GetScriptHashesForVerifying()
        {
            HashSet <UInt160> hashes = new HashSet <UInt160>(base.GetScriptHashesForVerifying());

            foreach (TransactionResult result in GetTransactionResults().Where(p => p.Amount < Fixed8.Zero))
            {
                RegisterTransaction tx = Blockchain.Default.GetTransaction(result.AssetId) as RegisterTransaction;
                if (tx == null)
                {
                    throw new InvalidOperationException();
                }
                hashes.Add(tx.Admin);
            }
            return(hashes.OrderBy(p => p).ToArray());
        }
Exemplo n.º 5
0
        public override UInt160[] GetScriptHashesForVerifying()
        {
            HashSet <UInt160> hashes = new HashSet <UInt160>(base.GetScriptHashesForVerifying());

            foreach (var group in Outputs.GroupBy(p => p.AssetId))
            {
                RegisterTransaction tx = Blockchain.Default.GetTransaction(group.Key) as RegisterTransaction;
                if (tx == null)
                {
                    throw new InvalidOperationException();
                }
                if (tx.AssetType == AssetType.Share)
                {
                    hashes.UnionWith(group.Select(p => p.ScriptHash));
                }
            }
            return(hashes.OrderBy(p => p).ToArray());
        }
Exemplo n.º 6
0
        private void button1_Click(object sender, EventArgs e)
        {
            RegisterTransaction antshare = new RegisterTransaction
            {
                AssetType = AssetType.AntShare,
#if TESTNET
                Name = "[{'lang':'zh-CN','name':'小蚁股(测试)'},{'lang':'en','name':'AntShare(TestNet)'}]",
#else
                Name = "[{'lang':'zh-CN','name':'小蚁股'},{'lang':'en','name':'AntShare'}]",
#endif
                Amount = Fixed8.FromDecimal(numericUpDown1.Value),
                Issuer = ECPoint.Parse(textBox1.Text, ECCurve.Secp256r1),
                Admin = Wallet.ToScriptHash(textBox2.Text),
                Attributes = new TransactionAttribute[0],
                Inputs = new TransactionInput[0],
                Outputs = new TransactionOutput[0]
            };
            SignatureContext context = new SignatureContext(antshare);
            InformationBox.Show(context.ToString(), "小蚁股签名上下文:");
        }
Exemplo n.º 7
0
        public virtual UInt160[] GetScriptHashesForVerifying()
        {
            if (References == null)
            {
                throw new InvalidOperationException();
            }
            TransactionOutput[] inputs = Inputs.Select(p => References[p]).ToArray();
            HashSet <UInt160>   hashes = new HashSet <UInt160>(inputs.Where(p => p.Value > Fixed8.Zero).Select(p => p.ScriptHash));

            foreach (UInt256 asset_id in inputs.Where(p => p.Value < Fixed8.Zero).Select(p => p.AssetId).Distinct())
            {
                RegisterTransaction tx = Blockchain.Default.GetTransaction(asset_id) as RegisterTransaction;
                if (tx == null)
                {
                    throw new InvalidOperationException();
                }
                hashes.Add(tx.Admin);
            }
            return(hashes.OrderBy(p => p).ToArray());
        }
Exemplo n.º 8
0
        /// <summary>
        /// 获取需要校验的脚本散列值
        /// </summary>
        /// <returns>返回需要校验的脚本散列值</returns>
        public virtual UInt160[] GetScriptHashesForVerifying()
        {
            if (References == null)
            {
                throw new InvalidOperationException();
            }
            HashSet <UInt160> hashes = new HashSet <UInt160>(Inputs.Select(p => References[p].ScriptHash));

            foreach (var group in Outputs.GroupBy(p => p.AssetId))
            {
                RegisterTransaction tx = Blockchain.Default.GetTransaction(group.Key) as RegisterTransaction;
                if (tx == null)
                {
                    throw new InvalidOperationException();
                }
                if (tx.AssetType.HasFlag(AssetType.DutyFlag))
                {
                    hashes.UnionWith(group.Select(p => p.ScriptHash));
                }
            }
            return(hashes.OrderBy(p => p).ToArray());
        }
Exemplo n.º 9
0
        UInt160[] ISignable.GetScriptHashesForVerifying()
        {
            HashSet <UInt160>   hashes = new HashSet <UInt160>();
            RegisterTransaction asset  = Blockchain.Default.GetTransaction(AssetId) as RegisterTransaction;

            if (asset == null)
            {
                throw new InvalidOperationException();
            }
            if (asset.AssetType == AssetType.Share)
            {
                hashes.Add(Client);
            }
            foreach (var group in Inputs.GroupBy(p => p.PrevHash))
            {
                Transaction tx = Blockchain.Default.GetTransaction(group.Key);
                if (tx == null)
                {
                    throw new InvalidOperationException();
                }
                hashes.UnionWith(group.Select(p => tx.Outputs[p.PrevIndex].ScriptHash));
            }
            return(hashes.OrderBy(p => p).ToArray());
        }
Exemplo n.º 10
0
        //TODO: 此处需要较多的测试来证明它的正确性
        //因为委托交易的验证算法有点太复杂了,
        //考虑未来是否可以优化这个算法
        public override bool Verify()
        {
            if (!base.Verify())
            {
                return(false);
            }
            foreach (Order order in Orders)
            {
                if (!order.VerifySignature())
                {
                    return(false);
                }
            }
            RegisterTransaction asset_value = Blockchain.Default.GetTransaction(ValueAssetId) as RegisterTransaction;

            if (asset_value?.AssetType != AssetType.Currency)
            {
                return(false);
            }
            List <Order> orders = new List <Order>(Orders);

            foreach (var group in Inputs.GroupBy(p => p.PrevHash))
            {
                Transaction tx = Blockchain.Default.GetTransaction(group.Key);
                if (tx == null)
                {
                    return(false);
                }
                AgencyTransaction tx_agency = tx as AgencyTransaction;
                if (tx_agency?.SplitOrder == null || tx_agency.AssetId != AssetId || tx_agency.ValueAssetId != ValueAssetId || tx_agency.Agent != Agent)
                {
                    continue;
                }
                var outputs = group.Select(p => new
                {
                    Input  = p,
                    Output = tx_agency.Outputs[p.PrevIndex]
                }).Where(p => p.Output.ScriptHash == tx_agency.SplitOrder.Client).ToDictionary(p => p.Input, p => p.Output);
                if (outputs.Count == 0)
                {
                    continue;
                }
                if (outputs.Count != tx_agency.Outputs.Count(p => p.ScriptHash == tx_agency.SplitOrder.Client))
                {
                    return(false);
                }
                orders.Add(new Order
                {
                    AssetId      = this.AssetId,
                    ValueAssetId = this.ValueAssetId,
                    Agent        = this.Agent,
                    Amount       = tx_agency.SplitOrder.Amount,
                    Price        = tx_agency.SplitOrder.Price,
                    Client       = tx_agency.SplitOrder.Client,
                    Inputs       = outputs.Keys.ToArray()
                });
            }
            if (orders.Count < 2)
            {
                return(false);
            }
            if (orders.Count(p => p.Amount > Fixed8.Zero) == 0 || orders.Count(p => p.Amount < Fixed8.Zero) == 0)
            {
                return(false);
            }
            Fixed8 amount_unmatched = orders.Sum(p => p.Amount);

            if (amount_unmatched == Fixed8.Zero)
            {
                if (SplitOrder != null)
                {
                    return(false);
                }
            }
            else
            {
                if (SplitOrder?.Amount != amount_unmatched)
                {
                    return(false);
                }
            }
            foreach (Order order in orders)
            {
                TransactionOutput[] inputs = order.Inputs.Select(p => References[p]).ToArray();
                if (order.Amount > Fixed8.Zero)
                {
                    if (inputs.Any(p => p.AssetId != order.ValueAssetId))
                    {
                        return(false);
                    }
                    if (inputs.Sum(p => p.Value) < order.Amount * order.Price)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (inputs.Any(p => p.AssetId != order.AssetId))
                    {
                        return(false);
                    }
                    if (inputs.Sum(p => p.Value) < order.Amount)
                    {
                        return(false);
                    }
                }
            }
            if (SplitOrder != null)
            {
                Fixed8 price_worst = amount_unmatched > Fixed8.Zero ? orders.Min(p => p.Price) : orders.Max(p => p.Price);
                if (SplitOrder.Price != price_worst)
                {
                    return(false);
                }
                Order[] orders_worst = orders.Where(p => p.Price == price_worst && p.Client == SplitOrder.Client).ToArray();
                if (orders_worst.Length == 0)
                {
                    return(false);
                }
                Fixed8 amount_worst = orders_worst.Sum(p => p.Amount);
                if (amount_worst.Abs() < amount_unmatched.Abs())
                {
                    return(false);
                }
                Order order_combine = new Order
                {
                    AssetId      = this.AssetId,
                    ValueAssetId = this.ValueAssetId,
                    Agent        = this.Agent,
                    Amount       = amount_worst - amount_unmatched,
                    Price        = price_worst,
                    Client       = SplitOrder.Client,
                    Inputs       = orders_worst.SelectMany(p => p.Inputs).ToArray()
                };
                foreach (Order order_worst in orders_worst)
                {
                    orders.Remove(order_worst);
                }
                orders.Add(order_combine);
            }
            foreach (var group in orders.GroupBy(p => p.Client))
            {
                TransactionOutput[] inputs  = group.SelectMany(p => p.Inputs).Select(p => References[p]).ToArray();
                TransactionOutput[] outputs = Outputs.Where(p => p.ScriptHash == group.Key).ToArray();
                Fixed8 money_spent          = inputs.Where(p => p.AssetId == ValueAssetId).Sum(p => p.Value) - outputs.Where(p => p.AssetId == ValueAssetId).Sum(p => p.Value);
                Fixed8 amount_changed       = outputs.Where(p => p.AssetId == AssetId).Sum(p => p.Value) - inputs.Where(p => p.AssetId == AssetId).Sum(p => p.Value);
                if (amount_changed != group.Sum(p => p.Amount))
                {
                    return(false);
                }
                if (money_spent > group.Sum(p => p.Amount * p.Price))
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 11
0
        /// <summary>
        /// 验证交易
        /// </summary>
        /// <returns>返回验证的结果</returns>
        public virtual bool Verify(IEnumerable <Transaction> mempool)
        {
            if (Blockchain.Default.ContainsTransaction(Hash))
            {
                return(true);
            }
            if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes) || !Blockchain.Default.Ability.HasFlag(BlockchainAbility.TransactionIndexes))
            {
                return(false);
            }
            for (int i = 1; i < Inputs.Length; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    if (Inputs[i].PrevHash == Inputs[j].PrevHash && Inputs[i].PrevIndex == Inputs[j].PrevIndex)
                    {
                        return(false);
                    }
                }
            }
            if (mempool.SelectMany(p => p.Inputs).Intersect(Inputs).Count() > 0)
            {
                return(false);
            }
            if (Blockchain.Default.IsDoubleSpend(this))
            {
                return(false);
            }
            foreach (var group in Outputs.GroupBy(p => p.AssetId))
            {
                RegisterTransaction asset = Blockchain.Default.GetTransaction(group.Key) as RegisterTransaction;
                if (asset == null)
                {
                    return(false);
                }
                foreach (TransactionOutput output in group)
                {
                    if (output.Value.GetData() % (long)Math.Pow(10, 8 - asset.Precision) != 0)
                    {
                        return(false);
                    }
                }
            }
            TransactionResult[] results = GetTransactionResults()?.ToArray();
            if (results == null)
            {
                return(false);
            }
            TransactionResult[] results_destroy = results.Where(p => p.Amount > Fixed8.Zero).ToArray();
            if (results_destroy.Length > 1)
            {
                return(false);
            }
            if (results_destroy.Length == 1 && results_destroy[0].AssetId != Blockchain.AntCoin.Hash)
            {
                return(false);
            }
            if (SystemFee > Fixed8.Zero && (results_destroy.Length == 0 || results_destroy[0].Amount < SystemFee))
            {
                return(false);
            }
            TransactionResult[] results_issue = results.Where(p => p.Amount < Fixed8.Zero).ToArray();
            switch (Type)
            {
            case TransactionType.MinerTransaction:
            case TransactionType.ClaimTransaction:
                if (results_issue.Any(p => p.AssetId != Blockchain.AntCoin.Hash))
                {
                    return(false);
                }
                break;

            case TransactionType.IssueTransaction:
                if (results_issue.Any(p => p.AssetId == Blockchain.AntCoin.Hash))
                {
                    return(false);
                }
                break;

            default:
                if (results_issue.Length > 0)
                {
                    return(false);
                }
                break;
            }
            if (Attributes.Count(p => p.Usage == TransactionAttributeUsage.ECDH02 || p.Usage == TransactionAttributeUsage.ECDH03) > 1)
            {
                return(false);
            }
            if (Attributes.Count(p => p.Usage == TransactionAttributeUsage.Vote) > 1024)
            {
                return(false);
            }
            if (Attributes.Where(p => p.Usage == TransactionAttributeUsage.Vote).Select(p => new UInt256(p.Data)).Distinct().Count() != Attributes.Count(p => p.Usage == TransactionAttributeUsage.Vote))
            {
                return(false);
            }
            if (Attributes.Any(p => p.Usage == TransactionAttributeUsage.Vote))
            {
                if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes))
                {
                    return(false);
                }
                if (Outputs.All(p => !p.AssetId.Equals(Blockchain.AntShare.Hash)))
                {
                    return(false);
                }
                HashSet <ECPoint> pubkeys = new HashSet <ECPoint>();
                foreach (UInt256 vote in Attributes.Where(p => p.Usage == TransactionAttributeUsage.Vote).Select(p => new UInt256(p.Data)))
                {
                    EnrollmentTransaction tx = Blockchain.Default.GetTransaction(vote) as EnrollmentTransaction;
                    if (tx == null)
                    {
                        return(false);
                    }
                    if (!Blockchain.Default.ContainsUnspent(vote, 0))
                    {
                        return(false);
                    }
                    if (!pubkeys.Add(tx.PublicKey))
                    {
                        return(false);
                    }
                }
            }
            return(this.VerifySignature());
        }
Exemplo n.º 12
0
        /// <summary>
        /// 验证交易
        /// </summary>
        /// <returns>返回验证的结果</returns>
        public override bool Verify()
        {
            if (Blockchain.Default.ContainsTransaction(Hash))
            {
                return(true);
            }
            if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes) || !Blockchain.Default.Ability.HasFlag(BlockchainAbility.TransactionIndexes))
            {
                return(false);
            }
            if (Blockchain.Default.IsDoubleSpend(this))
            {
                return(false);
            }
            foreach (var group in Outputs.GroupBy(p => p.AssetId))
            {
                RegisterTransaction asset = Blockchain.Default.GetTransaction(group.Key) as RegisterTransaction;
                if (asset == null)
                {
                    return(false);
                }
                foreach (TransactionOutput output in group)
                {
                    if (output.Value.GetData() % (long)Math.Pow(10, 8 - asset.Precision) != 0)
                    {
                        return(false);
                    }
                }
            }
            TransactionResult[] results = GetTransactionResults()?.ToArray();
            if (results == null)
            {
                return(false);
            }
            TransactionResult[] results_destroy = results.Where(p => p.Amount > Fixed8.Zero).ToArray();
            if (results_destroy.Length > 1)
            {
                return(false);
            }
            if (results_destroy.Length == 1 && results_destroy[0].AssetId != Blockchain.AntCoin.Hash)
            {
                return(false);
            }
            if (SystemFee > Fixed8.Zero && (results_destroy.Length == 0 || results_destroy[0].Amount < SystemFee))
            {
                return(false);
            }
            TransactionResult[] results_issue = results.Where(p => p.Amount < Fixed8.Zero).ToArray();
            switch (Type)
            {
            case TransactionType.MinerTransaction:
            case TransactionType.ClaimTransaction:
                if (results_issue.Any(p => p.AssetId != Blockchain.AntCoin.Hash))
                {
                    return(false);
                }
                break;

            case TransactionType.IssueTransaction:
                if (results_issue.Any(p => p.AssetId == Blockchain.AntCoin.Hash))
                {
                    return(false);
                }
                break;

            default:
                if (results_issue.Length > 0)
                {
                    return(false);
                }
                break;
            }
            TransactionAttribute script = Attributes.FirstOrDefault(p => p.Usage == TransactionAttributeUsage.Script);

            if (script != null)
            {
                ScriptEngine engine = new ScriptEngine(new Script
                {
                    StackScript  = new byte[0],
                    RedeemScript = script.Data
                }, this, InterfaceEngine.Default);
                if (!engine.Execute())
                {
                    return(false);
                }
            }
            return(this.VerifySignature());
        }
Exemplo n.º 13
0
        /// <summary>
        /// 验证交易
        /// </summary>
        /// <returns>返回验证的结果</returns>
        public virtual bool Verify()
        {
            if (Blockchain.Default.ContainsTransaction(Hash))
            {
                return(true);
            }
            if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes) || !Blockchain.Default.Ability.HasFlag(BlockchainAbility.TransactionIndexes))
            {
                return(false);
            }
            if (Blockchain.Default.IsDoubleSpend(this))
            {
                return(false);
            }
            foreach (var group in Outputs.GroupBy(p => p.AssetId))
            {
                RegisterTransaction asset = Blockchain.Default.GetTransaction(group.Key) as RegisterTransaction;
                if (asset == null)
                {
                    return(false);
                }
                foreach (TransactionOutput output in group)
                {
                    if (output.Value.GetData() % (long)Math.Pow(10, 8 - asset.Precision) != 0)
                    {
                        return(false);
                    }
                }
            }
            TransactionResult[] results = GetTransactionResults()?.ToArray();
            if (results == null)
            {
                return(false);
            }
            TransactionResult[] results_destroy = results.Where(p => p.Amount > Fixed8.Zero).ToArray();
            if (results_destroy.Length > 1)
            {
                return(false);
            }
            if (results_destroy.Length == 1 && results_destroy[0].AssetId != Blockchain.AntCoin.Hash)
            {
                return(false);
            }
            if (SystemFee > Fixed8.Zero && (results_destroy.Length == 0 || results_destroy[0].Amount < SystemFee))
            {
                return(false);
            }
            TransactionResult[] results_issue = results.Where(p => p.Amount < Fixed8.Zero).ToArray();
            switch (Type)
            {
            case TransactionType.MinerTransaction:
            case TransactionType.ClaimTransaction:
                if (results_issue.Any(p => p.AssetId != Blockchain.AntCoin.Hash))
                {
                    return(false);
                }
                break;

            case TransactionType.IssueTransaction:
                if (results_issue.Any(p => p.AssetId == Blockchain.AntCoin.Hash))
                {
                    return(false);
                }
                break;

            default:
                if (results_issue.Length > 0)
                {
                    return(false);
                }
                break;
            }
            foreach (TransactionAttribute script in Attributes.Where(p => p.Usage == TransactionAttributeUsage.Script))
            {
                ScriptEngine engine = new ScriptEngine(this, ECDsaCrypto.Default, Blockchain.Default, InterfaceEngine.Default);
                if (!engine.ExecuteScript(script.Data, false))
                {
                    return(false);
                }
                if (engine.Stack.Count != 1 || !engine.Stack.Pop())
                {
                    return(false);
                }
            }
            if (Attributes.Any(p => p.Usage == TransactionAttributeUsage.Vote))
            {
                if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes))
                {
                    return(false);
                }
                HashSet <ECPoint> pubkeys = new HashSet <ECPoint>();
                foreach (UInt256 vote in Attributes.Where(p => p.Usage == TransactionAttributeUsage.Vote).Select(p => new UInt256(p.Data)))
                {
                    EnrollmentTransaction tx = Blockchain.Default.GetTransaction(vote) as EnrollmentTransaction;
                    if (tx == null)
                    {
                        return(false);
                    }
                    if (!Blockchain.Default.ContainsUnspent(vote, 0))
                    {
                        return(false);
                    }
                    if (!pubkeys.Add(tx.PublicKey))
                    {
                        return(false);
                    }
                }
            }
            return(this.VerifySignature());
        }
Exemplo n.º 14
0
 public override bool Verify()
 {
     if (Blockchain.Default.ContainsTransaction(Hash))
     {
         return(true);
     }
     if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes) || !Blockchain.Default.Ability.HasFlag(BlockchainAbility.TransactionIndexes))
     {
         return(false);
     }
     if (Blockchain.Default.IsDoubleSpend(this))
     {
         return(false);
     }
     foreach (UInt256 hash in Outputs.Select(p => p.AssetId).Distinct())
     {
         if (!Blockchain.Default.ContainsAsset(hash))
         {
             return(false);
         }
     }
     if (References == null)
     {
         return(false);
     }
     foreach (var group in Outputs.Where(p => p.Value < Fixed8.Zero).GroupBy(p => p.AssetId))
     {
         if (group.Key == Blockchain.AntCoin.Hash || group.Key == Blockchain.AntShare.Hash)
         {
             return(false);
         }
         RegisterTransaction tx = Blockchain.Default.GetTransaction(group.Key) as RegisterTransaction;
         if (tx == null)
         {
             return(false);
         }
         if (tx.Amount != Fixed8.Zero)
         {
             return(false);
         }
         if (group.Any(p => p.ScriptHash != tx.Issuer))
         {
             return(false);
         }
         if (Type != TransactionType.IssueTransaction && References.Values.Where(p => p.AssetId == group.Key && p.Value < Fixed8.Zero).Sum(p => p.Value) > group.Sum(p => p.Value))
         {
             return(false);
         }
     }
     TransactionResult[] results         = GetTransactionResults().ToArray();
     TransactionResult[] results_destroy = results.Where(p => p.Amount > Fixed8.Zero).ToArray();
     if (results_destroy.Length > 1)
     {
         return(false);
     }
     if (results_destroy.Length == 1 && results_destroy[0].AssetId != Blockchain.AntCoin.Hash)
     {
         return(false);
     }
     if (SystemFee > Fixed8.Zero && (results_destroy.Length == 0 || results_destroy[0].Amount < SystemFee))
     {
         return(false);
     }
     TransactionResult[] results_issue = results.Where(p => p.Amount < Fixed8.Zero).ToArray();
     if (Type == TransactionType.GenerationTransaction)
     {
         if (results_issue.Any(p => p.AssetId != Blockchain.AntCoin.Hash))
         {
             return(false);
         }
     }
     else if (Type != TransactionType.IssueTransaction)
     {
         if (results_issue.Length > 0)
         {
             return(false);
         }
     }
     return(this.VerifySignature());
 }