コード例 #1
0
        public static void SignAndShowInformation(Transaction tx)
        {
            if (tx == null)
            {
                MessageBox.Show(LanHelper.LocalLanguage("Insufficient funds, transaction cannot be initiated."));
                return;
            }
            ContractParametersContext context;

            try
            {
                context = new ContractParametersContext(tx);
            }
            catch (InvalidOperationException)
            {
                MessageBox.Show(LanHelper.LocalLanguage("Blockchain unsynchronized, transaction cannot be sent."));
                return;
            }
            Program.CurrentWallet.Sign(context);
            if (context.Completed)
            {
                tx.Witnesses = context.GetWitnesses();
                Program.CurrentWallet.ApplyTransaction(tx);
                Program.OXSystem.LocalNode.Tell(new LocalNode.Relay {
                    Inventory = tx
                });
                InformationBox.Show(tx.Hash.ToString(), LanHelper.LocalLanguage("Transaction sent, TXID:"), LanHelper.LocalLanguage("Transaction successful"));
            }
            else
            {
                InformationBox.Show(context.ToString(), LanHelper.LocalLanguage("Transaction initiated, but the signature is incomplete."), LanHelper.LocalLanguage("Incomplete signature"));
            }
        }
コード例 #2
0
        private void ShowCost(Fixed8 fee)
        {
            StringBuilder sb = new StringBuilder(32);

            string content = sb.AppendFormat("{0} {1} {2}", fee.ToString(), "OXC", LanHelper.LocalLanguage("will be consumed, confirm?")).ToString();

            this.CostContext.Text = content;
        }
