private void timer1_Tick(object sender, EventArgs e) { lbl_height.Text = $"{Blockchain.Default.Height}/{Blockchain.Default.HeaderHeight}"; lbl_count_node.Text = Program.LocalNode.RemoteNodeCount.ToString(); TimeSpan persistence_span = DateTime.Now - 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?.WalletHeight > Blockchain.Default.Height + 1) { return; } if (balance_changed) { IEnumerable <Coin> coins = Program.CurrentWallet?.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent)) ?? Enumerable.Empty <Coin>(); Fixed8 bonus_available = Blockchain.CalculateBonus(Program.CurrentWallet.GetUnclaimedCoins().Select(p => p.Reference)); Fixed8 bonus_unavailable = Blockchain.CalculateBonus(coins.Where(p => p.State.HasFlag(CoinState.Confirmed) && p.Output.AssetId.Equals(Blockchain.GoverningToken.Hash)).Select(p => p.Reference), Blockchain.Default.Height + 1); Fixed8 bonus = bonus_available + bonus_unavailable; var assets = coins.GroupBy(p => p.Output.AssetId, (k, g) => new { Asset = Blockchain.Default.GetAssetState(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 = Blockchain.Default.GetAssetState(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 = Wallet.ToScriptHash(item.Name); 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 => (AssetState)p.Tag).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 ? "NEO" : asset.Asset.AssetType == AssetType.UtilityToken ? "NeoGas" : 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 = $"{Strings.UnknownIssuer}[{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 = Strings.SystemIssuer; break; case CertificateQueryResultType.Invalid: subitem.ForeColor = Color.Red; subitem.Text = $"[{Strings.InvalidCertificate}][{asset.Owner}]"; break; case CertificateQueryResultType.Expired: subitem.ForeColor = Color.Yellow; subitem.Text = $"[{Strings.ExpiredCertificate}]{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; } } } }
private void timer1_Tick(object sender, EventArgs e) { lbl_height.Text = $"{Blockchain.Default.Height}/{Blockchain.Default.HeaderHeight}"; lbl_count_node.Text = Program.LocalNode.RemoteNodeCount.ToString(); TimeSpan persistence_span = DateTime.Now - persistence_time; if (persistence_span > Blockchain.TimePerBlock) { toolStripProgressBar1.Style = ProgressBarStyle.Marquee; } else { toolStripProgressBar1.Value = persistence_span.Seconds; toolStripProgressBar1.Style = ProgressBarStyle.Blocks; } if (Program.CurrentWallet?.WalletHeight > Blockchain.Default.Height + 1) { return; } if (balance_changed) { IEnumerable <Coin> coins = Program.CurrentWallet?.FindCoins() ?? Enumerable.Empty <Coin>(); var assets = coins.GroupBy(p => p.AssetId, (k, g) => new { Asset = (RegisterTransaction)Blockchain.Default.GetTransaction(k), Value = g.Sum(p => p.Value), Available = g.Where(p => p.State == CoinState.Unspent).Sum(p => p.Value) }).ToDictionary(p => p.Asset.Hash); foreach (RegisterTransaction tx in listView2.Items.OfType <ListViewItem>().Select(p => (RegisterTransaction)p.Tag).ToArray()) { if (!assets.ContainsKey(tx.Hash)) { listView2.Items.RemoveByKey(tx.Hash.ToString()); } } foreach (var asset in assets.Values) { if (listView2.Items.ContainsKey(asset.Asset.Hash.ToString())) { listView2.Items[asset.Asset.Hash.ToString()].SubItems["value"].Text = asset.Value.ToString(); } else { listView2.Items.Add(new ListViewItem(new[] { new ListViewItem.ListViewSubItem { Name = "name", Text = asset.Asset.GetName() }, new ListViewItem.ListViewSubItem { Name = "type", Text = asset.Asset.AssetType.ToString() }, new ListViewItem.ListViewSubItem { Name = "value", Text = asset.Value.ToString() }, new ListViewItem.ListViewSubItem { ForeColor = Color.Gray, Name = "issuer", Text = $"{Strings.UnknownIssuer}[{asset.Asset.Issuer}]" } }, -1, listView2.Groups["unchecked"]) { Name = asset.Asset.Hash.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"]; RegisterTransaction asset = (RegisterTransaction)item.Tag; byte[] cert_url_data = asset.Attributes.FirstOrDefault(p => p.Usage == TransactionAttributeUsage.CertUrl)?.Data; string cert_url = cert_url_data == null ? null : Encoding.UTF8.GetString(cert_url_data); using (CertificateQueryResult result = CertificateQueryService.Query(asset.Issuer, cert_url)) { switch (result.Type) { case CertificateQueryResultType.Querying: case CertificateQueryResultType.QueryFailed: break; case CertificateQueryResultType.System: subitem.ForeColor = Color.Green; subitem.Text = Strings.SystemIssuer; break; case CertificateQueryResultType.Invalid: subitem.ForeColor = Color.Red; subitem.Text = $"[{Strings.InvalidCertificate}][{asset.Issuer}]"; break; case CertificateQueryResultType.Expired: subitem.ForeColor = Color.Yellow; subitem.Text = $"[{Strings.ExpiredCertificate}]{result.Certificate.Subject}[{asset.Issuer}]"; break; case CertificateQueryResultType.Good: subitem.ForeColor = Color.Black; subitem.Text = $"{result.Certificate.Subject}[{asset.Issuer}]"; 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; } } } }
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 ? "NEO" : asset.Asset.AssetType == AssetType.UtilityToken ? "NeoGas" : 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 = $"{Strings.UnknownIssuer}[{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 = Strings.SystemIssuer; break; case CertificateQueryResultType.Invalid: subitem.ForeColor = Color.Red; subitem.Text = $"[{Strings.InvalidCertificate}][{asset.Owner}]"; break; case CertificateQueryResultType.Expired: subitem.ForeColor = Color.Yellow; subitem.Text = $"[{Strings.ExpiredCertificate}]{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; } } }
private void timer1_Tick(object sender, EventArgs e) { lbl_height.Text = $"{Blockchain.Default.Height}/{Blockchain.Default.HeaderHeight}"; lbl_count_node.Text = Program.LocalNode.RemoteNodeCount.ToString(); if (balance_changed) { IEnumerable <UnspentCoin> coins = Program.CurrentWallet == null?Enumerable.Empty <UnspentCoin>() : Program.CurrentWallet.FindUnspentCoins(); var assets = coins.GroupBy(p => p.AssetId, (k, g) => new { Asset = (RegisterTransaction)Blockchain.Default.GetTransaction(k), Value = g.Sum(p => p.Value) }).ToDictionary(p => p.Asset.Hash); foreach (RegisterTransaction tx in listView2.Items.OfType <ListViewItem>().Select(p => (RegisterTransaction)p.Tag).ToArray()) { if (!assets.ContainsKey(tx.Hash)) { listView2.Items.RemoveByKey(tx.Hash.ToString()); } } foreach (var asset in assets.Values) { if (listView2.Items.ContainsKey(asset.Asset.Hash.ToString())) { listView2.Items[asset.Asset.Hash.ToString()].SubItems["value"].Text = asset.Value.ToString(); } else { listView2.Items.Add(new ListViewItem(new[] { new ListViewItem.ListViewSubItem { Name = "name", Text = asset.Asset.GetName() }, new ListViewItem.ListViewSubItem { Name = "type", Text = asset.Asset.AssetType.ToString() }, new ListViewItem.ListViewSubItem { Name = "value", Text = asset.Value.ToString() }, new ListViewItem.ListViewSubItem { ForeColor = Color.Gray, Name = "issuer", Text = $"未知发行者[{asset.Asset.Issuer}]" } }, -1, listView2.Groups["unchecked"]) { Name = asset.Asset.Hash.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"]; RegisterTransaction asset = (RegisterTransaction)item.Tag; using (CertificateQueryResult result = CertificateQueryService.Query(asset.Issuer)) { switch (result.Type) { case CertificateQueryResultType.Querying: case CertificateQueryResultType.QueryFailed: break; case CertificateQueryResultType.System: subitem.ForeColor = Color.Green; subitem.Text = "小蚁系统"; break; case CertificateQueryResultType.Invalid: subitem.ForeColor = Color.Red; subitem.Text = $"[证书错误][{asset.Issuer}]"; break; case CertificateQueryResultType.Expired: subitem.ForeColor = Color.Yellow; subitem.Text = $"[证书已过期]{result.Certificate.Subject}[{asset.Issuer}]"; break; case CertificateQueryResultType.Good: subitem.ForeColor = Color.Green; subitem.Text = $"{result.Certificate.Subject}[{asset.Issuer}]"; 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; } } } }