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/src/neo/SmartContract/Native/StdLib.cs b/src/neo/SmartContract/Native/StdLib.cs
index 101c1deebd..a3d9238b99 100644
--- a/src/neo/SmartContract/Native/StdLib.cs
+++ b/src/neo/SmartContract/Native/StdLib.cs
@@ -142,6 +142,28 @@ public static byte[] Base58Decode([MaxLength(MaxInputLength)] string s)
return Base58.Decode(s);
}
+ ///
+ /// Converts a byte array to its equivalent representation that is encoded with base-58 digits. The encoded contains the checksum of the binary data.
+ ///
+ /// The byte array to be encoded.
+ /// The encoded .
+ [ContractMethod(CpuFee = 1 << 16)]
+ public static string Base58CheckEncode([MaxLength(MaxInputLength)] byte[] data)
+ {
+ return Base58.Base58CheckEncode(data);
+ }
+
+ ///
+ /// Converts the specified , which encodes binary data as base-58 digits, to an equivalent byte array. The encoded contains the checksum of the binary data.
+ ///
+ /// The base58 .
+ /// The decoded byte array.
+ [ContractMethod(CpuFee = 1 << 16)]
+ public static byte[] Base58CheckDecode([MaxLength(MaxInputLength)] string s)
+ {
+ return Base58.Base58CheckDecode(s);
+ }
+
[ContractMethod(CpuFee = 1 << 5)]
private static int MemoryCompare([MaxLength(MaxInputLength)] byte[] str1, [MaxLength(MaxInputLength)] byte[] str2)
{
diff --git a/src/neo/neo.csproj b/src/neo/neo.csproj
index e82346f782..da28b8d4e7 100644
--- a/src/neo/neo.csproj
+++ b/src/neo/neo.csproj
@@ -4,7 +4,7 @@
2015-2021 The Neo Project
Neo
3.0.0
- rc2
+ rc3
The Neo Project
net5.0
true
@@ -26,11 +26,11 @@
-
+
-
-
+
+
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);
+ }
}
}
diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_StdLib.cs b/tests/neo.UnitTests/SmartContract/Native/UT_StdLib.cs
index 787faed9b9..8879c828b5 100644
--- a/tests/neo.UnitTests/SmartContract/Native/UT_StdLib.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/UT_StdLib.cs
@@ -69,6 +69,60 @@ public void MemoryCompare()
}
}
+ [TestMethod]
+ public void CheckDecodeEncode()
+ {
+ var snapshot = TestBlockchain.GetTestSnapshot();
+
+ using (ScriptBuilder script = new())
+ {
+ script.EmitDynamicCall(NativeContract.StdLib.Hash, "base58CheckEncode", new byte[] { 1, 2, 3 });
+
+ using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings);
+ engine.LoadScript(script.ToArray());
+
+ Assert.AreEqual(engine.Execute(), VMState.HALT);
+ Assert.AreEqual(1, engine.ResultStack.Count);
+
+ Assert.AreEqual("3DUz7ncyT", engine.ResultStack.Pop().GetString());
+ }
+
+ using (ScriptBuilder script = new())
+ {
+ script.EmitDynamicCall(NativeContract.StdLib.Hash, "base58CheckDecode", "3DUz7ncyT");
+
+ using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings);
+ engine.LoadScript(script.ToArray());
+
+ Assert.AreEqual(engine.Execute(), VMState.HALT);
+ Assert.AreEqual(1, engine.ResultStack.Count);
+
+ CollectionAssert.AreEqual(new byte[] { 1, 2, 3 }, engine.ResultStack.Pop().GetSpan().ToArray());
+ }
+
+ // Error
+
+ using (ScriptBuilder script = new())
+ {
+ script.EmitDynamicCall(NativeContract.StdLib.Hash, "base58CheckDecode", "AA");
+
+ using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings);
+ engine.LoadScript(script.ToArray());
+
+ Assert.AreEqual(engine.Execute(), VMState.FAULT);
+ }
+
+ using (ScriptBuilder script = new())
+ {
+ script.EmitDynamicCall(NativeContract.StdLib.Hash, "base58CheckDecode", null);
+
+ using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings);
+ engine.LoadScript(script.ToArray());
+
+ Assert.AreEqual(engine.Execute(), VMState.FAULT);
+ }
+ }
+
[TestMethod]
public void MemorySearch()
{
diff --git a/tests/neo.UnitTests/neo.UnitTests.csproj b/tests/neo.UnitTests/neo.UnitTests.csproj
index 944d1c82ba..95623808df 100644
--- a/tests/neo.UnitTests/neo.UnitTests.csproj
+++ b/tests/neo.UnitTests/neo.UnitTests.csproj
@@ -9,8 +9,8 @@
-
-
+
+