コード例 #3
0
        private void button5_Click(object sender, EventArgs e)
        {
            byte[] script;
            try
            {
                script = textBox6.Text.Trim().HexToBytes();
            }
            catch (FormatException ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
            if (tx == null)
            {
                tx = new InvocationTransaction();
            }
            tx.Version = 1;
            tx.Script  = script;
            if (tx.Attributes == null)
            {
                tx.Attributes = new TransactionAttribute[0];
            }
            if (tx.Inputs == null)
            {
                tx.Inputs = new CoinReference[0];
            }
            if (tx.Outputs == null)
            {
                tx.Outputs = new TransactionOutput[0];
            }
            if (tx.Witnesses == null)
            {
                tx.Witnesses = new Witness[0];
            }
            ApplicationEngine engine = ApplicationEngine.Run(tx.Script, tx, testMode: true);
            StringBuilder     sb     = new StringBuilder();

            sb.AppendLine($"VM State: {engine.State}");
            sb.AppendLine($"OXC Consumed: {engine.GasConsumed}");
            sb.AppendLine($"Evaluation Stack: {new JArray(engine.ResultStack.Select(p => p.ToParameter().ToJson()))}");
            textBox7.Text = sb.ToString();
            if (!engine.State.HasFlag(VMState.FAULT))
            {
                tx.Gas = engine.GasConsumed - Fixed8.FromDecimal(10);
                if (tx.Gas < Fixed8.Zero)
                {
                    tx.Gas = Fixed8.Zero;
                }
                tx.Gas = tx.Gas.Ceiling();
                Fixed8 fee = tx.Gas;
                label7.Text     = fee + " oxc";
                button3.Enabled = true;
            }
            else
            {
                MessageBox.Show(LanHelper.LocalLanguage("Execution terminated in fault state."));
            }
        }
コード例 #4
0
        private void button1_Click(object sender, EventArgs e)
        {
            ContractTransaction tx = Program.CurrentWallet.MakeTransaction(new ContractTransaction
            {
                Outputs = txOutListBox1.Items.Select(p => p.ToTxOutput()).ToArray()
            }, fee: Fixed8.Zero);

            textBox3.Text = RequestToJson(tx).ToString();
            InformationBox.Show(textBox3.Text, LanHelper.LocalLanguage("Transaction request generated, please send it to the counterparty or merge it with the counterparty's request."), LanHelper.LocalLanguage("Trade Request"));
            tabControl1.SelectedTab = tabPage2;
        }
コード例 #5
0
 /// <summary>
 /// Required method for Designer support - do not modify
 /// the contents of this method with the code editor.
 /// </summary>
 private void InitializeComponent()
 {
     System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NetFeeDialog));
     this.button1     = new System.Windows.Forms.Button();
     this.button2     = new System.Windows.Forms.Button();
     this.CostContext = new System.Windows.Forms.Label();
     this.SuspendLayout();
     //
     // button1
     //
     this.button1.DialogResult            = System.Windows.Forms.DialogResult.OK;
     this.button1.Location                = new System.Drawing.Point(63, 122);
     this.button1.Name                    = "button1";
     this.button1.Size                    = new System.Drawing.Size(75, 23);
     this.button1.TabIndex                = 1;
     this.button1.Text                    = LanHelper.LocalLanguage("Confirm");
     this.button1.UseVisualStyleBackColor = true;
     //
     // button2
     //
     this.button2.DialogResult            = System.Windows.Forms.DialogResult.Cancel;
     this.button2.Location                = new System.Drawing.Point(198, 122);
     this.button2.Name                    = "button2";
     this.button2.Size                    = new System.Drawing.Size(75, 23);
     this.button2.TabIndex                = 2;
     this.button2.Text                    = LanHelper.LocalLanguage("Cancel");
     this.button2.UseVisualStyleBackColor = true;
     this.button2.Click                  += new System.EventHandler(this.button2_Click);
     //
     // CostContext
     //
     this.CostContext.Font       = new System.Drawing.Font("Microsoft YaHei", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
     this.CostContext.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
     this.CostContext.Location   = new System.Drawing.Point(12, 9);
     this.CostContext.Name       = "CostContext";
     this.CostContext.Size       = new System.Drawing.Size(305, 110);
     this.CostContext.TabIndex   = 3;
     this.CostContext.Text       = "label1";
     this.CostContext.TextAlign  = System.Drawing.ContentAlignment.MiddleCenter;
     //
     // NetFeeDialog
     //
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
     this.AutoScaleMode       = System.Windows.Forms.AutoScaleMode.Font;
     this.ClientSize          = new System.Drawing.Size(329, 203);
     this.Controls.Add(this.CostContext);
     this.Controls.Add(this.button2);
     this.Controls.Add(this.button1);
     this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
     this.Name = "NetFeeDialog";
     this.Text = "Cost Warning";
     this.ResumeLayout(false);
 }
コード例 #6
0
 private void RefreshConfirmations()
 {
     foreach (ListViewItem item in listView3.Items)
     {
         uint?height        = item.Tag as uint?;
         int? confirmations = (int)Blockchain.Singleton.Height - (int?)height + 1;
         if (confirmations <= 0)
         {
             confirmations = null;
         }
         item.SubItems["confirmations"].Text = confirmations?.ToString() ?? LanHelper.LocalLanguage("unconfirmed");
     }
 }
コード例 #7
0
        private void AddTransaction(Transaction tx, uint?height, uint time)
        {
            int?confirmations = (int)Blockchain.Singleton.Height - (int?)height + 1;

            if (confirmations <= 0)
            {
                confirmations = null;
            }
            string confirmations_str = confirmations?.ToString() ?? LanHelper.LocalLanguage("unconfirmed");
            string txid = tx.Hash.ToString();

            if (listView3.Items.ContainsKey(txid))
            {
                listView3.Items[txid].Tag = height;
                listView3.Items[txid].SubItems["confirmations"].Text = confirmations_str;
            }
            else
            {
                listView3.Items.Insert(0, new ListViewItem(new[]
                {
                    new ListViewItem.ListViewSubItem
                    {
                        Name = "time",
                        Text = time.ToDateTime().ToString()
                    },
                    new ListViewItem.ListViewSubItem
                    {
                        Name = "hash",
                        Text = txid
                    },
                    new ListViewItem.ListViewSubItem
                    {
                        Name = "confirmations",
                        Text = confirmations_str
                    },
                    //add transaction type to list by phinx
                    new ListViewItem.ListViewSubItem
                    {
                        Name = "txtype",
                        Text = tx.Type.ToString()
                    }
                    //end
                }, -1)
                {
                    Name = txid,
                    Tag  = height
                });
            }
        }
