From c5319171b331d79962af5f733f5b80f8a0c64316 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Thu, 12 Dec 2024 22:39:04 -0500 Subject: [PATCH] [Add] Get Accounts and Balances for GasToken (#3614) * [Add] Get Accounts and Balances for GasToken * Removed `BalanceOf` extension * Added null check * Changed `Seek` to `Find` for `DataCache` --------- Co-authored-by: Jimmy --- .../SmartContract/GasTokenExtensions.cs | 42 +++++++++++++++ src/Neo/SmartContract/Native/FungibleToken.cs | 2 +- .../Extensions/UT_GasTokenExtensions.cs | 53 +++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/Neo/Extensions/SmartContract/GasTokenExtensions.cs create mode 100644 tests/Neo.UnitTests/Extensions/UT_GasTokenExtensions.cs diff --git a/src/Neo/Extensions/SmartContract/GasTokenExtensions.cs b/src/Neo/Extensions/SmartContract/GasTokenExtensions.cs new file mode 100644 index 0000000000..07a1bcb2d9 --- /dev/null +++ b/src/Neo/Extensions/SmartContract/GasTokenExtensions.cs @@ -0,0 +1,42 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// GasTokenExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Neo.Persistence; +using Neo.SmartContract; +using Neo.SmartContract.Native; +using System; +using System.Collections.Generic; +using System.Numerics; + +namespace Neo.Extensions +{ + public static class GasTokenExtensions + { + public static IEnumerable<(UInt160 Address, BigInteger Balance)> GetAccounts(this GasToken gasToken, DataCache snapshot) + { + if (gasToken is null) + throw new ArgumentNullException(nameof(gasToken)); + + if (snapshot is null) + throw new ArgumentNullException(nameof(snapshot)); + + var kb = new KeyBuilder(gasToken.Id, GasToken.Prefix_Account); + var prefixKey = kb.ToArray(); + + foreach (var (key, value) in snapshot.Find(prefixKey, SeekDirection.Forward)) + { + var keyBytes = key.ToArray(); + var addressHash = new UInt160(keyBytes.AsSpan(prefixKey.Length)); + yield return new(addressHash, value.GetInteroperable().Balance); + } + } + } +} diff --git a/src/Neo/SmartContract/Native/FungibleToken.cs b/src/Neo/SmartContract/Native/FungibleToken.cs index ab6ed8f9c0..2175f43dfd 100644 --- a/src/Neo/SmartContract/Native/FungibleToken.cs +++ b/src/Neo/SmartContract/Native/FungibleToken.cs @@ -51,7 +51,7 @@ public abstract class FungibleToken : NativeContract /// /// The prefix for storing account states. /// - protected const byte Prefix_Account = 20; + protected internal const byte Prefix_Account = 20; /// /// Initializes a new instance of the class. diff --git a/tests/Neo.UnitTests/Extensions/UT_GasTokenExtensions.cs b/tests/Neo.UnitTests/Extensions/UT_GasTokenExtensions.cs new file mode 100644 index 0000000000..9b13312eb6 --- /dev/null +++ b/tests/Neo.UnitTests/Extensions/UT_GasTokenExtensions.cs @@ -0,0 +1,53 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// UT_GasTokenExtensions.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Extensions; +using Neo.SmartContract.Native; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace Neo.UnitTests.Extensions +{ + [TestClass] + public class UT_GasTokenExtensions + { + private NeoSystem system; + + [TestInitialize] + public void Initialize() + { + system = TestBlockchain.TheNeoSystem; + } + + [TestCleanup] + public void Clean() + { + TestBlockchain.ResetStore(); + } + + [TestMethod] + public void TestGetAccounts() + { + UInt160 expected = "0x9f8f056a53e39585c7bb52886418c7bed83d126b"; + + var accounts = NativeContract.GAS.GetAccounts(system.StoreView); + var actual = accounts.FirstOrDefault(); + + Assert.AreEqual(expected, actual.Address); + Assert.AreEqual(5200000000000000, actual.Balance); + } + } +}