From 1abdbdfdb725b41ccefad963b816c985647fab9b Mon Sep 17 00:00:00 2001 From: erikzhang Date: Thu, 9 Jul 2020 20:27:05 +0800 Subject: [PATCH] Fix native contracts --- src/neo/Ledger/ContractState.cs | 2 +- .../Manifest/ContractManifest.cs | 11 +++++++-- .../SmartContract/Native/NativeContract.cs | 13 +++++------ .../SmartContract/Native/Tokens/Nep5Token.cs | 2 +- .../Nep5NativeContractExtensions.cs | 23 ------------------- .../neo.UnitTests/Ledger/UT_ContractState.cs | 2 +- .../Manifest/UT_ContractManifest.cs | 16 ++++++------- .../Native/Tokens/UT_GasToken.cs | 3 --- .../Native/Tokens/UT_NeoToken.cs | 3 --- .../SmartContract/Native/UT_PolicyContract.cs | 3 --- tests/neo.UnitTests/TestUtils.cs | 11 +++++---- 11 files changed, 32 insertions(+), 57 deletions(-) diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs index 41fee022e0..882abb4e2e 100644 --- a/src/neo/Ledger/ContractState.cs +++ b/src/neo/Ledger/ContractState.cs @@ -32,7 +32,7 @@ public UInt160 ScriptHash } } - int ISerializable.Size => sizeof(int) + Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize(); + int ISerializable.Size => sizeof(int) + Script.GetVarSize() + Manifest.Size; ContractState ICloneable.Clone() { diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs index 65fefddae3..990a400929 100644 --- a/src/neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/neo/SmartContract/Manifest/ContractManifest.cs @@ -20,7 +20,14 @@ public class ContractManifest : ISerializable /// /// Serialized size /// - public int Size => ToJson().ToString().GetVarSize(); + public int Size + { + get + { + int size = Utility.StrictUTF8.GetByteCount(ToString()); + return IO.Helper.GetVarSize(size) + size; + } + } /// /// Contract hash @@ -150,7 +157,7 @@ public ContractManifest Clone() public void Serialize(BinaryWriter writer) { - writer.WriteVarString(ToJson().ToString()); + writer.WriteVarString(ToString()); } public void Deserialize(BinaryReader reader) diff --git a/src/neo/SmartContract/Native/NativeContract.cs b/src/neo/SmartContract/Native/NativeContract.cs index 0f86ce91ba..217c4c9091 100644 --- a/src/neo/SmartContract/Native/NativeContract.cs +++ b/src/neo/SmartContract/Native/NativeContract.cs @@ -30,8 +30,6 @@ public abstract class NativeContract public UInt160 Hash { get; } public abstract int Id { get; } public ContractManifest Manifest { get; } - [ContractMethod(0, CallFlags.None)] - public virtual string[] SupportedStandards { get; } = { "NEP-10" }; protected NativeContract() { @@ -60,18 +58,19 @@ protected NativeContract() } this.Manifest = new ContractManifest { - Permissions = new[] { ContractPermission.DefaultPermission }, + Groups = System.Array.Empty(), + Features = ContractFeatures.NoProperty, + SupportedStandards = new string[0], Abi = new ContractAbi() { Hash = Hash, Events = System.Array.Empty(), Methods = descriptors.ToArray() }, - Features = ContractFeatures.NoProperty, - Groups = System.Array.Empty(), - SafeMethods = WildcardContainer.Create(safeMethods.ToArray()), + Permissions = new[] { ContractPermission.DefaultPermission }, Trusts = WildcardContainer.Create(), - Extra = null, + SafeMethods = WildcardContainer.Create(safeMethods.ToArray()), + Extra = null }; contractsList.Add(this); contractsNameDictionary.Add(Name, this); diff --git a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs index 6e7598ab70..111b69d4ce 100644 --- a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs +++ b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs @@ -13,7 +13,6 @@ namespace Neo.SmartContract.Native.Tokens public abstract class Nep5Token : NativeContract where TState : AccountState, new() { - public override string[] SupportedStandards { get; } = { "NEP-5", "NEP-10" }; [ContractMethod(0, CallFlags.None)] public abstract string Symbol { get; } [ContractMethod(0, CallFlags.None)] @@ -28,6 +27,7 @@ protected Nep5Token() this.Factor = BigInteger.Pow(10, Decimals); Manifest.Features = ContractFeatures.HasStorage; + Manifest.SupportedStandards = new[] { "NEP-5" }; var events = new List(Manifest.Abi.Events) { diff --git a/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs b/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs index e3a5fc9adf..0053b4e929 100644 --- a/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs +++ b/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs @@ -6,7 +6,6 @@ using Neo.VM; using System; using System.IO; -using System.Linq; using System.Numerics; namespace Neo.UnitTests.Extensions @@ -68,28 +67,6 @@ public static bool Transfer(this NativeContract contract, StoreView snapshot, by return result.GetBoolean(); } - public static string[] SupportedStandards(this NativeContract contract) - { - var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, testMode: true); - - engine.LoadScript(contract.Script); - - var script = new ScriptBuilder(); - script.EmitPush(0); - script.Emit(OpCode.PACK); - script.EmitPush("supportedStandards"); - engine.LoadScript(script.ToArray()); - - engine.Execute().Should().Be(VMState.HALT); - - var result = engine.ResultStack.Pop(); - result.Should().BeOfType(typeof(VM.Types.Array)); - - return (result as VM.Types.Array).ToArray() - .Select(u => u.GetString()) - .ToArray(); - } - public static BigInteger TotalSupply(this NativeContract contract, StoreView snapshot) { var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true); diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index 40e4a6a23d..76c48c4c3e 100644 --- a/tests/neo.UnitTests/Ledger/UT_ContractState.cs +++ b/tests/neo.UnitTests/Ledger/UT_ContractState.cs @@ -84,7 +84,7 @@ public void TestDeserialize() public void TestGetSize() { ISerializable newContract = contract; - newContract.Size.Should().Be(239); + newContract.Size.Should().Be(265); } [TestMethod] diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index ef2df0acff..fbd8e10f4e 100644 --- a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -11,7 +11,7 @@ public class UT_ContractManifest [TestMethod] public void ParseFromJson_Default() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -22,7 +22,7 @@ public void ParseFromJson_Default() [TestMethod] public void ParseFromJson_Features() { - var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}"; + var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToJson().ToString(), json); @@ -34,7 +34,7 @@ public void ParseFromJson_Features() [TestMethod] public void ParseFromJson_Permissions() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safemethods"":[],""extra"":null}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safemethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -53,7 +53,7 @@ public void ParseFromJson_Permissions() [TestMethod] public void ParseFromJson_SafeMethods() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[""balanceOf""],""extra"":null}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[""balanceOf""],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -65,7 +65,7 @@ public void ParseFromJson_SafeMethods() [TestMethod] public void ParseFromJson_Trust() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safemethods"":[],""extra"":null}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safemethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -77,7 +77,7 @@ public void ParseFromJson_Trust() [TestMethod] public void ParseFromJson_Groups() { - var json = @"{""groups"":[{""pubkey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}"; + var json = @"{""groups"":[{""pubkey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -89,7 +89,7 @@ public void ParseFromJson_Groups() [TestMethod] public void ParseFromJson_Extra() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":{""key"":""value""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":{""key"":""value""}}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(json, json); Assert.AreEqual("value", manifest.Extra["key"].AsString(), false); @@ -122,7 +122,7 @@ public void TestGetHash() public void TestGetSize() { var temp = TestUtils.CreateDefaultManifest(UInt160.Zero); - Assert.AreEqual(233, temp.Size); + Assert.AreEqual(259, temp.Size); } [TestMethod] diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs index e2910ae1e5..f1d10853b0 100644 --- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs +++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs @@ -31,9 +31,6 @@ public void TestSetup() [TestMethod] public void Check_Decimals() => NativeContract.GAS.Decimals().Should().Be(8); - [TestMethod] - public void Check_SupportedStandards() => NativeContract.GAS.SupportedStandards().Should().BeEquivalentTo(new string[] { "NEP-5", "NEP-10" }); - [TestMethod] public void Check_BalanceOfTransferAndBurn() { diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs index dafb1f9a72..02e9cba21a 100644 --- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs +++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs @@ -36,9 +36,6 @@ public void TestSetup() [TestMethod] public void Check_Decimals() => NativeContract.NEO.Decimals().Should().Be(0); - [TestMethod] - public void Check_SupportedStandards() => NativeContract.NEO.SupportedStandards().Should().BeEquivalentTo(new string[] { "NEP-5", "NEP-10" }); - [TestMethod] public void Check_Vote() { diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index a33b209a12..ac3b1dd2e9 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -19,9 +19,6 @@ public void TestSetup() TestBlockchain.InitializeMockNeoSystem(); } - [TestMethod] - public void Check_SupportedStandards() => NativeContract.Policy.SupportedStandards().Should().BeEquivalentTo(new string[] { "NEP-10" }); - [TestMethod] public void Check_Initialize() { diff --git a/tests/neo.UnitTests/TestUtils.cs b/tests/neo.UnitTests/TestUtils.cs index adaf205ea1..3edc590dae 100644 --- a/tests/neo.UnitTests/TestUtils.cs +++ b/tests/neo.UnitTests/TestUtils.cs @@ -22,18 +22,19 @@ public static ContractManifest CreateDefaultManifest(UInt160 hash) { return new ContractManifest() { - Permissions = new[] { ContractPermission.DefaultPermission }, + Groups = new ContractGroup[0], + Features = ContractFeatures.NoProperty, + SupportedStandards = Array.Empty(), Abi = new ContractAbi() { Hash = hash, Events = new ContractEventDescriptor[0], Methods = new ContractMethodDescriptor[0] }, - Features = ContractFeatures.NoProperty, - Groups = new ContractGroup[0], - SafeMethods = WildcardContainer.Create(), + Permissions = new[] { ContractPermission.DefaultPermission }, Trusts = WildcardContainer.Create(), - Extra = null, + SafeMethods = WildcardContainer.Create(), + Extra = null }; }