From 6b31958ca9b6a863a484e41d14057362c6d763b6 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Wed, 27 Dec 2023 10:10:06 +0100 Subject: [PATCH 01/29] Json BigInteger --- src/Neo.Json/JNumber.cs | 14 +++++++++++++- src/Neo.Json/JToken.cs | 6 ++++++ src/Neo/SmartContract/JsonSerializer.cs | 7 ++----- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/Neo.Json/JNumber.cs b/src/Neo.Json/JNumber.cs index 7e58b72567..624c7e9d11 100644 --- a/src/Neo.Json/JNumber.cs +++ b/src/Neo.Json/JNumber.cs @@ -9,6 +9,7 @@ // modifications are permitted. using System.Globalization; +using System.Numerics; using System.Text.Json; namespace Neo.Json @@ -39,7 +40,13 @@ public class JNumber : JToken /// The value of the JSON token. public JNumber(double value = 0) { - if (!double.IsFinite(value)) throw new FormatException(); + if (!double.IsFinite(value)) + throw new ArgumentException("value is not finite", nameof(value)); + if (value > MAX_SAFE_INTEGER) + throw new ArgumentException("value is higher than MAX_SAFE_INTEGER", nameof(value)); + if (value < MAX_SAFE_INTEGER) + throw new ArgumentException("value is lower than MAX_SAFE_INTEGER", nameof(value)); + this.Value = value; } @@ -117,5 +124,10 @@ public static implicit operator JNumber(double value) { return new JNumber(value); } + + public static implicit operator JNumber(BigInteger value) + { + return new JNumber((long)value); + } } } diff --git a/src/Neo.Json/JToken.cs b/src/Neo.Json/JToken.cs index 8c38fb9bc4..c93365b92a 100644 --- a/src/Neo.Json/JToken.cs +++ b/src/Neo.Json/JToken.cs @@ -8,6 +8,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using System.Numerics; using System.Text.Json; using static Neo.Json.Utility; @@ -297,6 +298,11 @@ public static implicit operator JToken(double value) return (JNumber)value; } + public static implicit operator JToken(BigInteger value) + { + return (JNumber)value; + } + public static implicit operator JToken?(string? value) { return (JString?)value; diff --git a/src/Neo/SmartContract/JsonSerializer.cs b/src/Neo/SmartContract/JsonSerializer.cs index 06eb1d5c22..cd69dfaaa8 100644 --- a/src/Neo/SmartContract/JsonSerializer.cs +++ b/src/Neo/SmartContract/JsonSerializer.cs @@ -50,10 +50,7 @@ public static JToken Serialize(StackItem item) } case Integer num: { - var integer = num.GetInteger(); - if (integer > JNumber.MAX_SAFE_INTEGER || integer < JNumber.MIN_SAFE_INTEGER) - throw new InvalidOperationException(); - return (double)integer; + return num.GetInteger(); } case Boolean boolean: { @@ -65,7 +62,7 @@ public static JToken Serialize(StackItem item) foreach (var entry in map) { - if (!(entry.Key is ByteString)) throw new FormatException(); + if (entry.Key is not ByteString) throw new FormatException(); var key = entry.Key.GetString(); var value = Serialize(entry.Value); From 48c26490f941b6e5652c3e5a95e00dace8ba553a Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Wed, 27 Dec 2023 10:17:33 +0100 Subject: [PATCH 02/29] Fix Min --- src/Neo.Json/JNumber.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.Json/JNumber.cs b/src/Neo.Json/JNumber.cs index 624c7e9d11..aa78569048 100644 --- a/src/Neo.Json/JNumber.cs +++ b/src/Neo.Json/JNumber.cs @@ -44,7 +44,7 @@ public JNumber(double value = 0) throw new ArgumentException("value is not finite", nameof(value)); if (value > MAX_SAFE_INTEGER) throw new ArgumentException("value is higher than MAX_SAFE_INTEGER", nameof(value)); - if (value < MAX_SAFE_INTEGER) + if (value < MIN_SAFE_INTEGER) throw new ArgumentException("value is lower than MAX_SAFE_INTEGER", nameof(value)); this.Value = value; From 186c2baa0ca66eaf2f0620ea11658aebb1ff6d55 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Wed, 27 Dec 2023 10:18:17 +0100 Subject: [PATCH 03/29] Fix ut --- tests/Neo.Json.UnitTests/UT_JNumber.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Neo.Json.UnitTests/UT_JNumber.cs b/tests/Neo.Json.UnitTests/UT_JNumber.cs index 6156bc1cb5..c03709f43e 100644 --- a/tests/Neo.Json.UnitTests/UT_JNumber.cs +++ b/tests/Neo.Json.UnitTests/UT_JNumber.cs @@ -33,13 +33,13 @@ public void TestAsBoolean() public void TestAsString() { Action action1 = () => new JNumber(double.PositiveInfinity).AsString(); - action1.Should().Throw(); + action1.Should().Throw(); Action action2 = () => new JNumber(double.NegativeInfinity).AsString(); - action2.Should().Throw(); + action2.Should().Throw(); Action action3 = () => new JNumber(double.NaN).AsString(); - action3.Should().Throw(); + action3.Should().Throw(); } [TestMethod] From eab5b25783a004e7d78dfc5b68f1da7449aa09ae Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Wed, 27 Dec 2023 10:19:45 +0100 Subject: [PATCH 04/29] add ut --- tests/Neo.Json.UnitTests/UT_JNumber.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/Neo.Json.UnitTests/UT_JNumber.cs b/tests/Neo.Json.UnitTests/UT_JNumber.cs index c03709f43e..6644e05e2f 100644 --- a/tests/Neo.Json.UnitTests/UT_JNumber.cs +++ b/tests/Neo.Json.UnitTests/UT_JNumber.cs @@ -1,3 +1,5 @@ +using System.Numerics; + namespace Neo.Json.UnitTests { enum Woo @@ -26,9 +28,18 @@ public void SetUp() public void TestAsBoolean() { maxInt.AsBoolean().Should().BeTrue(); + minInt.AsBoolean().Should().BeTrue(); zero.AsBoolean().Should().BeFalse(); } + [TestMethod] + public void TestBigInteger() + { + ((JNumber)BigInteger.One).AsNumber().Should().Be(1); + ((JNumber)BigInteger.Zero).AsNumber().Should().Be(0); + ((JNumber)BigInteger.MinusOne).AsNumber().Should().Be(-1); + } + [TestMethod] public void TestAsString() { From 776ab647b729acb4d3f029db5eef5720130472a3 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Wed, 27 Dec 2023 10:20:20 +0100 Subject: [PATCH 05/29] Fix exception msg --- src/Neo.Json/JNumber.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.Json/JNumber.cs b/src/Neo.Json/JNumber.cs index aa78569048..1a4c078583 100644 --- a/src/Neo.Json/JNumber.cs +++ b/src/Neo.Json/JNumber.cs @@ -45,7 +45,7 @@ public JNumber(double value = 0) if (value > MAX_SAFE_INTEGER) throw new ArgumentException("value is higher than MAX_SAFE_INTEGER", nameof(value)); if (value < MIN_SAFE_INTEGER) - throw new ArgumentException("value is lower than MAX_SAFE_INTEGER", nameof(value)); + throw new ArgumentException("value is lower than MIN_SAFE_INTEGER", nameof(value)); this.Value = value; } From 9ccb97d7ad46a3c94de65f08cb3e8f1272b2c544 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Wed, 27 Dec 2023 10:28:04 +0100 Subject: [PATCH 06/29] format --- src/Neo.Json/JNumber.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo.Json/JNumber.cs b/src/Neo.Json/JNumber.cs index 1a4c078583..c090bf381d 100644 --- a/src/Neo.Json/JNumber.cs +++ b/src/Neo.Json/JNumber.cs @@ -40,7 +40,7 @@ public class JNumber : JToken /// The value of the JSON token. public JNumber(double value = 0) { - if (!double.IsFinite(value)) + if (!double.IsFinite(value)) throw new ArgumentException("value is not finite", nameof(value)); if (value > MAX_SAFE_INTEGER) throw new ArgumentException("value is higher than MAX_SAFE_INTEGER", nameof(value)); From 458499b4cc9aeddf05bb2d8fa165757e751abca5 Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Wed, 27 Dec 2023 10:38:26 +0100 Subject: [PATCH 07/29] Fix UT --- .../Neo.UnitTests/SmartContract/UT_JsonSerializer.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Neo.UnitTests/SmartContract/UT_JsonSerializer.cs b/tests/Neo.UnitTests/SmartContract/UT_JsonSerializer.cs index bf608bc57e..7e48d9df01 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_JsonSerializer.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_JsonSerializer.cs @@ -32,7 +32,7 @@ public void JsonTest_WrongJson() Assert.ThrowsException(() => JObject.Parse(json)); json = @"{""length"":99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999}"; - Assert.ThrowsException(() => JObject.Parse(json)); + Assert.ThrowsException(() => JObject.Parse(json)); } [TestMethod] @@ -80,10 +80,10 @@ public void JsonTest_Numbers() Assert.AreEqual("[1,-2,3.5]", parsed.ToString()); - json = "[200.500000E+005,200.500000e+5,-1.1234e-100,9.05E+28]"; + json = "[200.500000E+005,200.500000e+5,-1.1234e-100,9.05E+8]"; parsed = JObject.Parse(json); - Assert.AreEqual("[20050000,20050000,-1.1234E-100,9.05E+28]", parsed.ToString()); + Assert.AreEqual("[20050000,20050000,-1.1234E-100,905000000]", parsed.ToString()); json = "[-]"; Assert.ThrowsException(() => JObject.Parse(json)); @@ -205,7 +205,7 @@ public void Serialize_EmptyObject() public void Serialize_Number() { var entry = new VM.Types.Array { 1, 9007199254740992 }; - Assert.ThrowsException(() => JsonSerializer.Serialize(entry)); + Assert.ThrowsException(() => JsonSerializer.Serialize(entry)); } [TestMethod] @@ -292,7 +292,7 @@ public void Serialize_Array_Bool_Str_Num() public void Deserialize_Array_Bool_Str_Num() { ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, null); - var items = JsonSerializer.Deserialize(engine, JObject.Parse("[true,\"test\",123,9.05E+28]"), ExecutionEngineLimits.Default); + var items = JsonSerializer.Deserialize(engine, JObject.Parse("[true,\"test\",123,1.05E+4]"), ExecutionEngineLimits.Default); Assert.IsInstanceOfType(items, typeof(VM.Types.Array)); Assert.AreEqual(((VM.Types.Array)items).Count, 4); @@ -302,7 +302,7 @@ public void Deserialize_Array_Bool_Str_Num() Assert.IsTrue(array[0].GetBoolean()); Assert.AreEqual(array[1].GetString(), "test"); Assert.AreEqual(array[2].GetInteger(), 123); - Assert.AreEqual(array[3].GetInteger(), BigInteger.Parse("90500000000000000000000000000")); + Assert.AreEqual(array[3].GetInteger(), BigInteger.Parse("10500")); } [TestMethod] From 308d33ddf9c990f2cbf229b7f9794d7af3bab10d Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 15 Feb 2024 17:23:55 +0800 Subject: [PATCH 08/29] Update src/Neo.Json/JNumber.cs --- src/Neo.Json/JNumber.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Neo.Json/JNumber.cs b/src/Neo.Json/JNumber.cs index ff75d0f6a1..95b1f08ef2 100644 --- a/src/Neo.Json/JNumber.cs +++ b/src/Neo.Json/JNumber.cs @@ -131,6 +131,17 @@ public static implicit operator JNumber(BigInteger value) return new JNumber((long)value); } + /// + /// Check if two JNumber are equal. + /// + /// Non null value + /// Nullable value + /// bool + /// + /// If the left is null, throw an . + /// If the right is null, return false. + /// If the left and right are the same object, return true. + /// public static bool operator ==(JNumber left, JNumber? right) { if (right is null) return false; From 19e31118051b4c1368fe81bf4697cb932659d3ec Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 15 Feb 2024 17:24:11 +0800 Subject: [PATCH 09/29] Update tests/Neo.Json.UnitTests/UT_JNumber.cs --- tests/Neo.Json.UnitTests/UT_JNumber.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/Neo.Json.UnitTests/UT_JNumber.cs b/tests/Neo.Json.UnitTests/UT_JNumber.cs index 0709a9bcd6..84d4019f1f 100644 --- a/tests/Neo.Json.UnitTests/UT_JNumber.cs +++ b/tests/Neo.Json.UnitTests/UT_JNumber.cs @@ -50,6 +50,22 @@ public void TestBigInteger() ((JNumber)BigInteger.Zero).AsNumber().Should().Be(0); ((JNumber)BigInteger.MinusOne).AsNumber().Should().Be(-1); } + + [TestMethod] + public void TestNullEqual() + { + JNumber nullJNumber = null; + + Assert.IsFalse(maxInt.Equals(null)); + Assert.IsFalse(maxInt == null); + Assert.IsFalse(minInt.Equals(null)); + Assert.IsFalse(minInt == null); + Assert.IsFalse(zero == null); + + Assert.ThrowsException(() => nullJNumber == maxInt); + Assert.ThrowsException(() => nullJNumber == minInt); + Assert.ThrowsException(() => nullJNumber == zero); + } [TestMethod] public void TestAsString() From 1214697581fa17d064793fd3386ad1b04e9f50df Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 15 Feb 2024 12:06:47 +0100 Subject: [PATCH 10/29] Fix format --- tests/Neo.Json.UnitTests/UT_JNumber.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Neo.Json.UnitTests/UT_JNumber.cs b/tests/Neo.Json.UnitTests/UT_JNumber.cs index 84d4019f1f..4342c46451 100644 --- a/tests/Neo.Json.UnitTests/UT_JNumber.cs +++ b/tests/Neo.Json.UnitTests/UT_JNumber.cs @@ -50,7 +50,7 @@ public void TestBigInteger() ((JNumber)BigInteger.Zero).AsNumber().Should().Be(0); ((JNumber)BigInteger.MinusOne).AsNumber().Should().Be(-1); } - + [TestMethod] public void TestNullEqual() { From bcc5fd09563fde07893cd59b4d07d402727d6b10 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 8 Aug 2024 00:24:40 +0800 Subject: [PATCH 11/29] add hardofork HF_Echidna --- src/Neo.CLI/config.fs.mainnet.json | 3 ++- src/Neo.CLI/config.json | 3 ++- src/Neo.CLI/config.mainnet.json | 3 ++- src/Neo.CLI/config.testnet.json | 3 ++- src/Neo/Hardfork.cs | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Neo.CLI/config.fs.mainnet.json b/src/Neo.CLI/config.fs.mainnet.json index 6879232732..c12372b43b 100644 --- a/src/Neo.CLI/config.fs.mainnet.json +++ b/src/Neo.CLI/config.fs.mainnet.json @@ -40,7 +40,8 @@ "HF_Aspidochelone": 3000000, "HF_Basilisk": 4500000, "HF_Cockatrice": 5800000, - "HF_Domovoi": 5800000 + "HF_Domovoi": 5800000, + "HF_Echidna": 0 }, "StandbyCommittee": [ "026fa34ec057d74c2fdf1a18e336d0bd597ea401a0b2ad57340d5c220d09f44086", diff --git a/src/Neo.CLI/config.json b/src/Neo.CLI/config.json index 772a221714..9e97ec1f00 100644 --- a/src/Neo.CLI/config.json +++ b/src/Neo.CLI/config.json @@ -38,7 +38,8 @@ "HF_Aspidochelone": 1730000, "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, - "HF_Domovoi": 5570000 + "HF_Domovoi": 5570000, + "HF_Echidna": 0 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.mainnet.json b/src/Neo.CLI/config.mainnet.json index 772a221714..9e97ec1f00 100644 --- a/src/Neo.CLI/config.mainnet.json +++ b/src/Neo.CLI/config.mainnet.json @@ -38,7 +38,8 @@ "HF_Aspidochelone": 1730000, "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, - "HF_Domovoi": 5570000 + "HF_Domovoi": 5570000, + "HF_Echidna": 0 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.testnet.json b/src/Neo.CLI/config.testnet.json index dc102be54b..88a04794f0 100644 --- a/src/Neo.CLI/config.testnet.json +++ b/src/Neo.CLI/config.testnet.json @@ -38,7 +38,8 @@ "HF_Aspidochelone": 210000, "HF_Basilisk": 2680000, "HF_Cockatrice": 3967000, - "HF_Domovoi": 4144000 + "HF_Domovoi": 4144000, + "HF_Echidna": 0 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo/Hardfork.cs b/src/Neo/Hardfork.cs index 7bd3cc0aef..9276c9c07d 100644 --- a/src/Neo/Hardfork.cs +++ b/src/Neo/Hardfork.cs @@ -16,6 +16,7 @@ public enum Hardfork : byte HF_Aspidochelone, HF_Basilisk, HF_Cockatrice, - HF_Domovoi + HF_Domovoi, + HF_Echidna } } From e63f10b3ad7d96ab2cf456f7faf101724f406e17 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 8 Aug 2024 01:54:41 -0700 Subject: [PATCH 12/29] Add entries to `Designation` event (#3397) * Add entries to Designation event * Change to HF_Echidna * Add UT * Add count --- .../SmartContract/Native/RoleManagement.cs | 24 +++++++++++++++++-- .../SmartContract/Native/UT_NativeContract.cs | 18 ++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index d0437594c9..a0fc82f126 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -26,7 +26,16 @@ public sealed class RoleManagement : NativeContract { [ContractEvent(0, name: "Designation", "Role", ContractParameterType.Integer, - "BlockIndex", ContractParameterType.Integer)] + "BlockIndex", ContractParameterType.Integer, + Hardfork.HF_Echidna)] + + [ContractEvent(Hardfork.HF_Echidna, 0, name: "Designation", + "Role", ContractParameterType.Integer, + "BlockIndex", ContractParameterType.Integer, + "Old", ContractParameterType.Array, + "New", ContractParameterType.Array + )] + internal RoleManagement() : base() { } /// @@ -69,7 +78,18 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node list.AddRange(nodes); list.Sort(); engine.SnapshotCache.Add(key, new StorageItem(list)); - engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, new StackItem[] { (int)role, engine.PersistingBlock.Index })); + + if (engine.IsHardforkEnabled(Hardfork.HF_Echidna)) + { + var oldNodes = new VM.Types.Array(engine.ReferenceCounter, GetDesignatedByRole(engine.Snapshot, role, index - 1).Select(u => (ByteString)u.EncodePoint(true))); + var newNodes = new VM.Types.Array(engine.ReferenceCounter, nodes.Select(u => (ByteString)u.EncodePoint(true))); + + engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, [(int)role, engine.PersistingBlock.Index, oldNodes, newNodes])); + } + else + { + engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, [(int)role, engine.PersistingBlock.Index])); + } } private class NodeList : InteroperableList diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index f9a3089f9d..627a9fdd3c 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -80,6 +80,24 @@ public void TestActiveDeprecatedIn() Assert.IsFalse(NativeContract.IsActive(new active() { ActiveIn = null, DeprecatedIn = Hardfork.HF_Cockatrice }, settings.IsHardforkEnabled, 20)); } + [TestMethod] + public void TestActiveDeprecatedInRoleManagement() + { + string json = UT_ProtocolSettings.CreateHKSettings("\"HF_Echidna\": 20"); + var file = Path.GetTempFileName(); + File.WriteAllText(file, json); + ProtocolSettings settings = ProtocolSettings.Load(file, false); + File.Delete(file); + + var before = NativeContract.RoleManagement.GetContractState(settings.IsHardforkEnabled, 19); + var after = NativeContract.RoleManagement.GetContractState(settings.IsHardforkEnabled, 20); + + Assert.AreEqual(2, before.Manifest.Abi.Events[0].Parameters.Length); + Assert.AreEqual(1, before.Manifest.Abi.Events.Length); + Assert.AreEqual(4, after.Manifest.Abi.Events[0].Parameters.Length); + Assert.AreEqual(1, after.Manifest.Abi.Events.Length); + } + [TestMethod] public void TestGetContract() { From 9d16c53741e1373cd96226fe98008f9e46400ce6 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Fri, 9 Aug 2024 03:42:18 +0800 Subject: [PATCH 13/29] [Neo Core StdLib] Add Base64url (#3453) * add base64url * active in * update placehold hf height * fix hf issue and move methods to proper place. * fix test * use identifymodel instead. --- src/Neo.CLI/config.fs.mainnet.json | 2 +- src/Neo.CLI/config.json | 2 +- src/Neo.CLI/config.mainnet.json | 2 +- src/Neo.CLI/config.testnet.json | 2 +- src/Neo/Neo.csproj | 1 + src/Neo/SmartContract/Native/StdLib.cs | 23 +++++++++++++++++++ .../SmartContract/Native/UT_NativeContract.cs | 2 +- .../SmartContract/Native/UT_StdLib.cs | 20 ++++++++++++++++ 8 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/Neo.CLI/config.fs.mainnet.json b/src/Neo.CLI/config.fs.mainnet.json index c12372b43b..bbd17978e3 100644 --- a/src/Neo.CLI/config.fs.mainnet.json +++ b/src/Neo.CLI/config.fs.mainnet.json @@ -41,7 +41,7 @@ "HF_Basilisk": 4500000, "HF_Cockatrice": 5800000, "HF_Domovoi": 5800000, - "HF_Echidna": 0 + "HF_Echidna": 5800001 }, "StandbyCommittee": [ "026fa34ec057d74c2fdf1a18e336d0bd597ea401a0b2ad57340d5c220d09f44086", diff --git a/src/Neo.CLI/config.json b/src/Neo.CLI/config.json index 9e97ec1f00..9590fc60fd 100644 --- a/src/Neo.CLI/config.json +++ b/src/Neo.CLI/config.json @@ -39,7 +39,7 @@ "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, "HF_Domovoi": 5570000, - "HF_Echidna": 0 + "HF_Echidna": 5570001 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.mainnet.json b/src/Neo.CLI/config.mainnet.json index 9e97ec1f00..9590fc60fd 100644 --- a/src/Neo.CLI/config.mainnet.json +++ b/src/Neo.CLI/config.mainnet.json @@ -39,7 +39,7 @@ "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, "HF_Domovoi": 5570000, - "HF_Echidna": 0 + "HF_Echidna": 5570001 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.testnet.json b/src/Neo.CLI/config.testnet.json index 88a04794f0..8bcd6d8956 100644 --- a/src/Neo.CLI/config.testnet.json +++ b/src/Neo.CLI/config.testnet.json @@ -39,7 +39,7 @@ "HF_Basilisk": 2680000, "HF_Cockatrice": 3967000, "HF_Domovoi": 4144000, - "HF_Echidna": 0 + "HF_Echidna": 4144001 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo/Neo.csproj b/src/Neo/Neo.csproj index 7c6478c33e..f4f2cb36b3 100644 --- a/src/Neo/Neo.csproj +++ b/src/Neo/Neo.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Neo/SmartContract/Native/StdLib.cs b/src/Neo/SmartContract/Native/StdLib.cs index f8fa9efcc2..1b4030d9f5 100644 --- a/src/Neo/SmartContract/Native/StdLib.cs +++ b/src/Neo/SmartContract/Native/StdLib.cs @@ -11,6 +11,7 @@ #pragma warning disable IDE0051 +using Microsoft.IdentityModel.Tokens; using Neo.Cryptography; using Neo.Json; using Neo.VM.Types; @@ -131,6 +132,28 @@ public static byte[] Base64Decode([MaxLength(MaxInputLength)] string s) return Convert.FromBase64String(s); } + /// + /// Encodes a byte array into a base64Url string. + /// + /// The base64Url to be encoded. + /// The encoded base64Url string. + [ContractMethod(Hardfork.HF_Echidna, CpuFee = 1 << 5)] + public static string Base64UrlEncode([MaxLength(MaxInputLength)] string data) + { + return Base64UrlEncoder.Encode(data); + } + + /// + /// Decodes a byte array from a base64Url string. + /// + /// The base64Url string. + /// The decoded base64Url string. + [ContractMethod(Hardfork.HF_Echidna, CpuFee = 1 << 5)] + public static string Base64UrlDecode([MaxLength(MaxInputLength)] string s) + { + return Base64UrlEncoder.Decode(s); + } + /// /// Encodes a byte array into a base58 . /// diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index 627a9fdd3c..26e00a3c2d 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -41,7 +41,7 @@ public void TestSetup() _nativeStates = new Dictionary { {"ContractManagement", """{"id":-1,"updatecounter":0,"hash":"0xfffdc93764dbaddd97c48f252a53ea4643faa3fd","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"ContractManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Array","offset":0,"safe":false},{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Array","offset":7,"safe":false},{"name":"destroy","parameters":[],"returntype":"Void","offset":14,"safe":false},{"name":"getContract","parameters":[{"name":"hash","type":"Hash160"}],"returntype":"Array","offset":21,"safe":true},{"name":"getContractById","parameters":[{"name":"id","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getContractHashes","parameters":[],"returntype":"InteropInterface","offset":35,"safe":true},{"name":"getMinimumDeploymentFee","parameters":[],"returntype":"Integer","offset":42,"safe":true},{"name":"hasMethod","parameters":[{"name":"hash","type":"Hash160"},{"name":"method","type":"String"},{"name":"pcount","type":"Integer"}],"returntype":"Boolean","offset":49,"safe":true},{"name":"setMinimumDeploymentFee","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":56,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Void","offset":63,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","offset":70,"safe":false}],"events":[{"name":"Deploy","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Update","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Destroy","parameters":[{"name":"Hash","type":"Hash160"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}""" }, - {"StdLib", """{"id":-2,"updatecounter":0,"hash":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dA","checksum":1991619121},"manifest":{"name":"StdLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"atoi","parameters":[{"name":"value","type":"String"}],"returntype":"Integer","offset":0,"safe":true},{"name":"atoi","parameters":[{"name":"value","type":"String"},{"name":"base","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"base58CheckDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":14,"safe":true},{"name":"base58CheckEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":21,"safe":true},{"name":"base58Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":28,"safe":true},{"name":"base58Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":35,"safe":true},{"name":"base64Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"base64Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":49,"safe":true},{"name":"deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"Any","offset":56,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"}],"returntype":"String","offset":63,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"},{"name":"base","type":"Integer"}],"returntype":"String","offset":70,"safe":true},{"name":"jsonDeserialize","parameters":[{"name":"json","type":"ByteArray"}],"returntype":"Any","offset":77,"safe":true},{"name":"jsonSerialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":84,"safe":true},{"name":"memoryCompare","parameters":[{"name":"str1","type":"ByteArray"},{"name":"str2","type":"ByteArray"}],"returntype":"Integer","offset":91,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"}],"returntype":"Integer","offset":98,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"}],"returntype":"Integer","offset":105,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"},{"name":"backward","type":"Boolean"}],"returntype":"Integer","offset":112,"safe":true},{"name":"serialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":119,"safe":true},{"name":"strLen","parameters":[{"name":"str","type":"String"}],"returntype":"Integer","offset":126,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"}],"returntype":"Array","offset":133,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"},{"name":"removeEmptyEntries","type":"Boolean"}],"returntype":"Array","offset":140,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, + {"StdLib", """{"id":-2,"updatecounter":0,"hash":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2681632925},"manifest":{"name":"StdLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"atoi","parameters":[{"name":"value","type":"String"}],"returntype":"Integer","offset":0,"safe":true},{"name":"atoi","parameters":[{"name":"value","type":"String"},{"name":"base","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"base58CheckDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":14,"safe":true},{"name":"base58CheckEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":21,"safe":true},{"name":"base58Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":28,"safe":true},{"name":"base58Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":35,"safe":true},{"name":"base64Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"base64Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":49,"safe":true},{"name":"base64UrlDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":56,"safe":true},{"name":"base64UrlEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":63,"safe":true},{"name":"deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"Any","offset":70,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"}],"returntype":"String","offset":77,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"},{"name":"base","type":"Integer"}],"returntype":"String","offset":84,"safe":true},{"name":"jsonDeserialize","parameters":[{"name":"json","type":"ByteArray"}],"returntype":"Any","offset":91,"safe":true},{"name":"jsonSerialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":98,"safe":true},{"name":"memoryCompare","parameters":[{"name":"str1","type":"ByteArray"},{"name":"str2","type":"ByteArray"}],"returntype":"Integer","offset":105,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"}],"returntype":"Integer","offset":112,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"}],"returntype":"Integer","offset":119,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"},{"name":"backward","type":"Boolean"}],"returntype":"Integer","offset":126,"safe":true},{"name":"serialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":133,"safe":true},{"name":"strLen","parameters":[{"name":"str","type":"String"}],"returntype":"Integer","offset":140,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"}],"returntype":"Array","offset":147,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"},{"name":"removeEmptyEntries","type":"Boolean"}],"returntype":"Array","offset":154,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"CryptoLib", """{"id":-3,"updatecounter":0,"hash":"0x726cb6e0cd8628a1350a611384688911ab75f51b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"CryptoLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"bls12381Add","parameters":[{"name":"x","type":"InteropInterface"},{"name":"y","type":"InteropInterface"}],"returntype":"InteropInterface","offset":0,"safe":true},{"name":"bls12381Deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"InteropInterface","offset":7,"safe":true},{"name":"bls12381Equal","parameters":[{"name":"x","type":"InteropInterface"},{"name":"y","type":"InteropInterface"}],"returntype":"Boolean","offset":14,"safe":true},{"name":"bls12381Mul","parameters":[{"name":"x","type":"InteropInterface"},{"name":"mul","type":"ByteArray"},{"name":"neg","type":"Boolean"}],"returntype":"InteropInterface","offset":21,"safe":true},{"name":"bls12381Pairing","parameters":[{"name":"g1","type":"InteropInterface"},{"name":"g2","type":"InteropInterface"}],"returntype":"InteropInterface","offset":28,"safe":true},{"name":"bls12381Serialize","parameters":[{"name":"g","type":"InteropInterface"}],"returntype":"ByteArray","offset":35,"safe":true},{"name":"keccak256","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"murmur32","parameters":[{"name":"data","type":"ByteArray"},{"name":"seed","type":"Integer"}],"returntype":"ByteArray","offset":49,"safe":true},{"name":"ripemd160","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":56,"safe":true},{"name":"sha256","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":63,"safe":true},{"name":"verifyWithECDsa","parameters":[{"name":"message","type":"ByteArray"},{"name":"pubkey","type":"ByteArray"},{"name":"signature","type":"ByteArray"},{"name":"curveHash","type":"Integer"}],"returntype":"Boolean","offset":70,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"LedgerContract", """{"id":-4,"updatecounter":0,"hash":"0xda65b600f7124ce6c79950c1772a36403104f2be","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1110259869},"manifest":{"name":"LedgerContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"currentHash","parameters":[],"returntype":"Hash256","offset":0,"safe":true},{"name":"currentIndex","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getBlock","parameters":[{"name":"indexOrHash","type":"ByteArray"}],"returntype":"Array","offset":14,"safe":true},{"name":"getTransaction","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Array","offset":21,"safe":true},{"name":"getTransactionFromBlock","parameters":[{"name":"blockIndexOrHash","type":"ByteArray"},{"name":"txIndex","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getTransactionHeight","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Integer","offset":35,"safe":true},{"name":"getTransactionSigners","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Array","offset":42,"safe":true},{"name":"getTransactionVMState","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Integer","offset":49,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"NeoToken", """{"id":-5,"updatecounter":0,"hash":"0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1325686241},"manifest":{"name":"NeoToken","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getAccountState","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Array","offset":14,"safe":true},{"name":"getAllCandidates","parameters":[],"returntype":"InteropInterface","offset":21,"safe":true},{"name":"getCandidateVote","parameters":[{"name":"pubKey","type":"PublicKey"}],"returntype":"Integer","offset":28,"safe":true},{"name":"getCandidates","parameters":[],"returntype":"Array","offset":35,"safe":true},{"name":"getCommittee","parameters":[],"returntype":"Array","offset":42,"safe":true},{"name":"getCommitteeAddress","parameters":[],"returntype":"Hash160","offset":49,"safe":true},{"name":"getGasPerBlock","parameters":[],"returntype":"Integer","offset":56,"safe":true},{"name":"getNextBlockValidators","parameters":[],"returntype":"Array","offset":63,"safe":true},{"name":"getRegisterPrice","parameters":[],"returntype":"Integer","offset":70,"safe":true},{"name":"registerCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":77,"safe":false},{"name":"setGasPerBlock","parameters":[{"name":"gasPerBlock","type":"Integer"}],"returntype":"Void","offset":84,"safe":false},{"name":"setRegisterPrice","parameters":[{"name":"registerPrice","type":"Integer"}],"returntype":"Void","offset":91,"safe":false},{"name":"symbol","parameters":[],"returntype":"String","offset":98,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":105,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":112,"safe":false},{"name":"unclaimedGas","parameters":[{"name":"account","type":"Hash160"},{"name":"end","type":"Integer"}],"returntype":"Integer","offset":119,"safe":true},{"name":"unregisterCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":126,"safe":false},{"name":"vote","parameters":[{"name":"account","type":"Hash160"},{"name":"voteTo","type":"PublicKey"}],"returntype":"Boolean","offset":133,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]},{"name":"CandidateStateChanged","parameters":[{"name":"pubkey","type":"PublicKey"},{"name":"registered","type":"Boolean"},{"name":"votes","type":"Integer"}]},{"name":"Vote","parameters":[{"name":"account","type":"Hash160"},{"name":"from","type":"PublicKey"},{"name":"to","type":"PublicKey"},{"name":"amount","type":"Integer"}]},{"name":"CommitteeChanged","parameters":[{"name":"old","type":"Array"},{"name":"new","type":"Array"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs index 1dffb3d384..f9761bee07 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs @@ -406,5 +406,25 @@ public void TestRuntime_Deserialize() Assert.AreEqual(engine.ResultStack.Pop().GetInteger(), 100); Assert.AreEqual(engine.ResultStack.Pop().GetString(), "test"); } + + [TestMethod] + public void TestBase64Url() + { + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + using (var script = new ScriptBuilder()) + { + // Test encoding + script.EmitDynamicCall(NativeContract.StdLib.Hash, "base64UrlEncode", "Subject=test@example.com&Issuer=https://example.com"); + script.EmitDynamicCall(NativeContract.StdLib.Hash, "base64UrlDecode", "U3ViamVjdD10ZXN0QGV4YW1wbGUuY29tJklzc3Vlcj1odHRwczovL2V4YW1wbGUuY29t"); + + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); + engine.LoadScript(script.ToArray()); + + Assert.AreEqual(engine.Execute(), VMState.HALT); + Assert.AreEqual(2, engine.ResultStack.Count); + Assert.AreEqual("Subject=test@example.com&Issuer=https://example.com", engine.ResultStack.Pop()); + Assert.AreEqual("U3ViamVjdD10ZXN0QGV4YW1wbGUuY29tJklzc3Vlcj1odHRwczovL2V4YW1wbGUuY29t", engine.ResultStack.Pop().GetString()); + } + } } } From f746f8de81958560bbd45c8d225931a559fb3ec4 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 8 Aug 2024 00:24:40 +0800 Subject: [PATCH 14/29] add hardofork HF_Echidna --- src/Neo.CLI/config.fs.mainnet.json | 3 ++- src/Neo.CLI/config.json | 3 ++- src/Neo.CLI/config.mainnet.json | 3 ++- src/Neo.CLI/config.testnet.json | 3 ++- src/Neo/Hardfork.cs | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Neo.CLI/config.fs.mainnet.json b/src/Neo.CLI/config.fs.mainnet.json index 6879232732..c12372b43b 100644 --- a/src/Neo.CLI/config.fs.mainnet.json +++ b/src/Neo.CLI/config.fs.mainnet.json @@ -40,7 +40,8 @@ "HF_Aspidochelone": 3000000, "HF_Basilisk": 4500000, "HF_Cockatrice": 5800000, - "HF_Domovoi": 5800000 + "HF_Domovoi": 5800000, + "HF_Echidna": 0 }, "StandbyCommittee": [ "026fa34ec057d74c2fdf1a18e336d0bd597ea401a0b2ad57340d5c220d09f44086", diff --git a/src/Neo.CLI/config.json b/src/Neo.CLI/config.json index 772a221714..9e97ec1f00 100644 --- a/src/Neo.CLI/config.json +++ b/src/Neo.CLI/config.json @@ -38,7 +38,8 @@ "HF_Aspidochelone": 1730000, "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, - "HF_Domovoi": 5570000 + "HF_Domovoi": 5570000, + "HF_Echidna": 0 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.mainnet.json b/src/Neo.CLI/config.mainnet.json index 772a221714..9e97ec1f00 100644 --- a/src/Neo.CLI/config.mainnet.json +++ b/src/Neo.CLI/config.mainnet.json @@ -38,7 +38,8 @@ "HF_Aspidochelone": 1730000, "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, - "HF_Domovoi": 5570000 + "HF_Domovoi": 5570000, + "HF_Echidna": 0 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.testnet.json b/src/Neo.CLI/config.testnet.json index dc102be54b..88a04794f0 100644 --- a/src/Neo.CLI/config.testnet.json +++ b/src/Neo.CLI/config.testnet.json @@ -38,7 +38,8 @@ "HF_Aspidochelone": 210000, "HF_Basilisk": 2680000, "HF_Cockatrice": 3967000, - "HF_Domovoi": 4144000 + "HF_Domovoi": 4144000, + "HF_Echidna": 0 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo/Hardfork.cs b/src/Neo/Hardfork.cs index 7bd3cc0aef..9276c9c07d 100644 --- a/src/Neo/Hardfork.cs +++ b/src/Neo/Hardfork.cs @@ -16,6 +16,7 @@ public enum Hardfork : byte HF_Aspidochelone, HF_Basilisk, HF_Cockatrice, - HF_Domovoi + HF_Domovoi, + HF_Echidna } } From 8d7f9e8ccbd556bf488994a6944f5f3b5a443682 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 8 Aug 2024 01:54:41 -0700 Subject: [PATCH 15/29] Add entries to `Designation` event (#3397) * Add entries to Designation event * Change to HF_Echidna * Add UT * Add count --- .../SmartContract/Native/RoleManagement.cs | 24 +++++++++++++++++-- .../SmartContract/Native/UT_NativeContract.cs | 18 ++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index d0437594c9..a0fc82f126 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -26,7 +26,16 @@ public sealed class RoleManagement : NativeContract { [ContractEvent(0, name: "Designation", "Role", ContractParameterType.Integer, - "BlockIndex", ContractParameterType.Integer)] + "BlockIndex", ContractParameterType.Integer, + Hardfork.HF_Echidna)] + + [ContractEvent(Hardfork.HF_Echidna, 0, name: "Designation", + "Role", ContractParameterType.Integer, + "BlockIndex", ContractParameterType.Integer, + "Old", ContractParameterType.Array, + "New", ContractParameterType.Array + )] + internal RoleManagement() : base() { } /// @@ -69,7 +78,18 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node list.AddRange(nodes); list.Sort(); engine.SnapshotCache.Add(key, new StorageItem(list)); - engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, new StackItem[] { (int)role, engine.PersistingBlock.Index })); + + if (engine.IsHardforkEnabled(Hardfork.HF_Echidna)) + { + var oldNodes = new VM.Types.Array(engine.ReferenceCounter, GetDesignatedByRole(engine.Snapshot, role, index - 1).Select(u => (ByteString)u.EncodePoint(true))); + var newNodes = new VM.Types.Array(engine.ReferenceCounter, nodes.Select(u => (ByteString)u.EncodePoint(true))); + + engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, [(int)role, engine.PersistingBlock.Index, oldNodes, newNodes])); + } + else + { + engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, [(int)role, engine.PersistingBlock.Index])); + } } private class NodeList : InteroperableList diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index f9a3089f9d..627a9fdd3c 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -80,6 +80,24 @@ public void TestActiveDeprecatedIn() Assert.IsFalse(NativeContract.IsActive(new active() { ActiveIn = null, DeprecatedIn = Hardfork.HF_Cockatrice }, settings.IsHardforkEnabled, 20)); } + [TestMethod] + public void TestActiveDeprecatedInRoleManagement() + { + string json = UT_ProtocolSettings.CreateHKSettings("\"HF_Echidna\": 20"); + var file = Path.GetTempFileName(); + File.WriteAllText(file, json); + ProtocolSettings settings = ProtocolSettings.Load(file, false); + File.Delete(file); + + var before = NativeContract.RoleManagement.GetContractState(settings.IsHardforkEnabled, 19); + var after = NativeContract.RoleManagement.GetContractState(settings.IsHardforkEnabled, 20); + + Assert.AreEqual(2, before.Manifest.Abi.Events[0].Parameters.Length); + Assert.AreEqual(1, before.Manifest.Abi.Events.Length); + Assert.AreEqual(4, after.Manifest.Abi.Events[0].Parameters.Length); + Assert.AreEqual(1, after.Manifest.Abi.Events.Length); + } + [TestMethod] public void TestGetContract() { From 3fc8077e17df8112de51dd260395455e27c69004 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Fri, 9 Aug 2024 03:42:18 +0800 Subject: [PATCH 16/29] [Neo Core StdLib] Add Base64url (#3453) * add base64url * active in * update placehold hf height * fix hf issue and move methods to proper place. * fix test * use identifymodel instead. --- src/Neo.CLI/config.fs.mainnet.json | 2 +- src/Neo.CLI/config.json | 2 +- src/Neo.CLI/config.mainnet.json | 2 +- src/Neo.CLI/config.testnet.json | 2 +- src/Neo/Neo.csproj | 1 + src/Neo/SmartContract/Native/StdLib.cs | 23 +++++++++++++++++++ .../SmartContract/Native/UT_NativeContract.cs | 2 +- .../SmartContract/Native/UT_StdLib.cs | 20 ++++++++++++++++ 8 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/Neo.CLI/config.fs.mainnet.json b/src/Neo.CLI/config.fs.mainnet.json index c12372b43b..bbd17978e3 100644 --- a/src/Neo.CLI/config.fs.mainnet.json +++ b/src/Neo.CLI/config.fs.mainnet.json @@ -41,7 +41,7 @@ "HF_Basilisk": 4500000, "HF_Cockatrice": 5800000, "HF_Domovoi": 5800000, - "HF_Echidna": 0 + "HF_Echidna": 5800001 }, "StandbyCommittee": [ "026fa34ec057d74c2fdf1a18e336d0bd597ea401a0b2ad57340d5c220d09f44086", diff --git a/src/Neo.CLI/config.json b/src/Neo.CLI/config.json index 9e97ec1f00..9590fc60fd 100644 --- a/src/Neo.CLI/config.json +++ b/src/Neo.CLI/config.json @@ -39,7 +39,7 @@ "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, "HF_Domovoi": 5570000, - "HF_Echidna": 0 + "HF_Echidna": 5570001 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.mainnet.json b/src/Neo.CLI/config.mainnet.json index 9e97ec1f00..9590fc60fd 100644 --- a/src/Neo.CLI/config.mainnet.json +++ b/src/Neo.CLI/config.mainnet.json @@ -39,7 +39,7 @@ "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, "HF_Domovoi": 5570000, - "HF_Echidna": 0 + "HF_Echidna": 5570001 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.testnet.json b/src/Neo.CLI/config.testnet.json index 88a04794f0..8bcd6d8956 100644 --- a/src/Neo.CLI/config.testnet.json +++ b/src/Neo.CLI/config.testnet.json @@ -39,7 +39,7 @@ "HF_Basilisk": 2680000, "HF_Cockatrice": 3967000, "HF_Domovoi": 4144000, - "HF_Echidna": 0 + "HF_Echidna": 4144001 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo/Neo.csproj b/src/Neo/Neo.csproj index 7c6478c33e..f4f2cb36b3 100644 --- a/src/Neo/Neo.csproj +++ b/src/Neo/Neo.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Neo/SmartContract/Native/StdLib.cs b/src/Neo/SmartContract/Native/StdLib.cs index f8fa9efcc2..1b4030d9f5 100644 --- a/src/Neo/SmartContract/Native/StdLib.cs +++ b/src/Neo/SmartContract/Native/StdLib.cs @@ -11,6 +11,7 @@ #pragma warning disable IDE0051 +using Microsoft.IdentityModel.Tokens; using Neo.Cryptography; using Neo.Json; using Neo.VM.Types; @@ -131,6 +132,28 @@ public static byte[] Base64Decode([MaxLength(MaxInputLength)] string s) return Convert.FromBase64String(s); } + /// + /// Encodes a byte array into a base64Url string. + /// + /// The base64Url to be encoded. + /// The encoded base64Url string. + [ContractMethod(Hardfork.HF_Echidna, CpuFee = 1 << 5)] + public static string Base64UrlEncode([MaxLength(MaxInputLength)] string data) + { + return Base64UrlEncoder.Encode(data); + } + + /// + /// Decodes a byte array from a base64Url string. + /// + /// The base64Url string. + /// The decoded base64Url string. + [ContractMethod(Hardfork.HF_Echidna, CpuFee = 1 << 5)] + public static string Base64UrlDecode([MaxLength(MaxInputLength)] string s) + { + return Base64UrlEncoder.Decode(s); + } + /// /// Encodes a byte array into a base58 . /// diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index 627a9fdd3c..26e00a3c2d 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -41,7 +41,7 @@ public void TestSetup() _nativeStates = new Dictionary { {"ContractManagement", """{"id":-1,"updatecounter":0,"hash":"0xfffdc93764dbaddd97c48f252a53ea4643faa3fd","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"ContractManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Array","offset":0,"safe":false},{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Array","offset":7,"safe":false},{"name":"destroy","parameters":[],"returntype":"Void","offset":14,"safe":false},{"name":"getContract","parameters":[{"name":"hash","type":"Hash160"}],"returntype":"Array","offset":21,"safe":true},{"name":"getContractById","parameters":[{"name":"id","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getContractHashes","parameters":[],"returntype":"InteropInterface","offset":35,"safe":true},{"name":"getMinimumDeploymentFee","parameters":[],"returntype":"Integer","offset":42,"safe":true},{"name":"hasMethod","parameters":[{"name":"hash","type":"Hash160"},{"name":"method","type":"String"},{"name":"pcount","type":"Integer"}],"returntype":"Boolean","offset":49,"safe":true},{"name":"setMinimumDeploymentFee","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":56,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Void","offset":63,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","offset":70,"safe":false}],"events":[{"name":"Deploy","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Update","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Destroy","parameters":[{"name":"Hash","type":"Hash160"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}""" }, - {"StdLib", """{"id":-2,"updatecounter":0,"hash":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dA","checksum":1991619121},"manifest":{"name":"StdLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"atoi","parameters":[{"name":"value","type":"String"}],"returntype":"Integer","offset":0,"safe":true},{"name":"atoi","parameters":[{"name":"value","type":"String"},{"name":"base","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"base58CheckDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":14,"safe":true},{"name":"base58CheckEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":21,"safe":true},{"name":"base58Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":28,"safe":true},{"name":"base58Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":35,"safe":true},{"name":"base64Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"base64Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":49,"safe":true},{"name":"deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"Any","offset":56,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"}],"returntype":"String","offset":63,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"},{"name":"base","type":"Integer"}],"returntype":"String","offset":70,"safe":true},{"name":"jsonDeserialize","parameters":[{"name":"json","type":"ByteArray"}],"returntype":"Any","offset":77,"safe":true},{"name":"jsonSerialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":84,"safe":true},{"name":"memoryCompare","parameters":[{"name":"str1","type":"ByteArray"},{"name":"str2","type":"ByteArray"}],"returntype":"Integer","offset":91,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"}],"returntype":"Integer","offset":98,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"}],"returntype":"Integer","offset":105,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"},{"name":"backward","type":"Boolean"}],"returntype":"Integer","offset":112,"safe":true},{"name":"serialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":119,"safe":true},{"name":"strLen","parameters":[{"name":"str","type":"String"}],"returntype":"Integer","offset":126,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"}],"returntype":"Array","offset":133,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"},{"name":"removeEmptyEntries","type":"Boolean"}],"returntype":"Array","offset":140,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, + {"StdLib", """{"id":-2,"updatecounter":0,"hash":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2681632925},"manifest":{"name":"StdLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"atoi","parameters":[{"name":"value","type":"String"}],"returntype":"Integer","offset":0,"safe":true},{"name":"atoi","parameters":[{"name":"value","type":"String"},{"name":"base","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"base58CheckDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":14,"safe":true},{"name":"base58CheckEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":21,"safe":true},{"name":"base58Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":28,"safe":true},{"name":"base58Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":35,"safe":true},{"name":"base64Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"base64Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":49,"safe":true},{"name":"base64UrlDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":56,"safe":true},{"name":"base64UrlEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":63,"safe":true},{"name":"deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"Any","offset":70,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"}],"returntype":"String","offset":77,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"},{"name":"base","type":"Integer"}],"returntype":"String","offset":84,"safe":true},{"name":"jsonDeserialize","parameters":[{"name":"json","type":"ByteArray"}],"returntype":"Any","offset":91,"safe":true},{"name":"jsonSerialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":98,"safe":true},{"name":"memoryCompare","parameters":[{"name":"str1","type":"ByteArray"},{"name":"str2","type":"ByteArray"}],"returntype":"Integer","offset":105,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"}],"returntype":"Integer","offset":112,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"}],"returntype":"Integer","offset":119,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"},{"name":"backward","type":"Boolean"}],"returntype":"Integer","offset":126,"safe":true},{"name":"serialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":133,"safe":true},{"name":"strLen","parameters":[{"name":"str","type":"String"}],"returntype":"Integer","offset":140,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"}],"returntype":"Array","offset":147,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"},{"name":"removeEmptyEntries","type":"Boolean"}],"returntype":"Array","offset":154,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"CryptoLib", """{"id":-3,"updatecounter":0,"hash":"0x726cb6e0cd8628a1350a611384688911ab75f51b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"CryptoLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"bls12381Add","parameters":[{"name":"x","type":"InteropInterface"},{"name":"y","type":"InteropInterface"}],"returntype":"InteropInterface","offset":0,"safe":true},{"name":"bls12381Deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"InteropInterface","offset":7,"safe":true},{"name":"bls12381Equal","parameters":[{"name":"x","type":"InteropInterface"},{"name":"y","type":"InteropInterface"}],"returntype":"Boolean","offset":14,"safe":true},{"name":"bls12381Mul","parameters":[{"name":"x","type":"InteropInterface"},{"name":"mul","type":"ByteArray"},{"name":"neg","type":"Boolean"}],"returntype":"InteropInterface","offset":21,"safe":true},{"name":"bls12381Pairing","parameters":[{"name":"g1","type":"InteropInterface"},{"name":"g2","type":"InteropInterface"}],"returntype":"InteropInterface","offset":28,"safe":true},{"name":"bls12381Serialize","parameters":[{"name":"g","type":"InteropInterface"}],"returntype":"ByteArray","offset":35,"safe":true},{"name":"keccak256","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"murmur32","parameters":[{"name":"data","type":"ByteArray"},{"name":"seed","type":"Integer"}],"returntype":"ByteArray","offset":49,"safe":true},{"name":"ripemd160","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":56,"safe":true},{"name":"sha256","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":63,"safe":true},{"name":"verifyWithECDsa","parameters":[{"name":"message","type":"ByteArray"},{"name":"pubkey","type":"ByteArray"},{"name":"signature","type":"ByteArray"},{"name":"curveHash","type":"Integer"}],"returntype":"Boolean","offset":70,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"LedgerContract", """{"id":-4,"updatecounter":0,"hash":"0xda65b600f7124ce6c79950c1772a36403104f2be","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1110259869},"manifest":{"name":"LedgerContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"currentHash","parameters":[],"returntype":"Hash256","offset":0,"safe":true},{"name":"currentIndex","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getBlock","parameters":[{"name":"indexOrHash","type":"ByteArray"}],"returntype":"Array","offset":14,"safe":true},{"name":"getTransaction","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Array","offset":21,"safe":true},{"name":"getTransactionFromBlock","parameters":[{"name":"blockIndexOrHash","type":"ByteArray"},{"name":"txIndex","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getTransactionHeight","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Integer","offset":35,"safe":true},{"name":"getTransactionSigners","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Array","offset":42,"safe":true},{"name":"getTransactionVMState","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Integer","offset":49,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"NeoToken", """{"id":-5,"updatecounter":0,"hash":"0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1325686241},"manifest":{"name":"NeoToken","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getAccountState","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Array","offset":14,"safe":true},{"name":"getAllCandidates","parameters":[],"returntype":"InteropInterface","offset":21,"safe":true},{"name":"getCandidateVote","parameters":[{"name":"pubKey","type":"PublicKey"}],"returntype":"Integer","offset":28,"safe":true},{"name":"getCandidates","parameters":[],"returntype":"Array","offset":35,"safe":true},{"name":"getCommittee","parameters":[],"returntype":"Array","offset":42,"safe":true},{"name":"getCommitteeAddress","parameters":[],"returntype":"Hash160","offset":49,"safe":true},{"name":"getGasPerBlock","parameters":[],"returntype":"Integer","offset":56,"safe":true},{"name":"getNextBlockValidators","parameters":[],"returntype":"Array","offset":63,"safe":true},{"name":"getRegisterPrice","parameters":[],"returntype":"Integer","offset":70,"safe":true},{"name":"registerCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":77,"safe":false},{"name":"setGasPerBlock","parameters":[{"name":"gasPerBlock","type":"Integer"}],"returntype":"Void","offset":84,"safe":false},{"name":"setRegisterPrice","parameters":[{"name":"registerPrice","type":"Integer"}],"returntype":"Void","offset":91,"safe":false},{"name":"symbol","parameters":[],"returntype":"String","offset":98,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":105,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":112,"safe":false},{"name":"unclaimedGas","parameters":[{"name":"account","type":"Hash160"},{"name":"end","type":"Integer"}],"returntype":"Integer","offset":119,"safe":true},{"name":"unregisterCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":126,"safe":false},{"name":"vote","parameters":[{"name":"account","type":"Hash160"},{"name":"voteTo","type":"PublicKey"}],"returntype":"Boolean","offset":133,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]},{"name":"CandidateStateChanged","parameters":[{"name":"pubkey","type":"PublicKey"},{"name":"registered","type":"Boolean"},{"name":"votes","type":"Integer"}]},{"name":"Vote","parameters":[{"name":"account","type":"Hash160"},{"name":"from","type":"PublicKey"},{"name":"to","type":"PublicKey"},{"name":"amount","type":"Integer"}]},{"name":"CommitteeChanged","parameters":[{"name":"old","type":"Array"},{"name":"new","type":"Array"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs index 1dffb3d384..f9761bee07 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs @@ -406,5 +406,25 @@ public void TestRuntime_Deserialize() Assert.AreEqual(engine.ResultStack.Pop().GetInteger(), 100); Assert.AreEqual(engine.ResultStack.Pop().GetString(), "test"); } + + [TestMethod] + public void TestBase64Url() + { + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + using (var script = new ScriptBuilder()) + { + // Test encoding + script.EmitDynamicCall(NativeContract.StdLib.Hash, "base64UrlEncode", "Subject=test@example.com&Issuer=https://example.com"); + script.EmitDynamicCall(NativeContract.StdLib.Hash, "base64UrlDecode", "U3ViamVjdD10ZXN0QGV4YW1wbGUuY29tJklzc3Vlcj1odHRwczovL2V4YW1wbGUuY29t"); + + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); + engine.LoadScript(script.ToArray()); + + Assert.AreEqual(engine.Execute(), VMState.HALT); + Assert.AreEqual(2, engine.ResultStack.Count); + Assert.AreEqual("Subject=test@example.com&Issuer=https://example.com", engine.ResultStack.Pop()); + Assert.AreEqual("U3ViamVjdD10ZXN0QGV4YW1wbGUuY29tJklzc3Vlcj1odHRwczovL2V4YW1wbGUuY29t", engine.ResultStack.Pop().GetString()); + } + } } } From 7e31d0caacfadb7634614d629c88b9244b434501 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 8 Aug 2024 00:24:40 +0800 Subject: [PATCH 17/29] add hardofork HF_Echidna --- src/Neo.CLI/config.fs.mainnet.json | 3 ++- src/Neo.CLI/config.json | 3 ++- src/Neo.CLI/config.mainnet.json | 3 ++- src/Neo.CLI/config.testnet.json | 3 ++- src/Neo/Hardfork.cs | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Neo.CLI/config.fs.mainnet.json b/src/Neo.CLI/config.fs.mainnet.json index 6879232732..c12372b43b 100644 --- a/src/Neo.CLI/config.fs.mainnet.json +++ b/src/Neo.CLI/config.fs.mainnet.json @@ -40,7 +40,8 @@ "HF_Aspidochelone": 3000000, "HF_Basilisk": 4500000, "HF_Cockatrice": 5800000, - "HF_Domovoi": 5800000 + "HF_Domovoi": 5800000, + "HF_Echidna": 0 }, "StandbyCommittee": [ "026fa34ec057d74c2fdf1a18e336d0bd597ea401a0b2ad57340d5c220d09f44086", diff --git a/src/Neo.CLI/config.json b/src/Neo.CLI/config.json index 772a221714..9e97ec1f00 100644 --- a/src/Neo.CLI/config.json +++ b/src/Neo.CLI/config.json @@ -38,7 +38,8 @@ "HF_Aspidochelone": 1730000, "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, - "HF_Domovoi": 5570000 + "HF_Domovoi": 5570000, + "HF_Echidna": 0 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.mainnet.json b/src/Neo.CLI/config.mainnet.json index 772a221714..9e97ec1f00 100644 --- a/src/Neo.CLI/config.mainnet.json +++ b/src/Neo.CLI/config.mainnet.json @@ -38,7 +38,8 @@ "HF_Aspidochelone": 1730000, "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, - "HF_Domovoi": 5570000 + "HF_Domovoi": 5570000, + "HF_Echidna": 0 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.testnet.json b/src/Neo.CLI/config.testnet.json index dc102be54b..88a04794f0 100644 --- a/src/Neo.CLI/config.testnet.json +++ b/src/Neo.CLI/config.testnet.json @@ -38,7 +38,8 @@ "HF_Aspidochelone": 210000, "HF_Basilisk": 2680000, "HF_Cockatrice": 3967000, - "HF_Domovoi": 4144000 + "HF_Domovoi": 4144000, + "HF_Echidna": 0 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo/Hardfork.cs b/src/Neo/Hardfork.cs index 7bd3cc0aef..9276c9c07d 100644 --- a/src/Neo/Hardfork.cs +++ b/src/Neo/Hardfork.cs @@ -16,6 +16,7 @@ public enum Hardfork : byte HF_Aspidochelone, HF_Basilisk, HF_Cockatrice, - HF_Domovoi + HF_Domovoi, + HF_Echidna } } From 993e3fe9dd4485387f8dd244885f616b4dd78de5 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 8 Aug 2024 01:54:41 -0700 Subject: [PATCH 18/29] Add entries to `Designation` event (#3397) * Add entries to Designation event * Change to HF_Echidna * Add UT * Add count --- .../SmartContract/Native/RoleManagement.cs | 24 +++++++++++++++++-- .../SmartContract/Native/UT_NativeContract.cs | 18 ++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index e57f3f3e83..ecedba4c86 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -26,7 +26,16 @@ public sealed class RoleManagement : NativeContract { [ContractEvent(0, name: "Designation", "Role", ContractParameterType.Integer, - "BlockIndex", ContractParameterType.Integer)] + "BlockIndex", ContractParameterType.Integer, + Hardfork.HF_Echidna)] + + [ContractEvent(Hardfork.HF_Echidna, 0, name: "Designation", + "Role", ContractParameterType.Integer, + "BlockIndex", ContractParameterType.Integer, + "Old", ContractParameterType.Array, + "New", ContractParameterType.Array + )] + internal RoleManagement() : base() { } /// @@ -69,7 +78,18 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node list.AddRange(nodes); list.Sort(); engine.SnapshotCache.Add(key, new StorageItem(list)); - engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, new StackItem[] { (int)role, engine.PersistingBlock.Index })); + + if (engine.IsHardforkEnabled(Hardfork.HF_Echidna)) + { + var oldNodes = new VM.Types.Array(engine.ReferenceCounter, GetDesignatedByRole(engine.Snapshot, role, index - 1).Select(u => (ByteString)u.EncodePoint(true))); + var newNodes = new VM.Types.Array(engine.ReferenceCounter, nodes.Select(u => (ByteString)u.EncodePoint(true))); + + engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, [(int)role, engine.PersistingBlock.Index, oldNodes, newNodes])); + } + else + { + engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, [(int)role, engine.PersistingBlock.Index])); + } } private class NodeList : InteroperableList diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index f9a3089f9d..627a9fdd3c 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -80,6 +80,24 @@ public void TestActiveDeprecatedIn() Assert.IsFalse(NativeContract.IsActive(new active() { ActiveIn = null, DeprecatedIn = Hardfork.HF_Cockatrice }, settings.IsHardforkEnabled, 20)); } + [TestMethod] + public void TestActiveDeprecatedInRoleManagement() + { + string json = UT_ProtocolSettings.CreateHKSettings("\"HF_Echidna\": 20"); + var file = Path.GetTempFileName(); + File.WriteAllText(file, json); + ProtocolSettings settings = ProtocolSettings.Load(file, false); + File.Delete(file); + + var before = NativeContract.RoleManagement.GetContractState(settings.IsHardforkEnabled, 19); + var after = NativeContract.RoleManagement.GetContractState(settings.IsHardforkEnabled, 20); + + Assert.AreEqual(2, before.Manifest.Abi.Events[0].Parameters.Length); + Assert.AreEqual(1, before.Manifest.Abi.Events.Length); + Assert.AreEqual(4, after.Manifest.Abi.Events[0].Parameters.Length); + Assert.AreEqual(1, after.Manifest.Abi.Events.Length); + } + [TestMethod] public void TestGetContract() { From 37bf0cb81a64661e2939af0f2c7d8f5af0c610af Mon Sep 17 00:00:00 2001 From: Jimmy Date: Fri, 9 Aug 2024 03:42:18 +0800 Subject: [PATCH 19/29] [Neo Core StdLib] Add Base64url (#3453) * add base64url * active in * update placehold hf height * fix hf issue and move methods to proper place. * fix test * use identifymodel instead. --- src/Neo.CLI/config.fs.mainnet.json | 2 +- src/Neo.CLI/config.json | 2 +- src/Neo.CLI/config.mainnet.json | 2 +- src/Neo.CLI/config.testnet.json | 2 +- src/Neo/Neo.csproj | 1 + src/Neo/SmartContract/Native/StdLib.cs | 23 +++++++++++++++++++ .../SmartContract/Native/UT_NativeContract.cs | 2 +- .../SmartContract/Native/UT_StdLib.cs | 20 ++++++++++++++++ 8 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/Neo.CLI/config.fs.mainnet.json b/src/Neo.CLI/config.fs.mainnet.json index c12372b43b..bbd17978e3 100644 --- a/src/Neo.CLI/config.fs.mainnet.json +++ b/src/Neo.CLI/config.fs.mainnet.json @@ -41,7 +41,7 @@ "HF_Basilisk": 4500000, "HF_Cockatrice": 5800000, "HF_Domovoi": 5800000, - "HF_Echidna": 0 + "HF_Echidna": 5800001 }, "StandbyCommittee": [ "026fa34ec057d74c2fdf1a18e336d0bd597ea401a0b2ad57340d5c220d09f44086", diff --git a/src/Neo.CLI/config.json b/src/Neo.CLI/config.json index 9e97ec1f00..9590fc60fd 100644 --- a/src/Neo.CLI/config.json +++ b/src/Neo.CLI/config.json @@ -39,7 +39,7 @@ "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, "HF_Domovoi": 5570000, - "HF_Echidna": 0 + "HF_Echidna": 5570001 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.mainnet.json b/src/Neo.CLI/config.mainnet.json index 9e97ec1f00..9590fc60fd 100644 --- a/src/Neo.CLI/config.mainnet.json +++ b/src/Neo.CLI/config.mainnet.json @@ -39,7 +39,7 @@ "HF_Basilisk": 4120000, "HF_Cockatrice": 5450000, "HF_Domovoi": 5570000, - "HF_Echidna": 0 + "HF_Echidna": 5570001 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo.CLI/config.testnet.json b/src/Neo.CLI/config.testnet.json index 88a04794f0..8bcd6d8956 100644 --- a/src/Neo.CLI/config.testnet.json +++ b/src/Neo.CLI/config.testnet.json @@ -39,7 +39,7 @@ "HF_Basilisk": 2680000, "HF_Cockatrice": 3967000, "HF_Domovoi": 4144000, - "HF_Echidna": 0 + "HF_Echidna": 4144001 }, "InitialGasDistribution": 5200000000000000, "ValidatorsCount": 7, diff --git a/src/Neo/Neo.csproj b/src/Neo/Neo.csproj index 89c200e31b..25d80ba91f 100644 --- a/src/Neo/Neo.csproj +++ b/src/Neo/Neo.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Neo/SmartContract/Native/StdLib.cs b/src/Neo/SmartContract/Native/StdLib.cs index f8fa9efcc2..1b4030d9f5 100644 --- a/src/Neo/SmartContract/Native/StdLib.cs +++ b/src/Neo/SmartContract/Native/StdLib.cs @@ -11,6 +11,7 @@ #pragma warning disable IDE0051 +using Microsoft.IdentityModel.Tokens; using Neo.Cryptography; using Neo.Json; using Neo.VM.Types; @@ -131,6 +132,28 @@ public static byte[] Base64Decode([MaxLength(MaxInputLength)] string s) return Convert.FromBase64String(s); } + /// + /// Encodes a byte array into a base64Url string. + /// + /// The base64Url to be encoded. + /// The encoded base64Url string. + [ContractMethod(Hardfork.HF_Echidna, CpuFee = 1 << 5)] + public static string Base64UrlEncode([MaxLength(MaxInputLength)] string data) + { + return Base64UrlEncoder.Encode(data); + } + + /// + /// Decodes a byte array from a base64Url string. + /// + /// The base64Url string. + /// The decoded base64Url string. + [ContractMethod(Hardfork.HF_Echidna, CpuFee = 1 << 5)] + public static string Base64UrlDecode([MaxLength(MaxInputLength)] string s) + { + return Base64UrlEncoder.Decode(s); + } + /// /// Encodes a byte array into a base58 . /// diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index 627a9fdd3c..26e00a3c2d 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -41,7 +41,7 @@ public void TestSetup() _nativeStates = new Dictionary { {"ContractManagement", """{"id":-1,"updatecounter":0,"hash":"0xfffdc93764dbaddd97c48f252a53ea4643faa3fd","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"ContractManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Array","offset":0,"safe":false},{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Array","offset":7,"safe":false},{"name":"destroy","parameters":[],"returntype":"Void","offset":14,"safe":false},{"name":"getContract","parameters":[{"name":"hash","type":"Hash160"}],"returntype":"Array","offset":21,"safe":true},{"name":"getContractById","parameters":[{"name":"id","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getContractHashes","parameters":[],"returntype":"InteropInterface","offset":35,"safe":true},{"name":"getMinimumDeploymentFee","parameters":[],"returntype":"Integer","offset":42,"safe":true},{"name":"hasMethod","parameters":[{"name":"hash","type":"Hash160"},{"name":"method","type":"String"},{"name":"pcount","type":"Integer"}],"returntype":"Boolean","offset":49,"safe":true},{"name":"setMinimumDeploymentFee","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":56,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Void","offset":63,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","offset":70,"safe":false}],"events":[{"name":"Deploy","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Update","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Destroy","parameters":[{"name":"Hash","type":"Hash160"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}""" }, - {"StdLib", """{"id":-2,"updatecounter":0,"hash":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dA","checksum":1991619121},"manifest":{"name":"StdLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"atoi","parameters":[{"name":"value","type":"String"}],"returntype":"Integer","offset":0,"safe":true},{"name":"atoi","parameters":[{"name":"value","type":"String"},{"name":"base","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"base58CheckDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":14,"safe":true},{"name":"base58CheckEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":21,"safe":true},{"name":"base58Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":28,"safe":true},{"name":"base58Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":35,"safe":true},{"name":"base64Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"base64Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":49,"safe":true},{"name":"deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"Any","offset":56,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"}],"returntype":"String","offset":63,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"},{"name":"base","type":"Integer"}],"returntype":"String","offset":70,"safe":true},{"name":"jsonDeserialize","parameters":[{"name":"json","type":"ByteArray"}],"returntype":"Any","offset":77,"safe":true},{"name":"jsonSerialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":84,"safe":true},{"name":"memoryCompare","parameters":[{"name":"str1","type":"ByteArray"},{"name":"str2","type":"ByteArray"}],"returntype":"Integer","offset":91,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"}],"returntype":"Integer","offset":98,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"}],"returntype":"Integer","offset":105,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"},{"name":"backward","type":"Boolean"}],"returntype":"Integer","offset":112,"safe":true},{"name":"serialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":119,"safe":true},{"name":"strLen","parameters":[{"name":"str","type":"String"}],"returntype":"Integer","offset":126,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"}],"returntype":"Array","offset":133,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"},{"name":"removeEmptyEntries","type":"Boolean"}],"returntype":"Array","offset":140,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, + {"StdLib", """{"id":-2,"updatecounter":0,"hash":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2681632925},"manifest":{"name":"StdLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"atoi","parameters":[{"name":"value","type":"String"}],"returntype":"Integer","offset":0,"safe":true},{"name":"atoi","parameters":[{"name":"value","type":"String"},{"name":"base","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"base58CheckDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":14,"safe":true},{"name":"base58CheckEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":21,"safe":true},{"name":"base58Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":28,"safe":true},{"name":"base58Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":35,"safe":true},{"name":"base64Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"base64Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":49,"safe":true},{"name":"base64UrlDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":56,"safe":true},{"name":"base64UrlEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":63,"safe":true},{"name":"deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"Any","offset":70,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"}],"returntype":"String","offset":77,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"},{"name":"base","type":"Integer"}],"returntype":"String","offset":84,"safe":true},{"name":"jsonDeserialize","parameters":[{"name":"json","type":"ByteArray"}],"returntype":"Any","offset":91,"safe":true},{"name":"jsonSerialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":98,"safe":true},{"name":"memoryCompare","parameters":[{"name":"str1","type":"ByteArray"},{"name":"str2","type":"ByteArray"}],"returntype":"Integer","offset":105,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"}],"returntype":"Integer","offset":112,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"}],"returntype":"Integer","offset":119,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"},{"name":"backward","type":"Boolean"}],"returntype":"Integer","offset":126,"safe":true},{"name":"serialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":133,"safe":true},{"name":"strLen","parameters":[{"name":"str","type":"String"}],"returntype":"Integer","offset":140,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"}],"returntype":"Array","offset":147,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"},{"name":"removeEmptyEntries","type":"Boolean"}],"returntype":"Array","offset":154,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"CryptoLib", """{"id":-3,"updatecounter":0,"hash":"0x726cb6e0cd8628a1350a611384688911ab75f51b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"CryptoLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"bls12381Add","parameters":[{"name":"x","type":"InteropInterface"},{"name":"y","type":"InteropInterface"}],"returntype":"InteropInterface","offset":0,"safe":true},{"name":"bls12381Deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"InteropInterface","offset":7,"safe":true},{"name":"bls12381Equal","parameters":[{"name":"x","type":"InteropInterface"},{"name":"y","type":"InteropInterface"}],"returntype":"Boolean","offset":14,"safe":true},{"name":"bls12381Mul","parameters":[{"name":"x","type":"InteropInterface"},{"name":"mul","type":"ByteArray"},{"name":"neg","type":"Boolean"}],"returntype":"InteropInterface","offset":21,"safe":true},{"name":"bls12381Pairing","parameters":[{"name":"g1","type":"InteropInterface"},{"name":"g2","type":"InteropInterface"}],"returntype":"InteropInterface","offset":28,"safe":true},{"name":"bls12381Serialize","parameters":[{"name":"g","type":"InteropInterface"}],"returntype":"ByteArray","offset":35,"safe":true},{"name":"keccak256","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"murmur32","parameters":[{"name":"data","type":"ByteArray"},{"name":"seed","type":"Integer"}],"returntype":"ByteArray","offset":49,"safe":true},{"name":"ripemd160","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":56,"safe":true},{"name":"sha256","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":63,"safe":true},{"name":"verifyWithECDsa","parameters":[{"name":"message","type":"ByteArray"},{"name":"pubkey","type":"ByteArray"},{"name":"signature","type":"ByteArray"},{"name":"curveHash","type":"Integer"}],"returntype":"Boolean","offset":70,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"LedgerContract", """{"id":-4,"updatecounter":0,"hash":"0xda65b600f7124ce6c79950c1772a36403104f2be","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1110259869},"manifest":{"name":"LedgerContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"currentHash","parameters":[],"returntype":"Hash256","offset":0,"safe":true},{"name":"currentIndex","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getBlock","parameters":[{"name":"indexOrHash","type":"ByteArray"}],"returntype":"Array","offset":14,"safe":true},{"name":"getTransaction","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Array","offset":21,"safe":true},{"name":"getTransactionFromBlock","parameters":[{"name":"blockIndexOrHash","type":"ByteArray"},{"name":"txIndex","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getTransactionHeight","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Integer","offset":35,"safe":true},{"name":"getTransactionSigners","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Array","offset":42,"safe":true},{"name":"getTransactionVMState","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Integer","offset":49,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"NeoToken", """{"id":-5,"updatecounter":0,"hash":"0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1325686241},"manifest":{"name":"NeoToken","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getAccountState","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Array","offset":14,"safe":true},{"name":"getAllCandidates","parameters":[],"returntype":"InteropInterface","offset":21,"safe":true},{"name":"getCandidateVote","parameters":[{"name":"pubKey","type":"PublicKey"}],"returntype":"Integer","offset":28,"safe":true},{"name":"getCandidates","parameters":[],"returntype":"Array","offset":35,"safe":true},{"name":"getCommittee","parameters":[],"returntype":"Array","offset":42,"safe":true},{"name":"getCommitteeAddress","parameters":[],"returntype":"Hash160","offset":49,"safe":true},{"name":"getGasPerBlock","parameters":[],"returntype":"Integer","offset":56,"safe":true},{"name":"getNextBlockValidators","parameters":[],"returntype":"Array","offset":63,"safe":true},{"name":"getRegisterPrice","parameters":[],"returntype":"Integer","offset":70,"safe":true},{"name":"registerCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":77,"safe":false},{"name":"setGasPerBlock","parameters":[{"name":"gasPerBlock","type":"Integer"}],"returntype":"Void","offset":84,"safe":false},{"name":"setRegisterPrice","parameters":[{"name":"registerPrice","type":"Integer"}],"returntype":"Void","offset":91,"safe":false},{"name":"symbol","parameters":[],"returntype":"String","offset":98,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":105,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":112,"safe":false},{"name":"unclaimedGas","parameters":[{"name":"account","type":"Hash160"},{"name":"end","type":"Integer"}],"returntype":"Integer","offset":119,"safe":true},{"name":"unregisterCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":126,"safe":false},{"name":"vote","parameters":[{"name":"account","type":"Hash160"},{"name":"voteTo","type":"PublicKey"}],"returntype":"Boolean","offset":133,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]},{"name":"CandidateStateChanged","parameters":[{"name":"pubkey","type":"PublicKey"},{"name":"registered","type":"Boolean"},{"name":"votes","type":"Integer"}]},{"name":"Vote","parameters":[{"name":"account","type":"Hash160"},{"name":"from","type":"PublicKey"},{"name":"to","type":"PublicKey"},{"name":"amount","type":"Integer"}]},{"name":"CommitteeChanged","parameters":[{"name":"old","type":"Array"},{"name":"new","type":"Array"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs index 1dffb3d384..f9761bee07 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs @@ -406,5 +406,25 @@ public void TestRuntime_Deserialize() Assert.AreEqual(engine.ResultStack.Pop().GetInteger(), 100); Assert.AreEqual(engine.ResultStack.Pop().GetString(), "test"); } + + [TestMethod] + public void TestBase64Url() + { + var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + using (var script = new ScriptBuilder()) + { + // Test encoding + script.EmitDynamicCall(NativeContract.StdLib.Hash, "base64UrlEncode", "Subject=test@example.com&Issuer=https://example.com"); + script.EmitDynamicCall(NativeContract.StdLib.Hash, "base64UrlDecode", "U3ViamVjdD10ZXN0QGV4YW1wbGUuY29tJklzc3Vlcj1odHRwczovL2V4YW1wbGUuY29t"); + + using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshotCache, settings: TestBlockchain.TheNeoSystem.Settings); + engine.LoadScript(script.ToArray()); + + Assert.AreEqual(engine.Execute(), VMState.HALT); + Assert.AreEqual(2, engine.ResultStack.Count); + Assert.AreEqual("Subject=test@example.com&Issuer=https://example.com", engine.ResultStack.Pop()); + Assert.AreEqual("U3ViamVjdD10ZXN0QGV4YW1wbGUuY29tJklzc3Vlcj1odHRwczovL2V4YW1wbGUuY29t", engine.ResultStack.Pop().GetString()); + } + } } } From 7dba1303c9b3d7b7f8b6a470e7d185d8d0903302 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Wed, 6 Nov 2024 12:42:42 +0800 Subject: [PATCH 20/29] format --- src/Neo/SmartContract/Native/RoleManagement.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index ecedba4c86..084d6fdd36 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -78,7 +78,7 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node list.AddRange(nodes); list.Sort(); engine.SnapshotCache.Add(key, new StorageItem(list)); - + if (engine.IsHardforkEnabled(Hardfork.HF_Echidna)) { var oldNodes = new VM.Types.Array(engine.ReferenceCounter, GetDesignatedByRole(engine.Snapshot, role, index - 1).Select(u => (ByteString)u.EncodePoint(true))); From 6e780c049b441f2b4ddf5e4e5975f9500b4a2101 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 17 Nov 2024 07:44:14 -0500 Subject: [PATCH 21/29] Fixed typo --- tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index 26e00a3c2d..240e202d9b 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -83,7 +83,7 @@ public void TestActiveDeprecatedIn() [TestMethod] public void TestActiveDeprecatedInRoleManagement() { - string json = UT_ProtocolSettings.CreateHKSettings("\"HF_Echidna\": 20"); + string json = UT_ProtocolSettings.CreateHFSettings("\"HF_Echidna\": 20"); var file = Path.GetTempFileName(); File.WriteAllText(file, json); ProtocolSettings settings = ProtocolSettings.Load(file, false); From 02d6ab9e30354863207cf14018946963adc39d27 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 17 Nov 2024 09:12:56 -0500 Subject: [PATCH 22/29] Added back #3397 --- .../SmartContract/Native/RoleManagement.cs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index e57f3f3e83..2577300720 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -26,7 +26,16 @@ public sealed class RoleManagement : NativeContract { [ContractEvent(0, name: "Designation", "Role", ContractParameterType.Integer, - "BlockIndex", ContractParameterType.Integer)] + "BlockIndex", ContractParameterType.Integer, + Hardfork.HF_Echidna)] + + [ContractEvent(Hardfork.HF_Echidna, 0, name: "Designation", + "Role", ContractParameterType.Integer, + "BlockIndex", ContractParameterType.Integer, + "Old", ContractParameterType.Array, + "New", ContractParameterType.Array + )] + internal RoleManagement() : base() { } /// @@ -51,6 +60,7 @@ public ECPoint[] GetDesignatedByRole(DataCache snapshot, Role role, uint index) } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States | CallFlags.AllowNotify)] + [Obsolete] private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] nodes) { if (nodes.Length == 0 || nodes.Length > 32) @@ -69,7 +79,17 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node list.AddRange(nodes); list.Sort(); engine.SnapshotCache.Add(key, new StorageItem(list)); - engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, new StackItem[] { (int)role, engine.PersistingBlock.Index })); + if (engine.IsHardforkEnabled(Hardfork.HF_Echidna)) + { + var oldNodes = new VM.Types.Array(engine.ReferenceCounter, GetDesignatedByRole(engine.Snapshot, role, index - 1).Select(u => (ByteString)u.EncodePoint(true))); + var newNodes = new VM.Types.Array(engine.ReferenceCounter, nodes.Select(u => (ByteString)u.EncodePoint(true))); + + engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, [(int)role, engine.PersistingBlock.Index, oldNodes, newNodes])); + } + else + { + engine.SendNotification(Hash, "Designation", new VM.Types.Array(engine.ReferenceCounter, [(int)role, engine.PersistingBlock.Index])); + } } private class NodeList : InteroperableList From 8fb30df9dd7a129a68eef69db7d879cbbdade91f Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 17 Nov 2024 09:25:12 -0500 Subject: [PATCH 23/29] Fixed tests --- global.json | 2 +- tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/global.json b/global.json index beefe210a1..41c9ad2ed8 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.202", + "version": "9.0.100", "rollForward": "latestFeature", "allowPrerelease": false } diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index 240e202d9b..5de9448013 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -41,13 +41,13 @@ public void TestSetup() _nativeStates = new Dictionary { {"ContractManagement", """{"id":-1,"updatecounter":0,"hash":"0xfffdc93764dbaddd97c48f252a53ea4643faa3fd","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"ContractManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Array","offset":0,"safe":false},{"name":"deploy","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Array","offset":7,"safe":false},{"name":"destroy","parameters":[],"returntype":"Void","offset":14,"safe":false},{"name":"getContract","parameters":[{"name":"hash","type":"Hash160"}],"returntype":"Array","offset":21,"safe":true},{"name":"getContractById","parameters":[{"name":"id","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getContractHashes","parameters":[],"returntype":"InteropInterface","offset":35,"safe":true},{"name":"getMinimumDeploymentFee","parameters":[],"returntype":"Integer","offset":42,"safe":true},{"name":"hasMethod","parameters":[{"name":"hash","type":"Hash160"},{"name":"method","type":"String"},{"name":"pcount","type":"Integer"}],"returntype":"Boolean","offset":49,"safe":true},{"name":"setMinimumDeploymentFee","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":56,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"}],"returntype":"Void","offset":63,"safe":false},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","offset":70,"safe":false}],"events":[{"name":"Deploy","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Update","parameters":[{"name":"Hash","type":"Hash160"}]},{"name":"Destroy","parameters":[{"name":"Hash","type":"Hash160"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}""" }, - {"StdLib", """{"id":-2,"updatecounter":0,"hash":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2681632925},"manifest":{"name":"StdLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"atoi","parameters":[{"name":"value","type":"String"}],"returntype":"Integer","offset":0,"safe":true},{"name":"atoi","parameters":[{"name":"value","type":"String"},{"name":"base","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"base58CheckDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":14,"safe":true},{"name":"base58CheckEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":21,"safe":true},{"name":"base58Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":28,"safe":true},{"name":"base58Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":35,"safe":true},{"name":"base64Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"base64Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":49,"safe":true},{"name":"base64UrlDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":56,"safe":true},{"name":"base64UrlEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":63,"safe":true},{"name":"deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"Any","offset":70,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"}],"returntype":"String","offset":77,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"},{"name":"base","type":"Integer"}],"returntype":"String","offset":84,"safe":true},{"name":"jsonDeserialize","parameters":[{"name":"json","type":"ByteArray"}],"returntype":"Any","offset":91,"safe":true},{"name":"jsonSerialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":98,"safe":true},{"name":"memoryCompare","parameters":[{"name":"str1","type":"ByteArray"},{"name":"str2","type":"ByteArray"}],"returntype":"Integer","offset":105,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"}],"returntype":"Integer","offset":112,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"}],"returntype":"Integer","offset":119,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"},{"name":"backward","type":"Boolean"}],"returntype":"Integer","offset":126,"safe":true},{"name":"serialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":133,"safe":true},{"name":"strLen","parameters":[{"name":"str","type":"String"}],"returntype":"Integer","offset":140,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"}],"returntype":"Array","offset":147,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"},{"name":"removeEmptyEntries","type":"Boolean"}],"returntype":"Array","offset":154,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, + {"StdLib", """{"id":-2,"updatecounter":0,"hash":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2681632925},"manifest":{"name":"StdLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"atoi","parameters":[{"name":"value","type":"String"}],"returntype":"Integer","offset":0,"safe":true},{"name":"atoi","parameters":[{"name":"value","type":"String"},{"name":"base","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"base58CheckDecode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":14,"safe":true},{"name":"base58CheckEncode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":21,"safe":true},{"name":"base58Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":28,"safe":true},{"name":"base58Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":35,"safe":true},{"name":"base64Decode","parameters":[{"name":"s","type":"String"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"base64Encode","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"String","offset":49,"safe":true},{"name":"base64UrlDecode","parameters":[{"name":"s","type":"String"}],"returntype":"String","offset":56,"safe":true},{"name":"base64UrlEncode","parameters":[{"name":"data","type":"String"}],"returntype":"String","offset":63,"safe":true},{"name":"deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"Any","offset":70,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"}],"returntype":"String","offset":77,"safe":true},{"name":"itoa","parameters":[{"name":"value","type":"Integer"},{"name":"base","type":"Integer"}],"returntype":"String","offset":84,"safe":true},{"name":"jsonDeserialize","parameters":[{"name":"json","type":"ByteArray"}],"returntype":"Any","offset":91,"safe":true},{"name":"jsonSerialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":98,"safe":true},{"name":"memoryCompare","parameters":[{"name":"str1","type":"ByteArray"},{"name":"str2","type":"ByteArray"}],"returntype":"Integer","offset":105,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"}],"returntype":"Integer","offset":112,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"}],"returntype":"Integer","offset":119,"safe":true},{"name":"memorySearch","parameters":[{"name":"mem","type":"ByteArray"},{"name":"value","type":"ByteArray"},{"name":"start","type":"Integer"},{"name":"backward","type":"Boolean"}],"returntype":"Integer","offset":126,"safe":true},{"name":"serialize","parameters":[{"name":"item","type":"Any"}],"returntype":"ByteArray","offset":133,"safe":true},{"name":"strLen","parameters":[{"name":"str","type":"String"}],"returntype":"Integer","offset":140,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"}],"returntype":"Array","offset":147,"safe":true},{"name":"stringSplit","parameters":[{"name":"str","type":"String"},{"name":"separator","type":"String"},{"name":"removeEmptyEntries","type":"Boolean"}],"returntype":"Array","offset":154,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"CryptoLib", """{"id":-3,"updatecounter":0,"hash":"0x726cb6e0cd8628a1350a611384688911ab75f51b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"CryptoLib","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"bls12381Add","parameters":[{"name":"x","type":"InteropInterface"},{"name":"y","type":"InteropInterface"}],"returntype":"InteropInterface","offset":0,"safe":true},{"name":"bls12381Deserialize","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"InteropInterface","offset":7,"safe":true},{"name":"bls12381Equal","parameters":[{"name":"x","type":"InteropInterface"},{"name":"y","type":"InteropInterface"}],"returntype":"Boolean","offset":14,"safe":true},{"name":"bls12381Mul","parameters":[{"name":"x","type":"InteropInterface"},{"name":"mul","type":"ByteArray"},{"name":"neg","type":"Boolean"}],"returntype":"InteropInterface","offset":21,"safe":true},{"name":"bls12381Pairing","parameters":[{"name":"g1","type":"InteropInterface"},{"name":"g2","type":"InteropInterface"}],"returntype":"InteropInterface","offset":28,"safe":true},{"name":"bls12381Serialize","parameters":[{"name":"g","type":"InteropInterface"}],"returntype":"ByteArray","offset":35,"safe":true},{"name":"keccak256","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":42,"safe":true},{"name":"murmur32","parameters":[{"name":"data","type":"ByteArray"},{"name":"seed","type":"Integer"}],"returntype":"ByteArray","offset":49,"safe":true},{"name":"ripemd160","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":56,"safe":true},{"name":"sha256","parameters":[{"name":"data","type":"ByteArray"}],"returntype":"ByteArray","offset":63,"safe":true},{"name":"verifyWithECDsa","parameters":[{"name":"message","type":"ByteArray"},{"name":"pubkey","type":"ByteArray"},{"name":"signature","type":"ByteArray"},{"name":"curveHash","type":"Integer"}],"returntype":"Boolean","offset":70,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"LedgerContract", """{"id":-4,"updatecounter":0,"hash":"0xda65b600f7124ce6c79950c1772a36403104f2be","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1110259869},"manifest":{"name":"LedgerContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"currentHash","parameters":[],"returntype":"Hash256","offset":0,"safe":true},{"name":"currentIndex","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getBlock","parameters":[{"name":"indexOrHash","type":"ByteArray"}],"returntype":"Array","offset":14,"safe":true},{"name":"getTransaction","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Array","offset":21,"safe":true},{"name":"getTransactionFromBlock","parameters":[{"name":"blockIndexOrHash","type":"ByteArray"},{"name":"txIndex","type":"Integer"}],"returntype":"Array","offset":28,"safe":true},{"name":"getTransactionHeight","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Integer","offset":35,"safe":true},{"name":"getTransactionSigners","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Array","offset":42,"safe":true},{"name":"getTransactionVMState","parameters":[{"name":"hash","type":"Hash256"}],"returntype":"Integer","offset":49,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"NeoToken", """{"id":-5,"updatecounter":0,"hash":"0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1325686241},"manifest":{"name":"NeoToken","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"getAccountState","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Array","offset":14,"safe":true},{"name":"getAllCandidates","parameters":[],"returntype":"InteropInterface","offset":21,"safe":true},{"name":"getCandidateVote","parameters":[{"name":"pubKey","type":"PublicKey"}],"returntype":"Integer","offset":28,"safe":true},{"name":"getCandidates","parameters":[],"returntype":"Array","offset":35,"safe":true},{"name":"getCommittee","parameters":[],"returntype":"Array","offset":42,"safe":true},{"name":"getCommitteeAddress","parameters":[],"returntype":"Hash160","offset":49,"safe":true},{"name":"getGasPerBlock","parameters":[],"returntype":"Integer","offset":56,"safe":true},{"name":"getNextBlockValidators","parameters":[],"returntype":"Array","offset":63,"safe":true},{"name":"getRegisterPrice","parameters":[],"returntype":"Integer","offset":70,"safe":true},{"name":"registerCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":77,"safe":false},{"name":"setGasPerBlock","parameters":[{"name":"gasPerBlock","type":"Integer"}],"returntype":"Void","offset":84,"safe":false},{"name":"setRegisterPrice","parameters":[{"name":"registerPrice","type":"Integer"}],"returntype":"Void","offset":91,"safe":false},{"name":"symbol","parameters":[],"returntype":"String","offset":98,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":105,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":112,"safe":false},{"name":"unclaimedGas","parameters":[{"name":"account","type":"Hash160"},{"name":"end","type":"Integer"}],"returntype":"Integer","offset":119,"safe":true},{"name":"unregisterCandidate","parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean","offset":126,"safe":false},{"name":"vote","parameters":[{"name":"account","type":"Hash160"},{"name":"voteTo","type":"PublicKey"}],"returntype":"Boolean","offset":133,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]},{"name":"CandidateStateChanged","parameters":[{"name":"pubkey","type":"PublicKey"},{"name":"registered","type":"Boolean"},{"name":"votes","type":"Integer"}]},{"name":"Vote","parameters":[{"name":"account","type":"Hash160"},{"name":"from","type":"PublicKey"},{"name":"to","type":"PublicKey"},{"name":"amount","type":"Integer"}]},{"name":"CommitteeChanged","parameters":[{"name":"old","type":"Array"},{"name":"new","type":"Array"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"GasToken", """{"id":-6,"updatecounter":0,"hash":"0xd2a4cff31913016155e38e474a2c06d08be276cf","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2663858513},"manifest":{"name":"GasToken","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"symbol","parameters":[],"returntype":"String","offset":14,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":21,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":28,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"PolicyContract", """{"id":-7,"updatecounter":0,"hash":"0xcc5e4edd9f5f8dba8bb65734541df7a1c081c67b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1094259016},"manifest":{"name":"PolicyContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"blockAccount","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean","offset":0,"safe":false},{"name":"getAttributeFee","parameters":[{"name":"attributeType","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"getExecFeeFactor","parameters":[],"returntype":"Integer","offset":14,"safe":true},{"name":"getFeePerByte","parameters":[],"returntype":"Integer","offset":21,"safe":true},{"name":"getStoragePrice","parameters":[],"returntype":"Integer","offset":28,"safe":true},{"name":"isBlocked","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean","offset":35,"safe":true},{"name":"setAttributeFee","parameters":[{"name":"attributeType","type":"Integer"},{"name":"value","type":"Integer"}],"returntype":"Void","offset":42,"safe":false},{"name":"setExecFeeFactor","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":49,"safe":false},{"name":"setFeePerByte","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":56,"safe":false},{"name":"setStoragePrice","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":63,"safe":false},{"name":"unblockAccount","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean","offset":70,"safe":false}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, - {"RoleManagement", """{"id":-8,"updatecounter":0,"hash":"0x49cf4e5378ffcd4dec034fd98a174c5491e395e2","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0A=","checksum":983638438},"manifest":{"name":"RoleManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"designateAsRole","parameters":[{"name":"role","type":"Integer"},{"name":"nodes","type":"Array"}],"returntype":"Void","offset":0,"safe":false},{"name":"getDesignatedByRole","parameters":[{"name":"role","type":"Integer"},{"name":"index","type":"Integer"}],"returntype":"Array","offset":7,"safe":true}],"events":[{"name":"Designation","parameters":[{"name":"Role","type":"Integer"},{"name":"BlockIndex","type":"Integer"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, + {"RoleManagement", """{"id":-8,"updatecounter":0,"hash":"0x49cf4e5378ffcd4dec034fd98a174c5491e395e2","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0A=","checksum":983638438},"manifest":{"name":"RoleManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"designateAsRole","parameters":[{"name":"role","type":"Integer"},{"name":"nodes","type":"Array"}],"returntype":"Void","offset":0,"safe":false},{"name":"getDesignatedByRole","parameters":[{"name":"role","type":"Integer"},{"name":"index","type":"Integer"}],"returntype":"Array","offset":7,"safe":true}],"events":[{"name":"Designation","parameters":[{"name":"Role","type":"Integer"},{"name":"BlockIndex","type":"Integer"},{"name":"Old","type":"Array"},{"name":"New","type":"Array"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, {"OracleContract", """{"id":-9,"updatecounter":0,"hash":"0xfe924b7cfe89ddd271abaf7210a80a7e11178758","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2663858513},"manifest":{"name":"OracleContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"finish","parameters":[],"returntype":"Void","offset":0,"safe":false},{"name":"getPrice","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"request","parameters":[{"name":"url","type":"String"},{"name":"filter","type":"String"},{"name":"callback","type":"String"},{"name":"userData","type":"Any"},{"name":"gasForResponse","type":"Integer"}],"returntype":"Void","offset":14,"safe":false},{"name":"setPrice","parameters":[{"name":"price","type":"Integer"}],"returntype":"Void","offset":21,"safe":false},{"name":"verify","parameters":[],"returntype":"Boolean","offset":28,"safe":true}],"events":[{"name":"OracleRequest","parameters":[{"name":"Id","type":"Integer"},{"name":"RequestContract","type":"Hash160"},{"name":"Url","type":"String"},{"name":"Filter","type":"String"}]},{"name":"OracleResponse","parameters":[{"name":"Id","type":"Integer"},{"name":"OriginalTx","type":"Hash256"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}, }; } From f9244ebb9fab915b05dee5414cbfb1c4bf9097e0 Mon Sep 17 00:00:00 2001 From: Christopher Schuchardt Date: Sun, 17 Nov 2024 09:26:53 -0500 Subject: [PATCH 24/29] fixed global.json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 41c9ad2ed8..beefe210a1 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.100", + "version": "8.0.202", "rollForward": "latestFeature", "allowPrerelease": false } From 4b6542b1b04b5e5fe1fb0c40947c5670f3541fcc Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 28 Nov 2024 11:27:45 +0100 Subject: [PATCH 25/29] Add min and max ut --- tests/Neo.Json.UnitTests/UT_JNumber.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Neo.Json.UnitTests/UT_JNumber.cs b/tests/Neo.Json.UnitTests/UT_JNumber.cs index 58f01dc5b7..082598c126 100644 --- a/tests/Neo.Json.UnitTests/UT_JNumber.cs +++ b/tests/Neo.Json.UnitTests/UT_JNumber.cs @@ -49,6 +49,8 @@ public void TestBigInteger() ((JNumber)BigInteger.One).AsNumber().Should().Be(1); ((JNumber)BigInteger.Zero).AsNumber().Should().Be(0); ((JNumber)BigInteger.MinusOne).AsNumber().Should().Be(-1); + ((JNumber)JNumber.MAX_SAFE_INTEGER).AsNumber().Should().Be(JNumber.MAX_SAFE_INTEGER); + ((JNumber)JNumber.MIN_SAFE_INTEGER).AsNumber().Should().Be(JNumber.MIN_SAFE_INTEGER); } [TestMethod] From 758933e9b254232fe7cb3c2f3a1fa128be2e80ce Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 28 Nov 2024 11:29:30 +0100 Subject: [PATCH 26/29] Vitor suggestion --- src/Neo.Json/JNumber.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Neo.Json/JNumber.cs b/src/Neo.Json/JNumber.cs index 54b0f148e1..1efaeb6354 100644 --- a/src/Neo.Json/JNumber.cs +++ b/src/Neo.Json/JNumber.cs @@ -41,12 +41,12 @@ public class JNumber : JToken /// The value of the JSON token. public JNumber(double value = 0) { - if (!double.IsFinite(value)) - throw new ArgumentException("value is not finite", nameof(value)); if (value > MAX_SAFE_INTEGER) throw new ArgumentException("value is higher than MAX_SAFE_INTEGER", nameof(value)); if (value < MIN_SAFE_INTEGER) throw new ArgumentException("value is lower than MIN_SAFE_INTEGER", nameof(value)); + if (!double.IsFinite(value)) + throw new ArgumentException("value is not finite", nameof(value)); Value = value; } From 3599c81eba0df838baacf82b7ccaf9c166ad0dfa Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 28 Nov 2024 11:33:49 +0100 Subject: [PATCH 27/29] Avoid doble casting --- src/Neo.Json/JToken.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Neo.Json/JToken.cs b/src/Neo.Json/JToken.cs index 9db17334d2..b4dbf38ca3 100644 --- a/src/Neo.Json/JToken.cs +++ b/src/Neo.Json/JToken.cs @@ -296,12 +296,12 @@ public static implicit operator JToken(JToken?[] value) public static implicit operator JToken(bool value) { - return (JBoolean)value; + return new JBoolean(value); } public static implicit operator JToken(double value) { - return (JNumber)value; + return new JNumber(value); } public static implicit operator JToken(BigInteger value) From d41891672aa10bd42fe960b0551b1af42690a7ad Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 28 Nov 2024 11:46:08 +0100 Subject: [PATCH 28/29] Add HK checker --- src/Neo.Json/JNumber.cs | 15 ++++++++++----- src/Neo/SmartContract/JsonSerializer.cs | 9 +++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Neo.Json/JNumber.cs b/src/Neo.Json/JNumber.cs index 1efaeb6354..1bc604a3fc 100644 --- a/src/Neo.Json/JNumber.cs +++ b/src/Neo.Json/JNumber.cs @@ -39,12 +39,17 @@ public class JNumber : JToken /// Initializes a new instance of the class with the specified value. /// /// The value of the JSON token. - public JNumber(double value = 0) + /// True if we want to ensure that the value is in the limits. + public JNumber(double value = 0, bool checkMinMax = true) { - if (value > MAX_SAFE_INTEGER) - throw new ArgumentException("value is higher than MAX_SAFE_INTEGER", nameof(value)); - if (value < MIN_SAFE_INTEGER) - throw new ArgumentException("value is lower than MIN_SAFE_INTEGER", nameof(value)); + if (checkMinMax) + { + if (value > MAX_SAFE_INTEGER) + throw new ArgumentException("value is higher than MAX_SAFE_INTEGER", nameof(value)); + if (value < MIN_SAFE_INTEGER) + throw new ArgumentException("value is lower than MIN_SAFE_INTEGER", nameof(value)); + } + if (!double.IsFinite(value)) throw new ArgumentException("value is not finite", nameof(value)); diff --git a/src/Neo/SmartContract/JsonSerializer.cs b/src/Neo/SmartContract/JsonSerializer.cs index d0fec67cdd..482adefc54 100644 --- a/src/Neo/SmartContract/JsonSerializer.cs +++ b/src/Neo/SmartContract/JsonSerializer.cs @@ -35,14 +35,15 @@ public static class JsonSerializer /// Serializes a to a . /// /// The to serialize. + /// Hardfork checker /// The serialized object. - public static JToken Serialize(StackItem item) + public static JToken Serialize(StackItem item, Func hardforkChecker = null) { switch (item) { case Array array: { - return array.Select(p => Serialize(p)).ToArray(); + return array.Select(p => Serialize(p, hardforkChecker)).ToArray(); } case ByteString _: case Buffer _: @@ -51,7 +52,7 @@ public static JToken Serialize(StackItem item) } case Integer num: { - return num.GetInteger(); + return new JNumber((long)num.GetInteger(), hardforkChecker == null || hardforkChecker(Hardfork.HF_Echidna)); } case Boolean boolean: { @@ -66,7 +67,7 @@ public static JToken Serialize(StackItem item) if (entry.Key is not ByteString) throw new FormatException(); var key = entry.Key.GetString(); - var value = Serialize(entry.Value); + var value = Serialize(entry.Value, hardforkChecker); ret[key] = value; } From 04402c9d26adfbbe9678740d4f12e5f6eaa3043f Mon Sep 17 00:00:00 2001 From: Fernando Diaz Toledano Date: Thu, 28 Nov 2024 11:47:01 +0100 Subject: [PATCH 29/29] Reduce changes --- src/Neo.Json/JNumber.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Neo.Json/JNumber.cs b/src/Neo.Json/JNumber.cs index 1bc604a3fc..0842ed92e4 100644 --- a/src/Neo.Json/JNumber.cs +++ b/src/Neo.Json/JNumber.cs @@ -132,6 +132,11 @@ public static implicit operator JNumber(double value) return new JNumber(value); } + public static implicit operator JNumber(long value) + { + return new JNumber(value); + } + public static implicit operator JNumber(BigInteger value) { return new JNumber((long)value);