diff --git a/src/neo/SmartContract/ApplicationEngine.Contract.cs b/src/neo/SmartContract/ApplicationEngine.Contract.cs index f40ada522c..0d0312849d 100644 --- a/src/neo/SmartContract/ApplicationEngine.Contract.cs +++ b/src/neo/SmartContract/ApplicationEngine.Contract.cs @@ -38,9 +38,9 @@ protected internal void CallContract(UInt160 contractHash, string method, CallFl CallContractInternal(contract, md, callFlags, hasReturnValue, args); } - protected internal void CallNativeContract(string name) + protected internal void CallNativeContract(int id) { - NativeContract contract = NativeContract.GetContract(name); + NativeContract contract = NativeContract.GetContract(id); if (contract is null || contract.ActiveBlockIndex > Snapshot.Height) throw new InvalidOperationException(); contract.Invoke(this); diff --git a/src/neo/SmartContract/Native/ContractManagement.cs b/src/neo/SmartContract/Native/ContractManagement.cs index e161fa3ba3..a65d9fd100 100644 --- a/src/neo/SmartContract/Native/ContractManagement.cs +++ b/src/neo/SmartContract/Native/ContractManagement.cs @@ -14,8 +14,6 @@ namespace Neo.SmartContract.Native { public sealed class ContractManagement : NativeContract { - public override int Id => 0; - private const byte Prefix_MinimumDeploymentFee = 20; private const byte Prefix_NextAvailableId = 15; private const byte Prefix_Contract = 8; diff --git a/src/neo/SmartContract/Native/GasToken.cs b/src/neo/SmartContract/Native/GasToken.cs index db3e990c57..81e61b666c 100644 --- a/src/neo/SmartContract/Native/GasToken.cs +++ b/src/neo/SmartContract/Native/GasToken.cs @@ -6,7 +6,6 @@ namespace Neo.SmartContract.Native { public sealed class GasToken : FungibleToken { - public override int Id => -2; public override string Symbol => "GAS"; public override byte Decimals => 8; diff --git a/src/neo/SmartContract/Native/NameService.cs b/src/neo/SmartContract/Native/NameService.cs index d6be3d92c1..5defadeec3 100644 --- a/src/neo/SmartContract/Native/NameService.cs +++ b/src/neo/SmartContract/Native/NameService.cs @@ -19,7 +19,6 @@ namespace Neo.SmartContract.Native { public sealed class NameService : NonfungibleToken { - public override int Id => -6; public override string Symbol => "NNS"; private const byte Prefix_Roots = 10; diff --git a/src/neo/SmartContract/Native/NativeContract.cs b/src/neo/SmartContract/Native/NativeContract.cs index ee4749bfc7..fd47d5d6e2 100644 --- a/src/neo/SmartContract/Native/NativeContract.cs +++ b/src/neo/SmartContract/Native/NativeContract.cs @@ -14,11 +14,12 @@ namespace Neo.SmartContract.Native public abstract class NativeContract { private static readonly List contractsList = new List(); - private static readonly Dictionary contractsNameDictionary = new Dictionary(); + private static readonly Dictionary contractsIdDictionary = new Dictionary(); private static readonly Dictionary contractsHashDictionary = new Dictionary(); private readonly Dictionary methods = new Dictionary(); + private static int id_counter = 0; - public static IReadOnlyCollection Contracts { get; } = contractsList; + #region Named Native Contracts public static ContractManagement ContractManagement { get; } = new ContractManagement(); public static NeoToken NEO { get; } = new NeoToken(); public static GasToken GAS { get; } = new GasToken(); @@ -26,21 +27,24 @@ public abstract class NativeContract public static RoleManagement RoleManagement { get; } = new RoleManagement(); public static OracleContract Oracle { get; } = new OracleContract(); public static NameService NameService { get; } = new NameService(); + #endregion + public static IReadOnlyCollection Contracts { get; } = contractsList; public string Name => GetType().Name; public NefFile Nef { get; } public byte[] Script => Nef.Script; public UInt160 Hash { get; } - public abstract int Id { get; } + public int Id { get; } public ContractManifest Manifest { get; } public uint ActiveBlockIndex { get; } protected NativeContract() { + this.Id = --id_counter; byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitPush(Name); + sb.EmitPush(Id); sb.EmitSysCall(ApplicationEngine.System_Contract_CallNative); script = sb.ToArray(); } @@ -85,7 +89,7 @@ protected NativeContract() if (ProtocolSettings.Default.NativeActivations.TryGetValue(Name, out uint activationIndex)) this.ActiveBlockIndex = activationIndex; contractsList.Add(this); - contractsNameDictionary.Add(Name, this); + contractsIdDictionary.Add(Id, this); contractsHashDictionary.Add(Hash, this); } @@ -106,9 +110,9 @@ public static NativeContract GetContract(UInt160 hash) return contract; } - public static NativeContract GetContract(string name) + public static NativeContract GetContract(int id) { - contractsNameDictionary.TryGetValue(name, out var contract); + contractsIdDictionary.TryGetValue(id, out var contract); return contract; } diff --git a/src/neo/SmartContract/Native/NeoToken.cs b/src/neo/SmartContract/Native/NeoToken.cs index e9c80ed43d..375cb628ef 100644 --- a/src/neo/SmartContract/Native/NeoToken.cs +++ b/src/neo/SmartContract/Native/NeoToken.cs @@ -17,7 +17,6 @@ namespace Neo.SmartContract.Native { public sealed class NeoToken : FungibleToken { - public override int Id => -1; public override string Symbol => "NEO"; public override byte Decimals => 0; public BigInteger TotalAmount { get; } diff --git a/src/neo/SmartContract/Native/OracleContract.cs b/src/neo/SmartContract/Native/OracleContract.cs index 92e00c2565..b660f347ff 100644 --- a/src/neo/SmartContract/Native/OracleContract.cs +++ b/src/neo/SmartContract/Native/OracleContract.cs @@ -28,8 +28,6 @@ public sealed class OracleContract : NativeContract private const long OracleRequestPrice = 0_50000000; - public override int Id => -5; - internal OracleContract() { var events = new List(Manifest.Abi.Events) diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs index ccec40ea2a..c873f4ce14 100644 --- a/src/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -11,8 +11,6 @@ namespace Neo.SmartContract.Native { public sealed class PolicyContract : NativeContract { - public override int Id => -3; - public const uint DefaultExecFeeFactor = 30; public const uint DefaultStoragePrice = 100000; private const uint MaxExecFeeFactor = 1000; diff --git a/src/neo/SmartContract/Native/RoleManagement.cs b/src/neo/SmartContract/Native/RoleManagement.cs index 6c32ca7c4b..ee95bd3edb 100644 --- a/src/neo/SmartContract/Native/RoleManagement.cs +++ b/src/neo/SmartContract/Native/RoleManagement.cs @@ -14,8 +14,6 @@ namespace Neo.SmartContract.Native { public sealed class RoleManagement : NativeContract { - public override int Id => -4; - internal RoleManagement() { } diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_FungibleToken.cs b/tests/neo.UnitTests/SmartContract/Native/UT_FungibleToken.cs index 8b57384f5e..8018dcaa16 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_FungibleToken.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_FungibleToken.cs @@ -79,7 +79,6 @@ public StorageKey CreateStorageKey(byte prefix, byte[] key = null) public class TestNep17Token : FungibleToken { - public override int Id => 0x10000005; public override string Symbol => throw new NotImplementedException(); public override byte Decimals => 8; } diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index 9cd24fc66d..601c21ab52 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -32,8 +32,6 @@ public void TestInitialize() private class DummyNative : NativeContract { - public override int Id => 1; - [ContractMethod(0, CallFlags.None)] public void NetTypes( bool p1, sbyte p2, byte p3, short p4, ushort p5, int p6, uint p7, long p8, ulong p9, BigInteger p10, @@ -90,7 +88,7 @@ public void TestToParameter() [TestMethod] public void TestGetContract() { - Assert.IsTrue(NativeContract.NEO == NativeContract.GetContract(NativeContract.NEO.Name)); + Assert.IsTrue(NativeContract.NEO == NativeContract.GetContract(NativeContract.NEO.Id)); Assert.IsTrue(NativeContract.NEO == NativeContract.GetContract(NativeContract.NEO.Hash)); } @@ -136,8 +134,6 @@ public void TestTestCall() public class TestNativeContract : NativeContract { - public override int Id => 0x10000006; - [ContractMethod(0, CallFlags.None)] public string HelloWorld => "hello world"; diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_NeoToken.cs b/tests/neo.UnitTests/SmartContract/Native/UT_NeoToken.cs index e580e6f465..133df46bd3 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_NeoToken.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_NeoToken.cs @@ -503,7 +503,7 @@ public void TestCalculateBonus() Balance = 100, VoteTo = Blockchain.StandbyCommittee[0] })); - snapshot.Storages.Add(new KeyBuilder(-1, 23).Add(Blockchain.StandbyCommittee[0]).AddBigEndian(uint.MaxValue - 50), new StorageItem() { Value = new BigInteger(50 * 10000L).ToByteArray() }); + snapshot.Storages.Add(new KeyBuilder(-2, 23).Add(Blockchain.StandbyCommittee[0]).AddBigEndian(uint.MaxValue - 50), new StorageItem() { Value = new BigInteger(50 * 10000L).ToByteArray() }); NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 100).Should().Be(new BigInteger(50 * 100)); snapshot.Storages.Delete(key); } @@ -569,22 +569,22 @@ public void TestCheckCandidate() var point = committee[0].EncodePoint(true); // Prepare Prefix_VoterRewardPerCommittee - var storageKey = new KeyBuilder(-1, 23).Add(committee[0]).AddBigEndian(20); + var storageKey = new KeyBuilder(-2, 23).Add(committee[0]).AddBigEndian(20); snapshot.Storages.Add(storageKey, new StorageItem(new BigInteger(1000))); // Prepare Candidate - storageKey = new KeyBuilder(-1, 33).Add(committee[0]); + storageKey = new KeyBuilder(-2, 33).Add(committee[0]); snapshot.Storages.Add(storageKey, new StorageItem(new CandidateState { Registered = true, Votes = BigInteger.One })); - storageKey = new KeyBuilder(-1, 23).Add(committee[0]); + storageKey = new KeyBuilder(-2, 23).Add(committee[0]); snapshot.Storages.Find(storageKey.ToArray()).ToArray().Length.Should().Be(1); // Pre-persist - var persistingBlock = new Block { Index = 21, Transactions = Array.Empty() }; + var persistingBlock = new Block { Index = 21, ConsensusData = new ConsensusData(), Transactions = Array.Empty() }; Check_OnPersist(snapshot, persistingBlock); // Clear votes - storageKey = new KeyBuilder(-1, 33).Add(committee[0]); + storageKey = new KeyBuilder(-2, 33).Add(committee[0]); snapshot.Storages.GetAndChange(storageKey).GetInteroperable().Votes = BigInteger.Zero; // Unregister candidate, remove @@ -592,13 +592,13 @@ public void TestCheckCandidate() ret.State.Should().BeTrue(); ret.Result.Should().BeTrue(); - storageKey = new KeyBuilder(-1, 23).Add(committee[0]); + storageKey = new KeyBuilder(-2, 23).Add(committee[0]); snapshot.Storages.Find(storageKey.ToArray()).ToArray().Length.Should().Be(0); // Post-persist Check_PostPersist(snapshot, persistingBlock).Should().BeTrue(); - storageKey = new KeyBuilder(-1, 23).Add(committee[0]); + storageKey = new KeyBuilder(-2, 23).Add(committee[0]); snapshot.Storages.Find(storageKey.ToArray()).ToArray().Length.Should().Be(1); } @@ -713,16 +713,16 @@ public void TestClaimGas() for (var i = 0; i < ProtocolSettings.Default.CommitteeMembersCount; i++) { ECPoint member = standbyCommittee[i]; - snapshot.Storages.Add(new KeyBuilder(-1, 33).Add(member), new StorageItem(new CandidateState() + snapshot.Storages.Add(new KeyBuilder(-2, 33).Add(member), new StorageItem(new CandidateState() { Registered = true, Votes = 200 * 10000 })); cachedCommittee.Add((member, 200 * 10000)); } - snapshot.Storages[new KeyBuilder(-1, 14)].Value = BinarySerializer.Serialize(cachedCommittee.ToStackItem(null), 4096); + snapshot.Storages[new KeyBuilder(-2, 14)].Value = BinarySerializer.Serialize(cachedCommittee.ToStackItem(null), 4096); - var item = snapshot.Storages.GetAndChange(new KeyBuilder(-1, 1), () => new StorageItem()); + var item = snapshot.Storages.GetAndChange(new KeyBuilder(-2, 1), () => new StorageItem()); item.Value = ((BigInteger)2100 * 10000L).ToByteArray(); var persistingBlock = new Block { Index = 0, Transactions = Array.Empty() }; @@ -733,10 +733,10 @@ public void TestClaimGas() var accountB = committee[ProtocolSettings.Default.CommitteeMembersCount - 1]; NativeContract.NEO.BalanceOf(snapshot, Contract.CreateSignatureContract(accountA).ScriptHash).Should().Be(0); - StorageItem storageItem = snapshot.Storages.TryGet(new KeyBuilder(-1, 23).Add(accountA).AddBigEndian(1)); + StorageItem storageItem = snapshot.Storages.TryGet(new KeyBuilder(-2, 23).Add(accountA).AddBigEndian(1)); new BigInteger(storageItem.Value).Should().Be(30000000000); - snapshot.Storages.TryGet(new KeyBuilder(-1, 23).Add(accountB).AddBigEndian(uint.MaxValue - 1)).Should().BeNull(); + snapshot.Storages.TryGet(new KeyBuilder(-2, 23).Add(accountB).AddBigEndian(uint.MaxValue - 1)).Should().BeNull(); // Next block @@ -745,7 +745,7 @@ public void TestClaimGas() NativeContract.NEO.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[1]).ScriptHash).Should().Be(0); - storageItem = snapshot.Storages.TryGet(new KeyBuilder(-1, 23).Add(committee[1]).AddBigEndian(1)); + storageItem = snapshot.Storages.TryGet(new KeyBuilder(-2, 23).Add(committee[1]).AddBigEndian(1)); new BigInteger(storageItem.Value).Should().Be(30000000000); // Next block @@ -756,13 +756,13 @@ public void TestClaimGas() accountA = Blockchain.StandbyCommittee.OrderBy(p => p).ToArray()[2]; NativeContract.NEO.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[2]).ScriptHash).Should().Be(0); - storageItem = snapshot.Storages.TryGet(new KeyBuilder(-1, 23).Add(committee[2]).AddBigEndian(22)); + storageItem = snapshot.Storages.TryGet(new KeyBuilder(-2, 23).Add(committee[2]).AddBigEndian(22)); new BigInteger(storageItem.Value).Should().Be(30000000000 * 2); // Claim GAS var account = Contract.CreateSignatureContract(committee[2]).ScriptHash; - snapshot.Storages.Add(new KeyBuilder(-1, 20).Add(account), new StorageItem(new NeoAccountState + snapshot.Storages.Add(new KeyBuilder(-2, 20).Add(account), new StorageItem(new NeoAccountState { BalanceHeight = 3, Balance = 200 * 10000 - 2 * 100, diff --git a/tests/neo.UnitTests/VM/UT_Helper.cs b/tests/neo.UnitTests/VM/UT_Helper.cs index 896fa6f67d..4135a53f84 100644 --- a/tests/neo.UnitTests/VM/UT_Helper.cs +++ b/tests/neo.UnitTests/VM/UT_Helper.cs @@ -158,7 +158,7 @@ public void TestMakeScript() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero); - Assert.AreEqual("0c14000000000000000000000000000000000000000011c01f0c0962616c616e63654f660c141717ddafdd757eec365865b963473beb617f9a1441627d5b52", + Assert.AreEqual("0c14000000000000000000000000000000000000000011c01f0c0962616c616e63654f660c14a282435d0ee334fecaac7f5fde46f623f24cc09a41627d5b52", testScript.ToHexString()); }