diff --git a/src/neo/SmartContract/Native/NeoToken.cs b/src/neo/SmartContract/Native/NeoToken.cs index 32c10a18ac..3ec0b35958 100644 --- a/src/neo/SmartContract/Native/NeoToken.cs +++ b/src/neo/SmartContract/Native/NeoToken.cs @@ -348,6 +348,18 @@ public ECPoint[] GetCommittee(DataCache snapshot) return GetCommitteeFromCache(snapshot).Select(p => p.PublicKey).OrderBy(p => p).ToArray(); } + /// + /// Get account state. + /// + /// The snapshot used to read data. + /// account + /// The state of the account. + [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] + public NeoAccountState GetAccountState(DataCache snapshot, UInt160 account) + { + return snapshot.TryGet(CreateStorageKey(Prefix_Account).Add(account))?.GetInteroperable(); + } + /// /// Gets the address of the committee. /// diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_NeoToken.cs b/tests/neo.UnitTests/SmartContract/Native/UT_NeoToken.cs index 3789cc02ff..d80cb735c5 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_NeoToken.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_NeoToken.cs @@ -375,6 +375,12 @@ public void Check_Transfer() NativeContract.NEO.BalanceOf(snapshot, from).Should().Be(99999999); NativeContract.NEO.BalanceOf(snapshot, to).Should().Be(1); + var (from_balance, _, _) = GetAccountState(snapshot, new UInt160(from)); + var (to_balance, _, _) = GetAccountState(snapshot, new UInt160(to)); + + from_balance.Should().Be(99999999); + to_balance.Should().Be(1); + // Check unclaim unclaim = Check_UnclaimedGas(snapshot, from, persistingBlock); @@ -853,6 +859,9 @@ public void TestVote() ret.State.Should().BeTrue(); ret.Result.Should().BeFalse(); + var (_, _, vote_to_null) = GetAccountState(snapshot, account); + vote_to_null.Should().BeNull(); + snapshot.Delete(keyAccount); snapshot.GetAndChange(keyAccount, () => new StorageItem(new NeoAccountState { @@ -862,6 +871,9 @@ public void TestVote() ret = Check_Vote(snapshot, account.ToArray(), ECCurve.Secp256r1.G.ToArray(), true, _persistingBlock); ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); + + var (_, _, voteto) = GetAccountState(snapshot, account); + voteto.ToHexString().Should().Be(ECCurve.Secp256r1.G.ToArray().ToHexString()); } internal (bool State, bool Result) Transfer4TesingOnBalanceChanging(BigInteger amount, bool addVotes) @@ -1080,5 +1092,25 @@ internal static (bool State, bool Result) Check_UnregisterCandidate(DataCache sn return (true, result.GetBoolean()); } + + internal static (BigInteger balance, BigInteger height, byte[] voteto) GetAccountState(DataCache snapshot, UInt160 account) + { + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings); + + using var script = new ScriptBuilder(); + script.EmitDynamicCall(NativeContract.NEO.Hash, "getAccountState", account); + engine.LoadScript(script.ToArray()); + + engine.Execute().Should().Be(VMState.HALT); + + var result = engine.ResultStack.Pop(); + result.Should().BeOfType(typeof(VM.Types.Struct)); + + VM.Types.Struct state = (result as VM.Types.Struct); + var balance = state[0].GetInteger(); + var height = state[1].GetInteger(); + var voteto = state[2].IsNull ? null : state[2].GetSpan().ToArray(); + return (balance, height, voteto); + } } }