From 6883383de418b9ab563aa78c7ac38e74f6cbbcb2 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 15 Nov 2019 06:39:24 -0300 Subject: [PATCH 01/18] Adding neo 2 metadata --- .../Manifest/ContractContactInformation.cs | 31 +++++++++++++++++++ .../Manifest/ContractManifest.cs | 11 +++++-- .../neo.UnitTests/Ledger/UT_ContractState.cs | 2 +- .../Manifest/UT_ContractManifest.cs | 27 +++++++++++----- 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 neo/SmartContract/Manifest/ContractContactInformation.cs diff --git a/neo/SmartContract/Manifest/ContractContactInformation.cs b/neo/SmartContract/Manifest/ContractContactInformation.cs new file mode 100644 index 0000000000..92c8e02a4d --- /dev/null +++ b/neo/SmartContract/Manifest/ContractContactInformation.cs @@ -0,0 +1,31 @@ +using Neo.IO.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Neo.SmartContract.Manifest +{ + public class ContractContactInformation + { + public string Author { get; set; } = ""; + + public string Email { get; set; } = ""; + + public static ContractContactInformation FromJson(JObject jsonObject) + { + return jsonObject != null ? new ContractContactInformation + { + Author = jsonObject["author"]?.AsString(), + Email = jsonObject["email"]?.AsString(), + } : new ContractContactInformation(); + } + + public JObject ToJson() + { + var json = new JObject(); + json["author"] = Author; + json["email"] = Email; + return json; + } + } +} diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs index c376af7d00..6744dee28a 100644 --- a/src/neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/neo/SmartContract/Manifest/ContractManifest.cs @@ -41,6 +41,11 @@ public class ContractManifest : ISerializable /// public ContractAbi Abi { get; set; } + /// + /// Contract details including author and contact email. + /// + public ContractContactInformation Contact { get; set; } + /// /// The permissions field is an array containing a set of Permission objects. It describes which contracts may be invoked and which methods are called. /// @@ -78,7 +83,8 @@ public static ContractManifest CreateDefault(UInt160 hash) Features = ContractFeatures.NoProperty, Groups = new ContractGroup[0], SafeMethods = WildCardContainer.Create(), - Trusts = WildCardContainer.Create() + Trusts = WildCardContainer.Create(), + Contact = new ContractContactInformation(), }; } @@ -128,6 +134,7 @@ public JObject ToJson() json["permissions"] = Permissions.Select(p => p.ToJson()).ToArray(); json["trusts"] = Trusts.ToJson(); json["safeMethods"] = SafeMethods.ToJson(); + json["contact"] = Contact.ToJson(); return json; } @@ -173,7 +180,7 @@ private void DeserializeFromJson(JObject json) Permissions = ((JArray)json["permissions"]).Select(u => ContractPermission.FromJson(u)).ToArray(); Trusts = WildCardContainer.FromJson(json["trusts"], u => UInt160.Parse(u.AsString())); SafeMethods = WildCardContainer.FromJson(json["safeMethods"], u => u.AsString()); - + Contact = ContractContactInformation.FromJson(json["contact"]); if (json["features"]["storage"].AsBoolean()) Features |= ContractFeatures.HasStorage; if (json["features"]["payable"].AsBoolean()) Features |= ContractFeatures.Payable; } diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index 097e9c3e04..6fd90d7cc5 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(355); + newContract.Size.Should().Be(390); } [TestMethod] diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 2416c60bd5..6a9bce51e1 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[]}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[]}"; + var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[]}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""]}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""],""contact"":{""author"":"""",""email"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[]}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[]}"; + var json = @"{""groups"":[{""pubKey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -86,6 +86,19 @@ public void ParseFromJson_Groups() Assert.AreEqual(manifest.ToString(), check.ToString()); } + [TestMethod] + public void ParseFromJson_Details() + { + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":""author"",""email"":""email""}}"; + var manifest = ContractManifest.Parse(json); + var manifestString = manifest.ToString(); + + Assert.AreEqual(manifestString, json); + + } + + + [TestMethod] public void TestDeserializeAndSerialize() { @@ -113,7 +126,7 @@ public void TestGetHash() public void TestGetSize() { var temp = ContractManifest.CreateDefault(UInt160.Zero); - Assert.AreEqual(353, temp.Size); + Assert.AreEqual(388, temp.Size); } [TestMethod] From a7eb011e52f8be25679dbc1cbf1f5d3b307b3388 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 15 Nov 2019 06:46:47 -0300 Subject: [PATCH 02/18] Double check --- .../SmartContract/Manifest/UT_ContractManifest.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 6a9bce51e1..65f7f4c0af 100644 --- a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -87,18 +87,17 @@ public void ParseFromJson_Groups() } [TestMethod] - public void ParseFromJson_Details() + public void ParseFromJson_Contacts() { var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":""author"",""email"":""email""}}"; var manifest = ContractManifest.Parse(json); var manifestString = manifest.ToString(); Assert.AreEqual(manifestString, json); - + Assert.AreEqual("author", manifest.Contact.Author); + Assert.AreEqual("email", manifest.Contact.Email); } - - [TestMethod] public void TestDeserializeAndSerialize() { From 7002452bc67e70d209aa4d4c0cc4660d2b49443a Mon Sep 17 00:00:00 2001 From: Ricardo Date: Mon, 18 Nov 2019 15:32:32 -0300 Subject: [PATCH 03/18] Adding website and description --- neo/SmartContract/Manifest/ContractContactInformation.cs | 8 ++++++++ .../SmartContract/Manifest/UT_ContractManifest.cs | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/neo/SmartContract/Manifest/ContractContactInformation.cs b/neo/SmartContract/Manifest/ContractContactInformation.cs index 92c8e02a4d..9257e673f7 100644 --- a/neo/SmartContract/Manifest/ContractContactInformation.cs +++ b/neo/SmartContract/Manifest/ContractContactInformation.cs @@ -11,12 +11,18 @@ public class ContractContactInformation public string Email { get; set; } = ""; + public string Description { get; set; } = ""; + + public string Website { get; set; } = ""; + public static ContractContactInformation FromJson(JObject jsonObject) { return jsonObject != null ? new ContractContactInformation { Author = jsonObject["author"]?.AsString(), Email = jsonObject["email"]?.AsString(), + Description = jsonObject["description"]?.AsString(), + Website = jsonObject["website"]?.AsString(), } : new ContractContactInformation(); } @@ -25,6 +31,8 @@ public JObject ToJson() var json = new JObject(); json["author"] = Author; json["email"] = Email; + json["description"] = Description; + json["website"] = Website; return json; } } diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 65f7f4c0af..4ffb7140da 100644 --- a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -89,13 +89,15 @@ public void ParseFromJson_Groups() [TestMethod] public void ParseFromJson_Contacts() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":""author"",""email"":""email""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":""author"",""email"":""email"",""description"":""description"",""website"":""website""}}"; var manifest = ContractManifest.Parse(json); var manifestString = manifest.ToString(); Assert.AreEqual(manifestString, json); Assert.AreEqual("author", manifest.Contact.Author); Assert.AreEqual("email", manifest.Contact.Email); + Assert.AreEqual("description", manifest.Contact.Description); + Assert.AreEqual("website", manifest.Contact.Website); } [TestMethod] From e2b2605b6e25a046839004cbfc52f0718271258e Mon Sep 17 00:00:00 2001 From: Ricardo Date: Mon, 18 Nov 2019 16:39:43 -0300 Subject: [PATCH 04/18] Solution tests --- tests/neo.UnitTests/Ledger/UT_ContractState.cs | 2 +- .../SmartContract/Manifest/UT_ContractManifest.cs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index 6fd90d7cc5..e068a3c809 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(390); + newContract.Size.Should().Be(420); } [TestMethod] diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 4ffb7140da..0d229a704f 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""],""contact"":{""author"":"""",""email"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; 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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":""""}}"; + var json = @"{""groups"":[{""pubKey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -127,7 +127,7 @@ public void TestGetHash() public void TestGetSize() { var temp = ContractManifest.CreateDefault(UInt160.Zero); - Assert.AreEqual(388, temp.Size); + Assert.AreEqual(418, temp.Size); } [TestMethod] From 16e937793cd26ad31dddcbe1bdb8bb68251180fe Mon Sep 17 00:00:00 2001 From: Ricardo Date: Mon, 18 Nov 2019 16:53:41 -0300 Subject: [PATCH 05/18] Dotnet format --- src/neo/SmartContract/Manifest/ContractManifest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs index 6744dee28a..8b317967ff 100644 --- a/src/neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/neo/SmartContract/Manifest/ContractManifest.cs @@ -45,7 +45,7 @@ public class ContractManifest : ISerializable /// Contract details including author and contact email. /// public ContractContactInformation Contact { get; set; } - + /// /// The permissions field is an array containing a set of Permission objects. It describes which contracts may be invoked and which methods are called. /// From e2a098ccb57a10026ed77f45646865232c081097 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Mon, 2 Dec 2019 11:54:51 -0300 Subject: [PATCH 06/18] Using generic extra object --- neo.UnitTests/Ledger/ECPointOld.cs | 6 +++ .../Manifest/ContractContactInformation.cs | 39 ------------------- .../Manifest/ContractManifest.cs | 29 +++++++------- .../Manifest/ContractPermission.cs | 6 +-- .../Manifest/WildCardContainer.cs | 10 ++--- .../SmartContract/Native/NativeContract.cs | 2 +- .../neo.UnitTests/Ledger/UT_ContractState.cs | 2 +- .../Manifest/UT_ContractManifest.cs | 38 ++++++++---------- .../Manifest/UT_WildCardContainer.cs | 20 +++++----- .../SmartContract/UT_InteropService.cs | 4 +- 10 files changed, 60 insertions(+), 96 deletions(-) create mode 100644 neo.UnitTests/Ledger/ECPointOld.cs delete mode 100644 neo/SmartContract/Manifest/ContractContactInformation.cs diff --git a/neo.UnitTests/Ledger/ECPointOld.cs b/neo.UnitTests/Ledger/ECPointOld.cs new file mode 100644 index 0000000000..27c2ee2b89 --- /dev/null +++ b/neo.UnitTests/Ledger/ECPointOld.cs @@ -0,0 +1,6 @@ +namespace Neo.UnitTests.Ledger +{ + internal class ECPointOld + { + } +} \ No newline at end of file diff --git a/neo/SmartContract/Manifest/ContractContactInformation.cs b/neo/SmartContract/Manifest/ContractContactInformation.cs deleted file mode 100644 index 9257e673f7..0000000000 --- a/neo/SmartContract/Manifest/ContractContactInformation.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Neo.IO.Json; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Neo.SmartContract.Manifest -{ - public class ContractContactInformation - { - public string Author { get; set; } = ""; - - public string Email { get; set; } = ""; - - public string Description { get; set; } = ""; - - public string Website { get; set; } = ""; - - public static ContractContactInformation FromJson(JObject jsonObject) - { - return jsonObject != null ? new ContractContactInformation - { - Author = jsonObject["author"]?.AsString(), - Email = jsonObject["email"]?.AsString(), - Description = jsonObject["description"]?.AsString(), - Website = jsonObject["website"]?.AsString(), - } : new ContractContactInformation(); - } - - public JObject ToJson() - { - var json = new JObject(); - json["author"] = Author; - json["email"] = Email; - json["description"] = Description; - json["website"] = Website; - return json; - } - } -} diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs index 8b317967ff..cc48fdbae4 100644 --- a/src/neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/neo/SmartContract/Manifest/ContractManifest.cs @@ -1,5 +1,6 @@ using Neo.IO; using Neo.IO.Json; +using System.Collections.Generic; using System.IO; using System.Linq; @@ -41,11 +42,6 @@ public class ContractManifest : ISerializable /// public ContractAbi Abi { get; set; } - /// - /// Contract details including author and contact email. - /// - public ContractContactInformation Contact { get; set; } - /// /// The permissions field is an array containing a set of Permission objects. It describes which contracts may be invoked and which methods are called. /// @@ -55,13 +51,18 @@ public class ContractManifest : ISerializable /// The trusts field is an array containing a set of contract hashes or group public keys. It can also be assigned with a wildcard *. If it is a wildcard *, then it means that it trusts any contract. /// If a contract is trusted, the user interface will not give any warnings when called by the contract. /// - public WildCardContainer Trusts { get; set; } + public WildcardContainer Trusts { get; set; } /// /// The safemethods field is an array containing a set of method names. It can also be assigned with a wildcard *. If it is a wildcard *, then it means that all methods of the contract are safe. /// If a method is marked as safe, the user interface will not give any warnings when it is called by any other contract. /// - public WildCardContainer SafeMethods { get; set; } + public WildcardContainer SafeMethods { get; set; } + + /// + /// Custom user data + /// + public JObject Extra { get; set; } /// /// Create Default Contract manifest @@ -82,9 +83,9 @@ public static ContractManifest CreateDefault(UInt160 hash) }, Features = ContractFeatures.NoProperty, Groups = new ContractGroup[0], - SafeMethods = WildCardContainer.Create(), - Trusts = WildCardContainer.Create(), - Contact = new ContractContactInformation(), + SafeMethods = WildcardContainer.Create(), + Trusts = WildcardContainer.Create(), + Extra = new JObject(), }; } @@ -134,7 +135,7 @@ public JObject ToJson() json["permissions"] = Permissions.Select(p => p.ToJson()).ToArray(); json["trusts"] = Trusts.ToJson(); json["safeMethods"] = SafeMethods.ToJson(); - json["contact"] = Contact.ToJson(); + json["extra"] = Extra; return json; } @@ -178,9 +179,9 @@ private void DeserializeFromJson(JObject json) Groups = ((JArray)json["groups"]).Select(u => ContractGroup.FromJson(u)).ToArray(); Features = ContractFeatures.NoProperty; Permissions = ((JArray)json["permissions"]).Select(u => ContractPermission.FromJson(u)).ToArray(); - Trusts = WildCardContainer.FromJson(json["trusts"], u => UInt160.Parse(u.AsString())); - SafeMethods = WildCardContainer.FromJson(json["safeMethods"], u => u.AsString()); - Contact = ContractContactInformation.FromJson(json["contact"]); + Trusts = WildcardContainer.FromJson(json["trusts"], u => UInt160.Parse(u.AsString())); + SafeMethods = WildcardContainer.FromJson(json["safeMethods"], u => u.AsString()); + Extra = JObject.Parse(json["extra"].AsString()); if (json["features"]["storage"].AsBoolean()) Features |= ContractFeatures.HasStorage; if (json["features"]["payable"].AsBoolean()) Features |= ContractFeatures.Payable; } diff --git a/src/neo/SmartContract/Manifest/ContractPermission.cs b/src/neo/SmartContract/Manifest/ContractPermission.cs index ab86157786..f4084eaf0f 100644 --- a/src/neo/SmartContract/Manifest/ContractPermission.cs +++ b/src/neo/SmartContract/Manifest/ContractPermission.cs @@ -19,12 +19,12 @@ public class ContractPermission /// The methods field is an array containing a set of methods to be called. It can also be assigned with a wildcard *. If it is a wildcard *, then it means that any method can be called. /// If a contract invokes a contract or method that is not declared in the manifest at runtime, the invocation will fail. /// - public WildCardContainer Methods { get; set; } + public WildcardContainer Methods { get; set; } public static readonly ContractPermission DefaultPermission = new ContractPermission { Contract = ContractPermissionDescriptor.CreateWildcard(), - Methods = WildCardContainer.CreateWildcard() + Methods = WildcardContainer.CreateWildcard() }; public ContractPermission Clone() @@ -46,7 +46,7 @@ public static ContractPermission FromJson(JObject json) return new ContractPermission { Contract = ContractPermissionDescriptor.FromJson(json["contract"]), - Methods = WildCardContainer.FromJson(json["methods"], u => u.AsString()), + Methods = WildcardContainer.FromJson(json["methods"], u => u.AsString()), }; } diff --git a/src/neo/SmartContract/Manifest/WildCardContainer.cs b/src/neo/SmartContract/Manifest/WildCardContainer.cs index 12dbac60fe..d85f23fbd8 100644 --- a/src/neo/SmartContract/Manifest/WildCardContainer.cs +++ b/src/neo/SmartContract/Manifest/WildCardContainer.cs @@ -6,7 +6,7 @@ namespace Neo.SmartContract.Manifest { - public class WildCardContainer : IReadOnlyList + public class WildcardContainer : IReadOnlyList { private readonly T[] _data; @@ -26,7 +26,7 @@ public class WildCardContainer : IReadOnlyList /// Constructor /// /// Data - private WildCardContainer(T[] data) + private WildcardContainer(T[] data) { _data = data; } @@ -36,15 +36,15 @@ private WildCardContainer(T[] data) /// /// Data /// WildCardContainer - public static WildCardContainer Create(params T[] data) => new WildCardContainer(data); + public static WildcardContainer Create(params T[] data) => new WildcardContainer(data); /// /// Create a wildcard /// /// WildCardContainer - public static WildCardContainer CreateWildcard() => new WildCardContainer(null); + public static WildcardContainer CreateWildcard() => new WildcardContainer(null); - public static WildCardContainer FromJson(JObject json, Func elementSelector) + public static WildcardContainer FromJson(JObject json, Func elementSelector) { switch (json) { diff --git a/src/neo/SmartContract/Native/NativeContract.cs b/src/neo/SmartContract/Native/NativeContract.cs index 80edebd11b..cb2863fda2 100644 --- a/src/neo/SmartContract/Native/NativeContract.cs +++ b/src/neo/SmartContract/Native/NativeContract.cs @@ -62,7 +62,7 @@ protected NativeContract() }); } this.Manifest.Abi.Methods = descriptors.ToArray(); - this.Manifest.SafeMethods = WildCardContainer.Create(safeMethods.ToArray()); + this.Manifest.SafeMethods = WildcardContainer.Create(safeMethods.ToArray()); contracts.Add(this); } diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index e068a3c809..dbd0d7653a 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(420); + newContract.Size.Should().Be(366); } [TestMethod] diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 0d229a704f..870df2f7c8 100644 --- a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -1,5 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.IO.Json; using Neo.SmartContract.Manifest; using System.IO; @@ -11,7 +12,7 @@ public class UT_ContractManifest [TestMethod] public void ParseFromJson_Default() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{}}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -22,7 +23,7 @@ public void ParseFromJson_Default() [TestMethod] public void ParseFromJson_Features() { - var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{}}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToJson().ToString(), json); @@ -34,7 +35,7 @@ public void ParseFromJson_Features() [TestMethod] public void ParseFromJson_Permissions() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[],""extra"":{}}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -44,7 +45,7 @@ public void ParseFromJson_Permissions() new ContractPermission() { Contract = ContractPermissionDescriptor.Create(UInt160.Zero), - Methods = WildCardContainer.Create("method1", "method2") + Methods = WildcardContainer.Create("method1", "method2") } }; Assert.AreEqual(manifest.ToString(), check.ToString()); @@ -53,31 +54,31 @@ public void ParseFromJson_Permissions() [TestMethod] public void ParseFromJson_SafeMethods() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""],""extra"":{}}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); var check = ContractManifest.CreateDefault(UInt160.Zero); - check.SafeMethods = WildCardContainer.Create("balanceOf"); + check.SafeMethods = WildcardContainer.Create("balanceOf"); Assert.AreEqual(manifest.ToString(), check.ToString()); } [TestMethod] public void ParseFromJson_Trust() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[],""extra"":{}}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); var check = ContractManifest.CreateDefault(UInt160.Zero); - check.Trusts = WildCardContainer.Create(UInt160.Parse("0x0000000000000000000000000000000000000001")); + check.Trusts = WildcardContainer.Create(UInt160.Parse("0x0000000000000000000000000000000000000001")); Assert.AreEqual(manifest.ToString(), check.ToString()); } [TestMethod] public void ParseFromJson_Groups() { - var json = @"{""groups"":[{""pubKey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":"""",""email"":"""",""description"":"""",""website"":""""}}"; + var json = @"{""groups"":[{""pubKey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{}}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -89,15 +90,10 @@ public void ParseFromJson_Groups() [TestMethod] public void ParseFromJson_Contacts() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""contact"":{""author"":""author"",""email"":""email"",""description"":""description"",""website"":""website""}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{""key"":""value""}}"; var manifest = ContractManifest.Parse(json); - var manifestString = manifest.ToString(); - - Assert.AreEqual(manifestString, json); - Assert.AreEqual("author", manifest.Contact.Author); - Assert.AreEqual("email", manifest.Contact.Email); - Assert.AreEqual("description", manifest.Contact.Description); - Assert.AreEqual("website", manifest.Contact.Website); + Assert.AreEqual(json, json); + Assert.AreEqual("value", manifest.Extra["key"].AsString(), false); } [TestMethod] @@ -107,7 +103,7 @@ public void TestDeserializeAndSerialize() BinaryWriter writer = new BinaryWriter(stream); BinaryReader reader = new BinaryReader(stream); var expected = ContractManifest.CreateDefault(UInt160.Zero); - expected.SafeMethods = WildCardContainer.Create(new string[] { "AAA" }); + expected.SafeMethods = WildcardContainer.Create(new string[] { "AAA" }); expected.Serialize(writer); stream.Seek(0, SeekOrigin.Begin); var actual = ContractManifest.CreateDefault(UInt160.Zero); @@ -127,7 +123,7 @@ public void TestGetHash() public void TestGetSize() { var temp = ContractManifest.CreateDefault(UInt160.Zero); - Assert.AreEqual(418, temp.Size); + Assert.AreEqual(364, temp.Size); } [TestMethod] @@ -141,7 +137,7 @@ public void TestGenerator() public void TestCanCall() { var temp = ContractManifest.CreateDefault(UInt160.Zero); - temp.SafeMethods = WildCardContainer.Create(new string[] { "AAA" }); + temp.SafeMethods = WildcardContainer.Create(new string[] { "AAA" }); Assert.AreEqual(true, temp.CanCall(ContractManifest.CreateDefault(UInt160.Zero), "AAA")); } @@ -149,7 +145,7 @@ public void TestCanCall() public void TestClone() { var expected = ContractManifest.CreateDefault(UInt160.Zero); - expected.SafeMethods = WildCardContainer.Create(new string[] { "AAA" }); + expected.SafeMethods = WildcardContainer.Create(new string[] { "AAA" }); var actual = expected.Clone(); Assert.AreEqual(actual.ToString(), expected.ToString()); } diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_WildCardContainer.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_WildCardContainer.cs index 96bec21d2d..9a6743e4a5 100644 --- a/tests/neo.UnitTests/SmartContract/Manifest/UT_WildCardContainer.cs +++ b/tests/neo.UnitTests/SmartContract/Manifest/UT_WildCardContainer.cs @@ -15,22 +15,22 @@ public class UT_WildCardContainer public void TestFromJson() { JString jstring = new JString("*"); - WildCardContainer s = WildCardContainer.FromJson(jstring, u => u.AsString()); + WildcardContainer s = WildcardContainer.FromJson(jstring, u => u.AsString()); s.Should().BeEmpty(); jstring = new JString("hello world"); - Action action = () => WildCardContainer.FromJson(jstring, u => u.AsString()); + Action action = () => WildcardContainer.FromJson(jstring, u => u.AsString()); action.Should().Throw(); JObject alice = new JObject(); alice["name"] = "alice"; alice["age"] = 30; JArray jarray = new JArray { alice }; - WildCardContainer r = WildCardContainer.FromJson(jarray, u => u.AsString()); + WildcardContainer r = WildcardContainer.FromJson(jarray, u => u.AsString()); r[0].Should().Be("{\"name\":\"alice\",\"age\":30}"); JBoolean jbool = new JBoolean(); - action = () => WildCardContainer.FromJson(jbool, u => u.AsString()); + action = () => WildcardContainer.FromJson(jbool, u => u.AsString()); action.Should().Throw(); } @@ -38,11 +38,11 @@ public void TestFromJson() public void TestGetCount() { string[] s = new string[] { "hello", "world" }; - WildCardContainer container = WildCardContainer.Create(s); + WildcardContainer container = WildcardContainer.Create(s); container.Count.Should().Be(2); s = null; - container = WildCardContainer.Create(s); + container = WildcardContainer.Create(s); container.Count.Should().Be(0); } @@ -50,7 +50,7 @@ public void TestGetCount() public void TestGetItem() { string[] s = new string[] { "hello", "world" }; - WildCardContainer container = WildCardContainer.Create(s); + WildcardContainer container = WildcardContainer.Create(s); container[0].Should().Be("hello"); container[1].Should().Be("world"); } @@ -60,12 +60,12 @@ public void TestGetEnumerator() { string[] s = null; IReadOnlyList rs = (IReadOnlyList)new string[0]; - WildCardContainer container = WildCardContainer.Create(s); + WildcardContainer container = WildcardContainer.Create(s); IEnumerator enumerator = container.GetEnumerator(); enumerator.Should().Be(rs.GetEnumerator()); s = new string[] { "hello", "world" }; - container = WildCardContainer.Create(s); + container = WildcardContainer.Create(s); enumerator = container.GetEnumerator(); foreach (string _ in s) { @@ -78,7 +78,7 @@ public void TestGetEnumerator() public void TestIEnumerableGetEnumerator() { string[] s = new string[] { "hello", "world" }; - WildCardContainer container = WildCardContainer.Create(s); + WildcardContainer container = WildcardContainer.Create(s); IEnumerable enumerable = container; var enumerator = enumerable.GetEnumerator(); foreach (string _ in s) diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs index e1f29ad4ad..d7e376def3 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs @@ -748,12 +748,12 @@ public void TestContract_Call() engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString().Should().Be(method.ToHexString()); engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString().Should().Be(args.ToHexString()); - state.Manifest.Permissions[0].Methods = WildCardContainer.Create("a"); + state.Manifest.Permissions[0].Methods = WildcardContainer.Create("a"); engine.CurrentContext.EvaluationStack.Push(args); engine.CurrentContext.EvaluationStack.Push(method); engine.CurrentContext.EvaluationStack.Push(state.ScriptHash.ToArray()); InteropService.Invoke(engine, InteropService.System_Contract_Call).Should().BeFalse(); - state.Manifest.Permissions[0].Methods = WildCardContainer.CreateWildcard(); + state.Manifest.Permissions[0].Methods = WildcardContainer.CreateWildcard(); engine.CurrentContext.EvaluationStack.Push(args); engine.CurrentContext.EvaluationStack.Push(method); From 73bef2f648b0040fccc30c05e124ec4592f31193 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 6 Dec 2019 17:27:32 -0300 Subject: [PATCH 07/18] Fix clone --- src/neo/SmartContract/Manifest/ContractManifest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs index cc48fdbae4..64e69b9a2f 100644 --- a/src/neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/neo/SmartContract/Manifest/ContractManifest.cs @@ -153,7 +153,8 @@ public ContractManifest Clone() Abi = Abi.Clone(), Permissions = Permissions.Select(p => p.Clone()).ToArray(), Trusts = Trusts, - SafeMethods = SafeMethods + SafeMethods = SafeMethods, + Extra = Extra }; } From 4f57da4f757944314dbd2eabac29c0c2f98b62e8 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 6 Dec 2019 17:50:26 -0300 Subject: [PATCH 08/18] Removing manifest to test push --- .github/workflows/dotnetcore.yml | 74 -------------------------------- 1 file changed, 74 deletions(-) delete mode 100644 .github/workflows/dotnetcore.yml diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml deleted file mode 100644 index dab405a371..0000000000 --- a/.github/workflows/dotnetcore.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: .NET Core Test and Publish - -on: - push: - branches: master - pull_request: - -env: - DOTNET_VERSION: 3.0.100 - -jobs: - - Test: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v1 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 - with: - dotnet-version: ${{ env.DOTNET_VERSION }} - - name: Check format - run: | - dotnet tool install --tool-path ./ dotnet-format - ./dotnet-format --check --dry-run -v diagnostic - - name: Test - run: | - find tests -name *.csproj | xargs -I % dotnet add % package coverlet.msbuild - dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=${GITHUB_WORKSPACE}/coverage/lcov - - name: Coveralls - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - - PublishGithub: - # Because sometimes this action is not working as expected we will disable it until determine that it's more stable - if: false && github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/') - needs: Test - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v1 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 - with: - dotnet-version: ${{ env.DOTNET_VERSION }} - - name: Setup NuGet.exe for use with actions - uses: NuGet/setup-nuget@v1 - - name: Pack with dotnet - run: git rev-list --count HEAD |xargs printf "CI%05d" |xargs dotnet pack -c Debug -o out --include-source --version-suffix - - name: Publish to Github Packages - run: | - nuget source Add -Name "GitHub" -Source "https://nuget.pkg.github.com/neo-project/index.json" -UserName neo-project -Password ${GITHUB_TOKEN} - nuget push out/*.nupkg -Source "GitHub" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - PublishMyGet: - if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/') - needs: Test - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v1 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 - with: - dotnet-version: ${{ env.DOTNET_VERSION }} - - name: Pack with dotnet - run: git rev-list --count HEAD |xargs printf "CI%05d" |xargs dotnet pack -c Debug -o out --include-source --version-suffix - - name: Publish to MyGet - run: dotnet nuget push out/*.nupkg -s https://www.myget.org/F/neo/api/v2/package -k ${MYGET_TOKEN} -ss https://www.myget.org/F/neo/symbols/api/v2/package -sk ${MYGET_TOKEN} - env: - MYGET_TOKEN: ${{ secrets.MYGET_TOKEN }} From be9329da2a371f99092c28fb53d503a27b3d4897 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Sat, 7 Dec 2019 18:32:40 -0300 Subject: [PATCH 09/18] Removing wrong file, renaming test --- neo.UnitTests/Ledger/ECPointOld.cs | 6 ------ .../SmartContract/Manifest/UT_ContractManifest.cs | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 neo.UnitTests/Ledger/ECPointOld.cs diff --git a/neo.UnitTests/Ledger/ECPointOld.cs b/neo.UnitTests/Ledger/ECPointOld.cs deleted file mode 100644 index 27c2ee2b89..0000000000 --- a/neo.UnitTests/Ledger/ECPointOld.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Neo.UnitTests.Ledger -{ - internal class ECPointOld - { - } -} \ No newline at end of file diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 870df2f7c8..70ae720176 100644 --- a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -88,7 +88,7 @@ public void ParseFromJson_Groups() } [TestMethod] - public void ParseFromJson_Contacts() + public void ParseFromJson_Extra() { var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{""key"":""value""}}"; var manifest = ContractManifest.Parse(json); From 7636868c086e5cabb7efb88eec38ee7a9602dd68 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Sat, 7 Dec 2019 18:33:59 -0300 Subject: [PATCH 10/18] Revert "Removing manifest to test push" This reverts commit 4f57da4f757944314dbd2eabac29c0c2f98b62e8. --- .github/workflows/dotnetcore.yml | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 .github/workflows/dotnetcore.yml diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml new file mode 100644 index 0000000000..dab405a371 --- /dev/null +++ b/.github/workflows/dotnetcore.yml @@ -0,0 +1,74 @@ +name: .NET Core Test and Publish + +on: + push: + branches: master + pull_request: + +env: + DOTNET_VERSION: 3.0.100 + +jobs: + + Test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + - name: Check format + run: | + dotnet tool install --tool-path ./ dotnet-format + ./dotnet-format --check --dry-run -v diagnostic + - name: Test + run: | + find tests -name *.csproj | xargs -I % dotnet add % package coverlet.msbuild + dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=${GITHUB_WORKSPACE}/coverage/lcov + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + PublishGithub: + # Because sometimes this action is not working as expected we will disable it until determine that it's more stable + if: false && github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/') + needs: Test + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + - name: Setup NuGet.exe for use with actions + uses: NuGet/setup-nuget@v1 + - name: Pack with dotnet + run: git rev-list --count HEAD |xargs printf "CI%05d" |xargs dotnet pack -c Debug -o out --include-source --version-suffix + - name: Publish to Github Packages + run: | + nuget source Add -Name "GitHub" -Source "https://nuget.pkg.github.com/neo-project/index.json" -UserName neo-project -Password ${GITHUB_TOKEN} + nuget push out/*.nupkg -Source "GitHub" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + PublishMyGet: + if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/') + needs: Test + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + - name: Pack with dotnet + run: git rev-list --count HEAD |xargs printf "CI%05d" |xargs dotnet pack -c Debug -o out --include-source --version-suffix + - name: Publish to MyGet + run: dotnet nuget push out/*.nupkg -s https://www.myget.org/F/neo/api/v2/package -k ${MYGET_TOKEN} -ss https://www.myget.org/F/neo/symbols/api/v2/package -sk ${MYGET_TOKEN} + env: + MYGET_TOKEN: ${{ secrets.MYGET_TOKEN }} From fc8e7051d8c0e0f9e8cfa7efa6ef716e3ff84e5a Mon Sep 17 00:00:00 2001 From: Ricardo Prado <38396062+lock9@users.noreply.github.com> Date: Thu, 12 Dec 2019 01:16:40 -0300 Subject: [PATCH 11/18] Update src/neo/SmartContract/Manifest/ContractManifest.cs Co-Authored-By: Erik Zhang --- src/neo/SmartContract/Manifest/ContractManifest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs index 64e69b9a2f..4aa74262a5 100644 --- a/src/neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/neo/SmartContract/Manifest/ContractManifest.cs @@ -85,7 +85,7 @@ public static ContractManifest CreateDefault(UInt160 hash) Groups = new ContractGroup[0], SafeMethods = WildcardContainer.Create(), Trusts = WildcardContainer.Create(), - Extra = new JObject(), + Extra = null, }; } From 8200dde5b14c292fd72cb53013fcb727e3e1e36b Mon Sep 17 00:00:00 2001 From: Ricardo Prado <38396062+lock9@users.noreply.github.com> Date: Thu, 12 Dec 2019 01:16:53 -0300 Subject: [PATCH 12/18] Update src/neo/SmartContract/Manifest/ContractManifest.cs Co-Authored-By: Erik Zhang --- src/neo/SmartContract/Manifest/ContractManifest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs index 4aa74262a5..d051870de9 100644 --- a/src/neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/neo/SmartContract/Manifest/ContractManifest.cs @@ -182,7 +182,7 @@ private void DeserializeFromJson(JObject json) Permissions = ((JArray)json["permissions"]).Select(u => ContractPermission.FromJson(u)).ToArray(); Trusts = WildcardContainer.FromJson(json["trusts"], u => UInt160.Parse(u.AsString())); SafeMethods = WildcardContainer.FromJson(json["safeMethods"], u => u.AsString()); - Extra = JObject.Parse(json["extra"].AsString()); + Extra = json["extra"]; if (json["features"]["storage"].AsBoolean()) Features |= ContractFeatures.HasStorage; if (json["features"]["payable"].AsBoolean()) Features |= ContractFeatures.Payable; } From e98d08c2935b57d17428eb1f945a40a230accc3e Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 12 Dec 2019 01:29:49 -0300 Subject: [PATCH 13/18] Fixing tests --- tests/neo.UnitTests/Ledger/UT_ContractState.cs | 2 +- .../SmartContract/Manifest/UT_ContractManifest.cs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs index dbd0d7653a..670f31d757 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(366); + newContract.Size.Should().Be(368); } [TestMethod] diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 70ae720176..6bab91a808 100644 --- a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -12,7 +12,7 @@ public class UT_ContractManifest [TestMethod] public void ParseFromJson_Default() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -23,7 +23,7 @@ public void ParseFromJson_Default() [TestMethod] public void ParseFromJson_Features() { - var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{}}"; + var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToJson().ToString(), json); @@ -35,7 +35,7 @@ public void ParseFromJson_Features() [TestMethod] public void ParseFromJson_Permissions() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[],""extra"":{}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -54,7 +54,7 @@ public void ParseFromJson_Permissions() [TestMethod] public void ParseFromJson_SafeMethods() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""],""extra"":{}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -66,7 +66,7 @@ public void ParseFromJson_SafeMethods() [TestMethod] public void ParseFromJson_Trust() { - var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[],""extra"":{}}"; + var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -78,7 +78,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"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{}}"; + var json = @"{""groups"":[{""pubKey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":null}"; var manifest = ContractManifest.Parse(json); Assert.AreEqual(manifest.ToString(), json); @@ -123,7 +123,7 @@ public void TestGetHash() public void TestGetSize() { var temp = ContractManifest.CreateDefault(UInt160.Zero); - Assert.AreEqual(364, temp.Size); + Assert.AreEqual(366, temp.Size); } [TestMethod] From e839c1868b48e78753261c414e05b571522cfa62 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 12 Dec 2019 04:44:09 -0300 Subject: [PATCH 14/18] JObject clone --- src/neo/IO/Json/JArray.cs | 12 ++++++++++++ src/neo/IO/Json/JBoolean.cs | 5 +++++ src/neo/IO/Json/JNumber.cs | 5 +++++ src/neo/IO/Json/JObject.cs | 12 ++++++++++++ src/neo/IO/Json/JString.cs | 5 +++++ src/neo/SmartContract/Manifest/ContractManifest.cs | 2 +- tests/neo.UnitTests/IO/Json/UT_JObject.cs | 13 +++++++++++++ 7 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/neo/IO/Json/JArray.cs b/src/neo/IO/Json/JArray.cs index 8b7dab524d..489a2998d4 100644 --- a/src/neo/IO/Json/JArray.cs +++ b/src/neo/IO/Json/JArray.cs @@ -114,6 +114,18 @@ internal override void Write(Utf8JsonWriter writer) writer.WriteEndArray(); } + public override JObject Clone() + { + var cloned = new JArray(); + + foreach(JObject item in items) + { + cloned.Add(item.Clone()); + } + + return cloned; + } + public static implicit operator JArray(JObject[] value) { return new JArray(value); diff --git a/src/neo/IO/Json/JBoolean.cs b/src/neo/IO/Json/JBoolean.cs index fa1554ab56..0cc333bc3c 100644 --- a/src/neo/IO/Json/JBoolean.cs +++ b/src/neo/IO/Json/JBoolean.cs @@ -36,6 +36,11 @@ internal override void Write(Utf8JsonWriter writer) writer.WriteBooleanValue(Value); } + public override JObject Clone() + { + return new JBoolean(Value); + } + public static implicit operator JBoolean(bool value) { return new JBoolean(value); diff --git a/src/neo/IO/Json/JNumber.cs b/src/neo/IO/Json/JNumber.cs index 4f933aa3ad..f7a5e4fe91 100644 --- a/src/neo/IO/Json/JNumber.cs +++ b/src/neo/IO/Json/JNumber.cs @@ -58,6 +58,11 @@ internal override void Write(Utf8JsonWriter writer) writer.WriteNumberValue(Value); } + public override JObject Clone() + { + return new JNumber(Value); + } + public static implicit operator JNumber(double value) { return new JNumber(value); diff --git a/src/neo/IO/Json/JObject.cs b/src/neo/IO/Json/JObject.cs index 11e477704d..daa2e9741a 100644 --- a/src/neo/IO/Json/JObject.cs +++ b/src/neo/IO/Json/JObject.cs @@ -199,5 +199,17 @@ internal virtual void Write(Utf8JsonWriter writer) { return (JString)value; } + + public virtual JObject Clone() + { + var cloned = new JObject(); + + foreach (KeyValuePair pair in Properties) + { + cloned[pair.Key] = pair.Value != null ? pair.Value.Clone() : Null; + } + + return cloned; + } } } diff --git a/src/neo/IO/Json/JString.cs b/src/neo/IO/Json/JString.cs index a54284c3f0..3df8383c79 100644 --- a/src/neo/IO/Json/JString.cs +++ b/src/neo/IO/Json/JString.cs @@ -46,6 +46,11 @@ internal override void Write(Utf8JsonWriter writer) writer.WriteStringValue(Value); } + public override JObject Clone() + { + return new JString(Value); + } + public static implicit operator JString(Enum value) { return new JString(value.ToString()); diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs index d051870de9..7dba95b57a 100644 --- a/src/neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/neo/SmartContract/Manifest/ContractManifest.cs @@ -154,7 +154,7 @@ public ContractManifest Clone() Permissions = Permissions.Select(p => p.Clone()).ToArray(), Trusts = Trusts, SafeMethods = SafeMethods, - Extra = Extra + Extra = Extra.Clone() }; } diff --git a/tests/neo.UnitTests/IO/Json/UT_JObject.cs b/tests/neo.UnitTests/IO/Json/UT_JObject.cs index fe835016f0..2d2649f18a 100644 --- a/tests/neo.UnitTests/IO/Json/UT_JObject.cs +++ b/tests/neo.UnitTests/IO/Json/UT_JObject.cs @@ -1,6 +1,7 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.IO.Json; +using Neo.SmartContract.Manifest; using System; namespace Neo.UnitTests.IO.Json @@ -106,5 +107,17 @@ public void TestGetNull() { JObject.Null.Should().BeNull(); } + + [TestMethod] + public void TestClone() + { + var bobClone = bob.Clone(); + bobClone.Should().NotBeSameAs(bob); + foreach(var key in bobClone.Properties.Keys) + { + bobClone[key].Should().BeEquivalentTo(bob[key]); + bobClone[key].Should().NotBeSameAs(bob[key]); + } + } } } From b3a8fb545d311f8a94e6171f6b341cc262b7ce0b Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 12 Dec 2019 04:47:36 -0300 Subject: [PATCH 15/18] Dotnet format --- src/neo/IO/Json/JArray.cs | 2 +- tests/neo.UnitTests/IO/Json/UT_JObject.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/neo/IO/Json/JArray.cs b/src/neo/IO/Json/JArray.cs index 489a2998d4..9519c98b3e 100644 --- a/src/neo/IO/Json/JArray.cs +++ b/src/neo/IO/Json/JArray.cs @@ -118,7 +118,7 @@ public override JObject Clone() { var cloned = new JArray(); - foreach(JObject item in items) + foreach (JObject item in items) { cloned.Add(item.Clone()); } diff --git a/tests/neo.UnitTests/IO/Json/UT_JObject.cs b/tests/neo.UnitTests/IO/Json/UT_JObject.cs index 2d2649f18a..43aa7782a0 100644 --- a/tests/neo.UnitTests/IO/Json/UT_JObject.cs +++ b/tests/neo.UnitTests/IO/Json/UT_JObject.cs @@ -113,7 +113,7 @@ public void TestClone() { var bobClone = bob.Clone(); bobClone.Should().NotBeSameAs(bob); - foreach(var key in bobClone.Properties.Keys) + foreach (var key in bobClone.Properties.Keys) { bobClone[key].Should().BeEquivalentTo(bob[key]); bobClone[key].Should().NotBeSameAs(bob[key]); From e29df7c3258286b3b3ad76c1fa5682c1fda6d9ce Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 12 Dec 2019 04:56:57 -0300 Subject: [PATCH 16/18] Null check --- src/neo/SmartContract/Manifest/ContractManifest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs index 7dba95b57a..112a608030 100644 --- a/src/neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/neo/SmartContract/Manifest/ContractManifest.cs @@ -154,7 +154,7 @@ public ContractManifest Clone() Permissions = Permissions.Select(p => p.Clone()).ToArray(), Trusts = Trusts, SafeMethods = SafeMethods, - Extra = Extra.Clone() + Extra = Extra?.Clone() }; } From 320ec0960c1456b116a11c1b8225ff081eb33acc Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 12 Dec 2019 13:51:01 -0300 Subject: [PATCH 17/18] Removing unecessary instantiation of primitive types --- src/neo/IO/Json/JBoolean.cs | 2 +- src/neo/IO/Json/JNumber.cs | 2 +- src/neo/IO/Json/JString.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/neo/IO/Json/JBoolean.cs b/src/neo/IO/Json/JBoolean.cs index 0cc333bc3c..4f78c93a78 100644 --- a/src/neo/IO/Json/JBoolean.cs +++ b/src/neo/IO/Json/JBoolean.cs @@ -38,7 +38,7 @@ internal override void Write(Utf8JsonWriter writer) public override JObject Clone() { - return new JBoolean(Value); + return Value; } public static implicit operator JBoolean(bool value) diff --git a/src/neo/IO/Json/JNumber.cs b/src/neo/IO/Json/JNumber.cs index f7a5e4fe91..fd95d41511 100644 --- a/src/neo/IO/Json/JNumber.cs +++ b/src/neo/IO/Json/JNumber.cs @@ -60,7 +60,7 @@ internal override void Write(Utf8JsonWriter writer) public override JObject Clone() { - return new JNumber(Value); + return Value; } public static implicit operator JNumber(double value) diff --git a/src/neo/IO/Json/JString.cs b/src/neo/IO/Json/JString.cs index 3df8383c79..703e78abbc 100644 --- a/src/neo/IO/Json/JString.cs +++ b/src/neo/IO/Json/JString.cs @@ -48,7 +48,7 @@ internal override void Write(Utf8JsonWriter writer) public override JObject Clone() { - return new JString(Value); + return Value; } public static implicit operator JString(Enum value) From 95bdccb4d08055b56190785df9bd64edd5a40480 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Thu, 12 Dec 2019 14:16:02 -0300 Subject: [PATCH 18/18] Removing refenrece check, returning this --- src/neo/IO/Json/JBoolean.cs | 2 +- src/neo/IO/Json/JNumber.cs | 2 +- src/neo/IO/Json/JString.cs | 2 +- tests/neo.UnitTests/IO/Json/UT_JObject.cs | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/neo/IO/Json/JBoolean.cs b/src/neo/IO/Json/JBoolean.cs index 4f78c93a78..7cfd7ee025 100644 --- a/src/neo/IO/Json/JBoolean.cs +++ b/src/neo/IO/Json/JBoolean.cs @@ -38,7 +38,7 @@ internal override void Write(Utf8JsonWriter writer) public override JObject Clone() { - return Value; + return this; } public static implicit operator JBoolean(bool value) diff --git a/src/neo/IO/Json/JNumber.cs b/src/neo/IO/Json/JNumber.cs index fd95d41511..165d8138ec 100644 --- a/src/neo/IO/Json/JNumber.cs +++ b/src/neo/IO/Json/JNumber.cs @@ -60,7 +60,7 @@ internal override void Write(Utf8JsonWriter writer) public override JObject Clone() { - return Value; + return this; } public static implicit operator JNumber(double value) diff --git a/src/neo/IO/Json/JString.cs b/src/neo/IO/Json/JString.cs index 703e78abbc..7c625875b3 100644 --- a/src/neo/IO/Json/JString.cs +++ b/src/neo/IO/Json/JString.cs @@ -48,7 +48,7 @@ internal override void Write(Utf8JsonWriter writer) public override JObject Clone() { - return Value; + return this; } public static implicit operator JString(Enum value) diff --git a/tests/neo.UnitTests/IO/Json/UT_JObject.cs b/tests/neo.UnitTests/IO/Json/UT_JObject.cs index 43aa7782a0..f32bf968dc 100644 --- a/tests/neo.UnitTests/IO/Json/UT_JObject.cs +++ b/tests/neo.UnitTests/IO/Json/UT_JObject.cs @@ -116,7 +116,6 @@ public void TestClone() foreach (var key in bobClone.Properties.Keys) { bobClone[key].Should().BeEquivalentTo(bob[key]); - bobClone[key].Should().NotBeSameAs(bob[key]); } } }