コード例 #8
0
        private void button2_Click(object sender, EventArgs e)
        {
            IEnumerable <CoinReference>     inputs;
            IEnumerable <TransactionOutput> outputs;
            JObject json = JObject.Parse(textBox2.Text);

            if (json.ContainsProperty("hex"))
            {
                ContractTransaction tx_mine   = JsonToRequest(JObject.Parse(textBox3.Text));
                ContractTransaction tx_others = (ContractTransaction)ContractParametersContext.FromJson(json).Verifiable;
                inputs = tx_others.Inputs.Except(tx_mine.Inputs);
                List <TransactionOutput> outputs_others = new List <TransactionOutput>(tx_others.Outputs);
                foreach (TransactionOutput output_mine in tx_mine.Outputs)
                {
                    TransactionOutput output_others = outputs_others.FirstOrDefault(p => p.AssetId == output_mine.AssetId && p.Value == output_mine.Value && p.ScriptHash == output_mine.ScriptHash);
                    if (output_others == null)
                    {
                        MessageBox.Show(LanHelper.LocalLanguage("Validation failed, the counterparty falsified the transaction content!"), LanHelper.LocalLanguage("Failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    outputs_others.Remove(output_others);
                }
                outputs = outputs_others;
            }
            else
            {
                ContractTransaction tx_others = JsonToRequest(json);
                inputs  = tx_others.Inputs;
                outputs = tx_others.Outputs;
            }
            try
            {
                if (inputs.Select(p => Blockchain.Singleton.GetTransaction(p.PrevHash).Outputs[p.PrevIndex].ScriptHash).Distinct().Any(p => Program.CurrentWallet.Contains(p)))
                {
                    MessageBox.Show(LanHelper.LocalLanguage("Validation failed, the counterparty generated illegal transaction content!"), LanHelper.LocalLanguage("Failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            catch
            {
                MessageBox.Show(LanHelper.LocalLanguage("Validation failed, invalid transaction or unsynchronized blockchain, please try again when synchronized!"), LanHelper.LocalLanguage("Failed"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            outputs = outputs.Where(p => Program.CurrentWallet.Contains(p.ScriptHash));
            using (TradeVerificationDialog dialog = new TradeVerificationDialog(outputs))
            {
                button3.Enabled = dialog.ShowDialog() == DialogResult.OK;
            }
        }
コード例 #9
0
        private void button4_Click(object sender, EventArgs e)
        {
            ContractParametersContext context = ContractParametersContext.Parse(textBox2.Text);

            if (!(context.Verifiable is Transaction tx))
            {
                MessageBox.Show("Only support to broadcast transaction.");
                return;
            }
            tx.Witnesses = context.GetWitnesses();
            Program.OXSystem.LocalNode.Tell(new LocalNode.Relay {
                Inventory = tx
            });
            InformationBox.Show(tx.Hash.ToString(), LanHelper.LocalLanguage("Data broadcast success, the hash is shown as follows:"), LanHelper.LocalLanguage("Broadcast Success"));
            button4.Visible = false;
        }
コード例 #10
0
 private void 修改密码CToolStripMenuItem_Click(object sender, EventArgs e)
 {
     using (ChangePasswordDialog dialog = new ChangePasswordDialog())
     {
         if (dialog.ShowDialog() != DialogResult.OK)
         {
             return;
         }
         if (((UserWallet)Program.CurrentWallet).ChangePassword(dialog.OldPassword, dialog.NewPassword))
         {
             MessageBox.Show(LanHelper.LocalLanguage("Change password successful."));
         }
         else
         {
             MessageBox.Show(LanHelper.LocalLanguage("Password Incorrect"));
         }
     }
 }
コード例 #11
0
 private void  除DToolStripMenuItem_Click(object sender, EventArgs e)
 {
     if (MessageBox.Show(LanHelper.LocalLanguage("Upon deletion, assets in these addresses will be permanently lost, are you sure to proceed?"), LanHelper.LocalLanguage("Confirmation"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) != DialogResult.Yes)
     {
         return;
     }
     WalletAccount[] accounts = listView1.SelectedItems.OfType <ListViewItem>().Select(p => (WalletAccount)p.Tag).ToArray();
     foreach (WalletAccount account in accounts)
     {
         listView1.Items.RemoveByKey(account.Address);
         Program.CurrentWallet.DeleteAccount(account.ScriptHash);
     }
     if (Program.CurrentWallet is NEP6Wallet wallet)
     {
         wallet.Save();
     }
     balance_changed    = true;
     check_nep5_balance = true;
 }
コード例 #12
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "")
            {
                MessageBox.Show(LanHelper.LocalLanguage("You must input JSON object pending signature data."));
                return;
            }
            ContractParametersContext context = ContractParametersContext.Parse(textBox1.Text);

            if (!Program.CurrentWallet.Sign(context))
            {
                MessageBox.Show(LanHelper.LocalLanguage("The private key that can sign the data is not found."));
                return;
            }
            textBox2.Text = context.ToString();
            if (context.Completed)
            {
                button4.Visible = true;
            }
        }
コード例 #13
0
        private void  除DToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (listView2.SelectedIndices.Count == 0)
            {
                return;
            }
            var delete = listView2.SelectedItems.OfType <ListViewItem>().Select(p => p.Tag as AssetState).Where(p => p != null).Select(p => new
            {
                Asset = p,
                Value = Program.CurrentWallet.GetAvailable(p.AssetId)
            }).ToArray();

            if (delete.Length == 0)
            {
                return;
            }
            if (MessageBox.Show($"{LanHelper.LocalLanguage("Assets cannot be recovered once deleted, are you sure to delete the assets?")}\n"
                                + string.Join("\n", delete.Select(p => $"{p.Asset.GetName()}:{p.Value}"))
                                , LanHelper.LocalLanguage("Confirmation"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) != DialogResult.Yes)
            {
                return;
            }
            ContractTransaction tx = Program.CurrentWallet.MakeTransaction(new ContractTransaction
            {
                Outputs = delete.Select(p => new TransactionOutput
                {
                    AssetId    = p.Asset.AssetId,
                    Value      = p.Value,
                    ScriptHash = RecycleScriptHash
                }).ToArray()
            }, fee: Fixed8.Zero);

            try
            {
                Helper.SignAndShowInformation(tx);
            }
            catch
            {
                return;
            }
        }
コード例 #14
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "")
            {
                MessageBox.Show(LanHelper.LocalLanguage("You must input JSON object pending signature data."));
                return;
            }

            byte[] raw, signedData = null;
            try
            {
                switch (cmbFormat.SelectedIndex)
                {
                case 0: raw = Encoding.UTF8.GetBytes(textBox1.Text); break;

                case 1: raw = textBox1.Text.HexToBytes(); break;

                default: return;
                }
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var account = (WalletEntry)cmbAddress.SelectedItem;
            var keys    = account.Account.GetKey();

            try
            {
                signedData = Crypto.Default.Sign(raw, keys.PrivateKey, keys.PublicKey.EncodePoint(false).Skip(1).ToArray());
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            textBox2.Text = signedData?.ToHexString();
        }
コード例 #15
0
        private void importWatchOnlyAddressToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string text = InputBox.Show(LanHelper.LocalLanguage("Address"), LanHelper.LocalLanguage("Import Watch-Only Address"));

            if (string.IsNullOrEmpty(text))
            {
                return;
            }
            using (StringReader reader = new StringReader(text))
            {
                while (true)
                {
                    string address = reader.ReadLine();
                    if (address == null)
                    {
                        break;
                    }
                    address = address.Trim();
                    if (string.IsNullOrEmpty(address))
                    {
                        continue;
                    }
                    UInt160 scriptHash;
                    try
                    {
                        scriptHash = address.ToScriptHash();
                    }
                    catch (FormatException)
                    {
                        continue;
                    }
                    WalletAccount account = Program.CurrentWallet.CreateAccount(scriptHash);
                    AddAccount(account, true);
                }
            }
            if (Program.CurrentWallet is NEP6Wallet wallet)
            {
                wallet.Save();
            }
        }
コード例 #16
0
 private void lockToolStripMenuItem_Click(object sender, EventArgs e)
 {
     using (CreateLockAccountDialog dialog = new CreateLockAccountDialog())
     {
         if (dialog.ShowDialog() != DialogResult.OK)
         {
             return;
         }
         Contract contract = dialog.GetContract();
         if (contract == null)
         {
             MessageBox.Show(LanHelper.LocalLanguage("Failed to add smart contract, corresponding private key missing in this wallet."));
             return;
         }
         WalletAccount account = Program.CurrentWallet.CreateAccount(contract, dialog.GetKey());
         if (Program.CurrentWallet is NEP6Wallet wallet)
         {
             wallet.Save();
         }
         listView1.SelectedIndices.Clear();
         AddAccount(account, true);
     }
 }
コード例 #17
0
        private void button3_Click(object sender, EventArgs e)
        {
            ContractParametersContext context;
            JObject json1 = JObject.Parse(textBox2.Text);

            if (json1.ContainsProperty("hex"))
            {
                context = ContractParametersContext.FromJson(json1);
            }
            else
            {
                ContractTransaction tx1 = JsonToRequest(json1);
                ContractTransaction tx2 = JsonToRequest(JObject.Parse(textBox3.Text));
                context = new ContractParametersContext(new ContractTransaction
                {
                    Attributes = new TransactionAttribute[0],
                    Inputs     = tx1.Inputs.Concat(tx2.Inputs).ToArray(),
                    Outputs    = tx1.Outputs.Concat(tx2.Outputs).ToArray()
                });
            }
            Program.CurrentWallet.Sign(context);
            if (context.Completed)
            {
                ContractTransaction tx = (ContractTransaction)context.Verifiable;
                tx.Witnesses = context.GetWitnesses();
                Program.CurrentWallet.ApplyTransaction(tx);
                Program.OXSystem.LocalNode.Tell(new LocalNode.Relay {
                    Inventory = tx
                });
                InformationBox.Show(tx.Hash.ToString(), LanHelper.LocalLanguage("Transaction sent, this is the TXID:"), LanHelper.LocalLanguage("Trade Success"));
            }
            else
            {
                InformationBox.Show(context.ToString(), LanHelper.LocalLanguage("Transaction generated, please send the following information to the counterparty for signing:"), LanHelper.LocalLanguage("Need Signature"));
            }
        }
コード例 #18
0
 private void button1_Click(object sender, EventArgs e)
 {
     remark = InputBox.Show(LanHelper.LocalLanguage("Enter remark here, which will be recorded on the blockchain"), LanHelper.LocalLanguage("Transaction Remark"), remark);
 }
コード例 #19
0
 private void 打开钱包数据库OToolStripMenuItem_Click(object sender, EventArgs e)
 {
     using (OpenWalletDialog dialog = new OpenWalletDialog())
     {
         if (dialog.ShowDialog() != DialogResult.OK)
         {
             return;
         }
         string path = dialog.WalletPath;
         Wallet wallet;
         if (Path.GetExtension(path) == ".db3")
         {
             if (MessageBox.Show(LanHelper.LocalLanguage("Opening wallet files in older versions, update to newest format?Note: updated files cannot be openned by clients in older versions!"), LanHelper.LocalLanguage("Migrate Wallet"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
             {
                 string path_old = path;
                 path = Path.ChangeExtension(path_old, ".json");
                 NEP6Wallet nep6wallet;
                 try
                 {
                     nep6wallet = NEP6Wallet.Migrate(GetIndexer(), path, path_old, dialog.Password);
                 }
                 catch (CryptographicException)
                 {
                     MessageBox.Show(LanHelper.LocalLanguage("Password Incorrect"));
                     return;
                 }
                 nep6wallet.Save();
                 nep6wallet.Unlock(dialog.Password);
                 wallet = nep6wallet;
                 MessageBox.Show($"{LanHelper.LocalLanguage("Wallet file relocated. New wallet file has been saved at: ")}\n{path}");
             }
             else
             {
                 try
                 {
                     wallet = UserWallet.Open(GetIndexer(), path, dialog.Password);
                 }
                 catch (CryptographicException)
                 {
                     MessageBox.Show(LanHelper.LocalLanguage("Password Incorrect"));
                     return;
                 }
             }
         }
         else
         {
             NEP6Wallet nep6wallet = new NEP6Wallet(GetIndexer(), path);
             try
             {
                 nep6wallet.Unlock(dialog.Password);
             }
             catch (CryptographicException)
             {
                 MessageBox.Show(LanHelper.LocalLanguage("Password Incorrect"));
                 return;
             }
             wallet = nep6wallet;
         }
         ChangeWallet(wallet);
         Settings.Default.LastWalletPath = path;
         Settings.Default.Save();
     }
 }
コード例 #20
0
        private void timer1_Tick(object sender, EventArgs e)
        {
            uint walletHeight = 0;

            if (Program.CurrentWallet != null)
            {
                walletHeight = (Program.CurrentWallet.WalletHeight > 0) ? Program.CurrentWallet.WalletHeight - 1 : 0;
            }

            lbl_height.Text = $"{walletHeight}/{Blockchain.Singleton.Height}/{Blockchain.Singleton.HeaderHeight}";

            lbl_count_node.Text = LocalNode.Singleton.ConnectedCount.ToString();
            TimeSpan persistence_span = DateTime.UtcNow - persistence_time;

            if (persistence_span < TimeSpan.Zero)
            {
                persistence_span = TimeSpan.Zero;
            }
            if (persistence_span > Blockchain.TimePerBlock)
            {
                toolStripProgressBar1.Style = ProgressBarStyle.Marquee;
            }
            else
            {
                toolStripProgressBar1.Value = persistence_span.Seconds;
                toolStripProgressBar1.Style = ProgressBarStyle.Blocks;
            }
            if (Program.CurrentWallet != null)
            {
                if (Program.CurrentWallet.WalletHeight <= Blockchain.Singleton.Height + 1)
                {
                    if (balance_changed)
                    {
                        using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
                        {
                            IEnumerable <Coin> coins             = Program.CurrentWallet?.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent)) ?? Enumerable.Empty <Coin>();
                            Fixed8             bonus_available   = snapshot.CalculateBonus(Program.CurrentWallet.GetUnclaimedCoins().Select(p => p.Reference));
                            Fixed8             bonus_unavailable = snapshot.CalculateBonus(coins.Where(p => p.State.HasFlag(CoinState.Confirmed) && p.Output.AssetId.Equals(Blockchain.GoverningToken.Hash)).Select(p => p.Reference), snapshot.Height + 1);
                            Fixed8             bonus             = bonus_available + bonus_unavailable;
                            var assets = coins.GroupBy(p => p.Output.AssetId, (k, g) => new
                            {
                                Asset = snapshot.Assets.TryGet(k),
                                Value = g.Sum(p => p.Output.Value),
                                Claim = k.Equals(Blockchain.UtilityToken.Hash) ? bonus : Fixed8.Zero
                            }).ToDictionary(p => p.Asset.AssetId);
                            if (bonus != Fixed8.Zero && !assets.ContainsKey(Blockchain.UtilityToken.Hash))
                            {
                                assets[Blockchain.UtilityToken.Hash] = new
                                {
                                    Asset = snapshot.Assets.TryGet(Blockchain.UtilityToken.Hash),
                                    Value = Fixed8.Zero,
                                    Claim = bonus
                                };
                            }
                            var balance_ans = coins.Where(p => p.Output.AssetId.Equals(Blockchain.GoverningToken.Hash)).GroupBy(p => p.Output.ScriptHash).ToDictionary(p => p.Key, p => p.Sum(i => i.Output.Value));
                            var balance_anc = coins.Where(p => p.Output.AssetId.Equals(Blockchain.UtilityToken.Hash)).GroupBy(p => p.Output.ScriptHash).ToDictionary(p => p.Key, p => p.Sum(i => i.Output.Value));
                            foreach (ListViewItem item in listView1.Items)
                            {
                                UInt160 script_hash = item.Name.ToScriptHash();
                                Fixed8  ans         = balance_ans.ContainsKey(script_hash) ? balance_ans[script_hash] : Fixed8.Zero;
                                Fixed8  anc         = balance_anc.ContainsKey(script_hash) ? balance_anc[script_hash] : Fixed8.Zero;
                                item.SubItems["ans"].Text = ans.ToString();
                                item.SubItems["anc"].Text = anc.ToString();
                            }
                            foreach (AssetState asset in listView2.Items.OfType <ListViewItem>().Select(p => p.Tag as AssetState).Where(p => p != null).ToArray())
                            {
                                if (!assets.ContainsKey(asset.AssetId))
                                {
                                    listView2.Items.RemoveByKey(asset.AssetId.ToString());
                                }
                            }
                            foreach (var asset in assets.Values)
                            {
                                string value_text = asset.Value.ToString() + (asset.Asset.AssetId.Equals(Blockchain.UtilityToken.Hash) ? $"+({asset.Claim})" : "");
                                if (listView2.Items.ContainsKey(asset.Asset.AssetId.ToString()))
                                {
                                    listView2.Items[asset.Asset.AssetId.ToString()].SubItems["value"].Text = value_text;
                                }
                                else
                                {
                                    string asset_name = asset.Asset.AssetType == AssetType.GoverningToken ? "OXS" :
                                                        asset.Asset.AssetType == AssetType.UtilityToken ? "OXC" :
                                                        asset.Asset.GetName();
                                    listView2.Items.Add(new ListViewItem(new[]
                                    {
                                        new ListViewItem.ListViewSubItem
                                        {
                                            Name = "name",
                                            Text = asset_name
                                        },
                                        new ListViewItem.ListViewSubItem
                                        {
                                            Name = "type",
                                            Text = asset.Asset.AssetType.ToString()
                                        },
                                        new ListViewItem.ListViewSubItem
                                        {
                                            Name = "value",
                                            Text = value_text
                                        },
                                        new ListViewItem.ListViewSubItem
                                        {
                                            ForeColor = Color.Gray,
                                            Name      = "issuer",
                                            Text      = $"{LanHelper.LocalLanguage("unknown issuer")}[{asset.Asset.Owner}]"
                                        }
                                    }, -1, listView2.Groups["unchecked"])
                                    {
                                        Name = asset.Asset.AssetId.ToString(),
                                        Tag  = asset.Asset,
                                        UseItemStyleForSubItems = false
                                    });
                                }
                            }
                            balance_changed = false;
                        }
                    }
                    foreach (ListViewItem item in listView2.Groups["unchecked"].Items.OfType <ListViewItem>().ToArray())
                    {
                        ListViewItem.ListViewSubItem subitem = item.SubItems["issuer"];
                        AssetState             asset         = (AssetState)item.Tag;
                        CertificateQueryResult result;
                        if (asset.AssetType == AssetType.GoverningToken || asset.AssetType == AssetType.UtilityToken)
                        {
                            result = new CertificateQueryResult {
                                Type = CertificateQueryResultType.System
                            };
                        }
                        else
                        {
                            result = CertificateQueryService.Query(asset.Owner);
                        }
                        using (result)
                        {
                            subitem.Tag = result.Type;
                            switch (result.Type)
                            {
                            case CertificateQueryResultType.Querying:
                            case CertificateQueryResultType.QueryFailed:
                                break;

                            case CertificateQueryResultType.System:
                                subitem.ForeColor = Color.Green;
                                subitem.Text      = LanHelper.LocalLanguage("OX system");
                                break;

                            case CertificateQueryResultType.Invalid:
                                subitem.ForeColor = Color.Red;
                                subitem.Text      = $"[{ LanHelper.LocalLanguage("Invalid")}][{asset.Owner}]";
                                break;

                            case CertificateQueryResultType.Expired:
                                subitem.ForeColor = Color.Yellow;
                                subitem.Text      = $"[{LanHelper.LocalLanguage("Expired")}]{result.Certificate.Subject}[{asset.Owner}]";
                                break;

                            case CertificateQueryResultType.Good:
                                subitem.ForeColor = Color.Black;
                                subitem.Text      = $"{result.Certificate.Subject}[{asset.Owner}]";
                                break;
                            }
                            switch (result.Type)
                            {
                            case CertificateQueryResultType.System:
                            case CertificateQueryResultType.Missing:
                            case CertificateQueryResultType.Invalid:
                            case CertificateQueryResultType.Expired:
                            case CertificateQueryResultType.Good:
                                item.Group = listView2.Groups["checked"];
                                break;
                            }
                        }
                    }
                }
                if (check_nep5_balance && persistence_span > TimeSpan.FromSeconds(2))
                {
                    UInt160[] addresses = Program.CurrentWallet.GetAccounts().Select(p => p.ScriptHash).ToArray();
                    foreach (string s in Settings.Default.NEP5Watched)
                    {
                        UInt160 script_hash = UInt160.Parse(s);
                        byte[]  script;
                        using (ScriptBuilder sb = new ScriptBuilder())
                        {
                            foreach (UInt160 address in addresses)
                            {
                                sb.EmitAppCall(script_hash, "balanceOf", address);
                            }
                            sb.Emit(OpCode.DEPTH, OpCode.PACK);
                            sb.EmitAppCall(script_hash, "decimals");
                            sb.EmitAppCall(script_hash, "name");
                            script = sb.ToArray();
                        }
                        ApplicationEngine engine = ApplicationEngine.Run(script);
                        if (engine.State.HasFlag(VMState.FAULT))
                        {
                            continue;
                        }
                        string     name     = engine.ResultStack.Pop().GetString();
                        byte       decimals = (byte)engine.ResultStack.Pop().GetBigInteger();
                        BigInteger amount   = ((VMArray)engine.ResultStack.Pop()).Aggregate(BigInteger.Zero, (x, y) => x + y.GetBigInteger());
                        if (amount == 0)
                        {
                            listView2.Items.RemoveByKey(script_hash.ToString());
                            continue;
                        }
                        BigDecimal balance    = new BigDecimal(amount, decimals);
                        string     value_text = balance.ToString();
                        if (listView2.Items.ContainsKey(script_hash.ToString()))
                        {
                            listView2.Items[script_hash.ToString()].SubItems["value"].Text = value_text;
                        }
                        else
                        {
                            listView2.Items.Add(new ListViewItem(new[]
                            {
                                new ListViewItem.ListViewSubItem
                                {
                                    Name = "name",
                                    Text = name
                                },
                                new ListViewItem.ListViewSubItem
                                {
                                    Name = "type",
                                    Text = "NEP-5"
                                },
                                new ListViewItem.ListViewSubItem
                                {
                                    Name = "value",
                                    Text = value_text
                                },
                                new ListViewItem.ListViewSubItem
                                {
                                    ForeColor = Color.Gray,
                                    Name      = "issuer",
                                    Text      = $"ScriptHash:{script_hash}"
                                }
                            }, -1, listView2.Groups["checked"])
                            {
                                Name = script_hash.ToString(),
                                UseItemStyleForSubItems = false
                            });
                        }
                    }
                    check_nep5_balance = false;
                }
            }
        }