diff --git a/src/neo/SmartContract/CallFlags.cs b/src/neo/SmartContract/CallFlags.cs index 99af3e0599..86361e9b15 100644 --- a/src/neo/SmartContract/CallFlags.cs +++ b/src/neo/SmartContract/CallFlags.cs @@ -7,11 +7,12 @@ public enum CallFlags : byte { None = 0, - AllowModifyStates = 0b00000001, - AllowCall = 0b00000010, - AllowNotify = 0b00000100, + AllowStates = 0b00000001, + AllowModifyStates = 0b00000010, + AllowCall = 0b00000100, + AllowNotify = 0b00001000, - ReadOnly = AllowCall | AllowNotify, - All = AllowModifyStates | AllowCall | AllowNotify + ReadOnly = AllowStates | AllowCall | AllowNotify, + All = AllowStates | AllowModifyStates | AllowCall | AllowNotify } } diff --git a/src/neo/SmartContract/InteropService.Blockchain.cs b/src/neo/SmartContract/InteropService.Blockchain.cs index 1183c5e462..a8ada65f45 100644 --- a/src/neo/SmartContract/InteropService.Blockchain.cs +++ b/src/neo/SmartContract/InteropService.Blockchain.cs @@ -14,12 +14,12 @@ public static class Blockchain { public const uint MaxTraceableBlocks = Transaction.MaxValidUntilBlockIncrement; - public static readonly InteropDescriptor GetHeight = Register("System.Blockchain.GetHeight", Blockchain_GetHeight, 0_00000400, TriggerType.Application, CallFlags.None); - public static readonly InteropDescriptor GetBlock = Register("System.Blockchain.GetBlock", Blockchain_GetBlock, 0_02500000, TriggerType.Application, CallFlags.None); - public static readonly InteropDescriptor GetTransaction = Register("System.Blockchain.GetTransaction", Blockchain_GetTransaction, 0_01000000, TriggerType.Application, CallFlags.None); - public static readonly InteropDescriptor GetTransactionHeight = Register("System.Blockchain.GetTransactionHeight", Blockchain_GetTransactionHeight, 0_01000000, TriggerType.Application, CallFlags.None); - public static readonly InteropDescriptor GetTransactionFromBlock = Register("System.Blockchain.GetTransactionFromBlock", Blockchain_GetTransactionFromBlock, 0_01000000, TriggerType.Application, CallFlags.None); - public static readonly InteropDescriptor GetContract = Register("System.Blockchain.GetContract", Blockchain_GetContract, 0_01000000, TriggerType.Application, CallFlags.None); + public static readonly InteropDescriptor GetHeight = Register("System.Blockchain.GetHeight", Blockchain_GetHeight, 0_00000400, TriggerType.Application, CallFlags.AllowStates); + public static readonly InteropDescriptor GetBlock = Register("System.Blockchain.GetBlock", Blockchain_GetBlock, 0_02500000, TriggerType.Application, CallFlags.AllowStates); + public static readonly InteropDescriptor GetTransaction = Register("System.Blockchain.GetTransaction", Blockchain_GetTransaction, 0_01000000, TriggerType.Application, CallFlags.AllowStates); + public static readonly InteropDescriptor GetTransactionHeight = Register("System.Blockchain.GetTransactionHeight", Blockchain_GetTransactionHeight, 0_01000000, TriggerType.Application, CallFlags.AllowStates); + public static readonly InteropDescriptor GetTransactionFromBlock = Register("System.Blockchain.GetTransactionFromBlock", Blockchain_GetTransactionFromBlock, 0_01000000, TriggerType.Application, CallFlags.AllowStates); + public static readonly InteropDescriptor GetContract = Register("System.Blockchain.GetContract", Blockchain_GetContract, 0_01000000, TriggerType.Application, CallFlags.AllowStates); private static bool Blockchain_GetHeight(ApplicationEngine engine) { diff --git a/src/neo/SmartContract/InteropService.Runtime.cs b/src/neo/SmartContract/InteropService.Runtime.cs index aa525c1600..9942555cba 100644 --- a/src/neo/SmartContract/InteropService.Runtime.cs +++ b/src/neo/SmartContract/InteropService.Runtime.cs @@ -19,12 +19,12 @@ public static class Runtime public static readonly InteropDescriptor Platform = Register("System.Runtime.Platform", Runtime_Platform, 0_00000250, TriggerType.All, CallFlags.None); public static readonly InteropDescriptor GetTrigger = Register("System.Runtime.GetTrigger", Runtime_GetTrigger, 0_00000250, TriggerType.All, CallFlags.None); - public static readonly InteropDescriptor GetTime = Register("System.Runtime.GetTime", Runtime_GetTime, 0_00000250, TriggerType.Application, CallFlags.None); + public static readonly InteropDescriptor GetTime = Register("System.Runtime.GetTime", Runtime_GetTime, 0_00000250, TriggerType.Application, CallFlags.AllowStates); public static readonly InteropDescriptor GetScriptContainer = Register("System.Runtime.GetScriptContainer", Runtime_GetScriptContainer, 0_00000250, TriggerType.All, CallFlags.None); public static readonly InteropDescriptor GetExecutingScriptHash = Register("System.Runtime.GetExecutingScriptHash", Runtime_GetExecutingScriptHash, 0_00000400, TriggerType.All, CallFlags.None); public static readonly InteropDescriptor GetCallingScriptHash = Register("System.Runtime.GetCallingScriptHash", Runtime_GetCallingScriptHash, 0_00000400, TriggerType.All, CallFlags.None); public static readonly InteropDescriptor GetEntryScriptHash = Register("System.Runtime.GetEntryScriptHash", Runtime_GetEntryScriptHash, 0_00000400, TriggerType.All, CallFlags.None); - public static readonly InteropDescriptor CheckWitness = Register("System.Runtime.CheckWitness", Runtime_CheckWitness, 0_00030000, TriggerType.All, CallFlags.None); + public static readonly InteropDescriptor CheckWitness = Register("System.Runtime.CheckWitness", Runtime_CheckWitness, 0_00030000, TriggerType.All, CallFlags.AllowStates); public static readonly InteropDescriptor GetInvocationCounter = Register("System.Runtime.GetInvocationCounter", Runtime_GetInvocationCounter, 0_00000400, TriggerType.All, CallFlags.None); public static readonly InteropDescriptor Log = Register("System.Runtime.Log", Runtime_Log, 0_01000000, TriggerType.All, CallFlags.AllowNotify); public static readonly InteropDescriptor Notify = Register("System.Runtime.Notify", Runtime_Notify, 0_01000000, TriggerType.All, CallFlags.AllowNotify); diff --git a/src/neo/SmartContract/InteropService.Storage.cs b/src/neo/SmartContract/InteropService.Storage.cs index b7df35ea26..c23eebeb41 100644 --- a/src/neo/SmartContract/InteropService.Storage.cs +++ b/src/neo/SmartContract/InteropService.Storage.cs @@ -16,11 +16,11 @@ public static class Storage public const int MaxKeySize = 64; public const int MaxValueSize = ushort.MaxValue; - public static readonly InteropDescriptor GetContext = Register("System.Storage.GetContext", Storage_GetContext, 0_00000400, TriggerType.Application, CallFlags.None); - public static readonly InteropDescriptor GetReadOnlyContext = Register("System.Storage.GetReadOnlyContext", Storage_GetReadOnlyContext, 0_00000400, TriggerType.Application, CallFlags.None); - public static readonly InteropDescriptor AsReadOnly = Register("System.Storage.AsReadOnly", Storage_AsReadOnly, 0_00000400, TriggerType.Application, CallFlags.None); - public static readonly InteropDescriptor Get = Register("System.Storage.Get", Storage_Get, 0_01000000, TriggerType.Application, CallFlags.None); - public static readonly InteropDescriptor Find = Register("System.Storage.Find", Storage_Find, 0_01000000, TriggerType.Application, CallFlags.None); + public static readonly InteropDescriptor GetContext = Register("System.Storage.GetContext", Storage_GetContext, 0_00000400, TriggerType.Application, CallFlags.AllowStates); + public static readonly InteropDescriptor GetReadOnlyContext = Register("System.Storage.GetReadOnlyContext", Storage_GetReadOnlyContext, 0_00000400, TriggerType.Application, CallFlags.AllowStates); + public static readonly InteropDescriptor AsReadOnly = Register("System.Storage.AsReadOnly", Storage_AsReadOnly, 0_00000400, TriggerType.Application, CallFlags.AllowStates); + public static readonly InteropDescriptor Get = Register("System.Storage.Get", Storage_Get, 0_01000000, TriggerType.Application, CallFlags.AllowStates); + public static readonly InteropDescriptor Find = Register("System.Storage.Find", Storage_Find, 0_01000000, TriggerType.Application, CallFlags.AllowStates); public static readonly InteropDescriptor Put = Register("System.Storage.Put", Storage_Put, GetStoragePrice, TriggerType.Application, CallFlags.AllowModifyStates); public static readonly InteropDescriptor PutEx = Register("System.Storage.PutEx", Storage_PutEx, GetStoragePrice, TriggerType.Application, CallFlags.AllowModifyStates); public static readonly InteropDescriptor Delete = Register("System.Storage.Delete", Storage_Delete, 1 * GasPerByte, TriggerType.Application, CallFlags.AllowModifyStates); diff --git a/src/neo/SmartContract/Native/ContractMethodAttribute.cs b/src/neo/SmartContract/Native/ContractMethodAttribute.cs index 22051d72f7..6cb745fee5 100644 --- a/src/neo/SmartContract/Native/ContractMethodAttribute.cs +++ b/src/neo/SmartContract/Native/ContractMethodAttribute.cs @@ -10,12 +10,13 @@ internal class ContractMethodAttribute : Attribute public ContractParameterType ReturnType { get; } public ContractParameterType[] ParameterTypes { get; set; } = Array.Empty(); public string[] ParameterNames { get; set; } = Array.Empty(); - public bool SafeMethod { get; set; } = false; + public CallFlags RequiredCallFlags { get; } - public ContractMethodAttribute(long price, ContractParameterType returnType) + public ContractMethodAttribute(long price, ContractParameterType returnType, CallFlags requiredCallFlags) { this.Price = price; this.ReturnType = returnType; + this.RequiredCallFlags = requiredCallFlags; } } } diff --git a/src/neo/SmartContract/Native/NativeContract.cs b/src/neo/SmartContract/Native/NativeContract.cs index 7e402ac00a..ce34011e32 100644 --- a/src/neo/SmartContract/Native/NativeContract.cs +++ b/src/neo/SmartContract/Native/NativeContract.cs @@ -56,12 +56,12 @@ protected NativeContract() ReturnType = attribute.ReturnType, Parameters = attribute.ParameterTypes.Zip(attribute.ParameterNames, (t, n) => new ContractParameterDefinition { Type = t, Name = n }).ToArray() }); - if (attribute.SafeMethod) safeMethods.Add(name); + if (!attribute.RequiredCallFlags.HasFlag(CallFlags.AllowModifyStates)) safeMethods.Add(name); methods.Add(name, new ContractMethodMetadata { Delegate = (Func)method.CreateDelegate(typeof(Func), this), Price = attribute.Price, - RequiredCallFlags = attribute.SafeMethod ? CallFlags.None : CallFlags.AllowModifyStates + RequiredCallFlags = attribute.RequiredCallFlags }); } this.Manifest = new ContractManifest @@ -133,7 +133,7 @@ internal virtual bool Initialize(ApplicationEngine engine) return true; } - [ContractMethod(0, ContractParameterType.Boolean)] + [ContractMethod(0, ContractParameterType.Boolean, CallFlags.AllowModifyStates)] protected StackItem OnPersist(ApplicationEngine engine, Array args) { if (engine.Trigger != TriggerType.System) return false; @@ -145,7 +145,7 @@ protected virtual bool OnPersist(ApplicationEngine engine) return true; } - [ContractMethod(0, ContractParameterType.Array, Name = "supportedStandards", SafeMethod = true)] + [ContractMethod(0, ContractParameterType.Array, CallFlags.None, Name = "supportedStandards")] protected StackItem SupportedStandardsMethod(ApplicationEngine engine, Array args) { return new Array(engine.ReferenceCounter, SupportedStandards.Select(p => (StackItem)p)); diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs index ee5f45376e..ac9e9de471 100644 --- a/src/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -67,7 +67,7 @@ internal override bool Initialize(ApplicationEngine engine) return true; } - [ContractMethod(0_01000000, ContractParameterType.Integer, SafeMethod = true)] + [ContractMethod(0_01000000, ContractParameterType.Integer, CallFlags.AllowStates)] private StackItem GetMaxTransactionsPerBlock(ApplicationEngine engine, Array args) { return GetMaxTransactionsPerBlock(engine.Snapshot); @@ -78,7 +78,7 @@ public uint GetMaxTransactionsPerBlock(StoreView snapshot) return BitConverter.ToUInt32(snapshot.Storages[CreateStorageKey(Prefix_MaxTransactionsPerBlock)].Value, 0); } - [ContractMethod(0_01000000, ContractParameterType.Integer, SafeMethod = true)] + [ContractMethod(0_01000000, ContractParameterType.Integer, CallFlags.AllowStates)] private StackItem GetMaxBlockSize(ApplicationEngine engine, Array args) { return GetMaxBlockSize(engine.Snapshot); @@ -89,7 +89,7 @@ public uint GetMaxBlockSize(StoreView snapshot) return BitConverter.ToUInt32(snapshot.Storages[CreateStorageKey(Prefix_MaxBlockSize)].Value, 0); } - [ContractMethod(0_01000000, ContractParameterType.Integer, SafeMethod = true)] + [ContractMethod(0_01000000, ContractParameterType.Integer, CallFlags.AllowStates)] private StackItem GetFeePerByte(ApplicationEngine engine, Array args) { return GetFeePerByte(engine.Snapshot); @@ -100,7 +100,7 @@ public long GetFeePerByte(StoreView snapshot) return BitConverter.ToInt64(snapshot.Storages[CreateStorageKey(Prefix_FeePerByte)].Value, 0); } - [ContractMethod(0_01000000, ContractParameterType.Array, SafeMethod = true)] + [ContractMethod(0_01000000, ContractParameterType.Array, CallFlags.AllowStates)] private StackItem GetBlockedAccounts(ApplicationEngine engine, Array args) { return new Array(engine.ReferenceCounter, GetBlockedAccounts(engine.Snapshot).Select(p => (StackItem)p.ToArray())); @@ -111,7 +111,7 @@ public UInt160[] GetBlockedAccounts(StoreView snapshot) return snapshot.Storages[CreateStorageKey(Prefix_BlockedAccounts)].Value.AsSerializableArray(); } - [ContractMethod(0_03000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.Integer }, ParameterNames = new[] { "value" })] + [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Integer }, ParameterNames = new[] { "value" })] private StackItem SetMaxBlockSize(ApplicationEngine engine, Array args) { if (!CheckValidators(engine)) return false; @@ -122,7 +122,7 @@ private StackItem SetMaxBlockSize(ApplicationEngine engine, Array args) return true; } - [ContractMethod(0_03000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.Integer }, ParameterNames = new[] { "value" })] + [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Integer }, ParameterNames = new[] { "value" })] private StackItem SetMaxTransactionsPerBlock(ApplicationEngine engine, Array args) { if (!CheckValidators(engine)) return false; @@ -132,7 +132,7 @@ private StackItem SetMaxTransactionsPerBlock(ApplicationEngine engine, Array arg return true; } - [ContractMethod(0_03000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.Integer }, ParameterNames = new[] { "value" })] + [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Integer }, ParameterNames = new[] { "value" })] private StackItem SetFeePerByte(ApplicationEngine engine, Array args) { if (!CheckValidators(engine)) return false; @@ -142,7 +142,7 @@ private StackItem SetFeePerByte(ApplicationEngine engine, Array args) return true; } - [ContractMethod(0_03000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.Hash160 }, ParameterNames = new[] { "account" })] + [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Hash160 }, ParameterNames = new[] { "account" })] private StackItem BlockAccount(ApplicationEngine engine, Array args) { if (!CheckValidators(engine)) return false; @@ -156,7 +156,7 @@ private StackItem BlockAccount(ApplicationEngine engine, Array args) return true; } - [ContractMethod(0_03000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.Hash160 }, ParameterNames = new[] { "account" })] + [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Hash160 }, ParameterNames = new[] { "account" })] private StackItem UnblockAccount(ApplicationEngine engine, Array args) { if (!CheckValidators(engine)) return false; diff --git a/src/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs index 4c9147220e..7d3b82c797 100644 --- a/src/neo/SmartContract/Native/Tokens/NeoToken.cs +++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs @@ -116,7 +116,7 @@ protected override bool OnPersist(ApplicationEngine engine) return true; } - [ContractMethod(0_03000000, ContractParameterType.Integer, ParameterTypes = new[] { ContractParameterType.Hash160, ContractParameterType.Integer }, ParameterNames = new[] { "account", "end" }, SafeMethod = true)] + [ContractMethod(0_03000000, ContractParameterType.Integer, CallFlags.AllowStates, ParameterTypes = new[] { ContractParameterType.Hash160, ContractParameterType.Integer }, ParameterNames = new[] { "account", "end" })] private StackItem UnclaimedGas(ApplicationEngine engine, Array args) { UInt160 account = new UInt160(args[0].GetSpan()); @@ -132,7 +132,7 @@ public BigInteger UnclaimedGas(StoreView snapshot, UInt160 account, uint end) return CalculateBonus(snapshot, state.Balance, state.BalanceHeight, end); } - [ContractMethod(0_05000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.PublicKey }, ParameterNames = new[] { "pubkey" })] + [ContractMethod(0_05000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.PublicKey }, ParameterNames = new[] { "pubkey" })] private StackItem RegisterCandidate(ApplicationEngine engine, Array args) { ECPoint pubkey = args[0].GetSpan().AsSerializable(); @@ -150,7 +150,7 @@ private bool RegisterCandidate(StoreView snapshot, ECPoint pubkey) return true; } - [ContractMethod(0_05000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.PublicKey }, ParameterNames = new[] { "pubkey" })] + [ContractMethod(0_05000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.PublicKey }, ParameterNames = new[] { "pubkey" })] private StackItem UnregisterCandidate(ApplicationEngine engine, Array args) { ECPoint pubkey = args[0].GetSpan().AsSerializable(); @@ -172,7 +172,7 @@ private bool UnregisterCandidate(StoreView snapshot, ECPoint pubkey) return true; } - [ContractMethod(5_00000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.Hash160, ContractParameterType.Array }, ParameterNames = new[] { "account", "pubkeys" })] + [ContractMethod(5_00000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Hash160, ContractParameterType.Array }, ParameterNames = new[] { "account", "pubkeys" })] private StackItem Vote(ApplicationEngine engine, Array args) { UInt160 account = new UInt160(args[0].GetSpan()); @@ -209,7 +209,7 @@ private bool Vote(StoreView snapshot, UInt160 account, ECPoint voteTo) return true; } - [ContractMethod(1_00000000, ContractParameterType.Array, SafeMethod = true)] + [ContractMethod(1_00000000, ContractParameterType.Array, CallFlags.AllowStates)] private StackItem GetCandidates(ApplicationEngine engine, Array args) { return new Array(engine.ReferenceCounter, GetCandidates(engine.Snapshot).Select(p => new Struct(engine.ReferenceCounter, new StackItem[] { p.PublicKey.ToArray(), p.Votes }))); @@ -225,7 +225,7 @@ public IEnumerable<(ECPoint PublicKey, BigInteger Votes)> GetCandidates(StoreVie )).Where(p => p.Item2.Registered).Select(p => (p.Item1, p.Item2.Votes)); } - [ContractMethod(1_00000000, ContractParameterType.Array, SafeMethod = true)] + [ContractMethod(1_00000000, ContractParameterType.Array, CallFlags.AllowStates)] private StackItem GetValidators(ApplicationEngine engine, Array args) { return new Array(engine.ReferenceCounter, GetValidators(engine.Snapshot).Select(p => (StackItem)p.ToArray())); @@ -236,7 +236,7 @@ public ECPoint[] GetValidators(StoreView snapshot) return GetCommitteeMembers(snapshot, Blockchain.ValidatorsCount).OrderBy(p => p).ToArray(); } - [ContractMethod(1_00000000, ContractParameterType.Array, SafeMethod = true)] + [ContractMethod(1_00000000, ContractParameterType.Array, CallFlags.AllowStates)] private StackItem GetCommittee(ApplicationEngine engine, Array args) { return new Array(engine.ReferenceCounter, GetCommittee(engine.Snapshot).Select(p => (StackItem)p.ToArray())); @@ -252,7 +252,7 @@ private IEnumerable GetCommitteeMembers(StoreView snapshot, int count) return GetCandidates(snapshot).OrderByDescending(p => p.Votes).ThenBy(p => p.PublicKey).Select(p => p.PublicKey).Take(count); } - [ContractMethod(1_00000000, ContractParameterType.Array, SafeMethod = true)] + [ContractMethod(1_00000000, ContractParameterType.Array, CallFlags.AllowStates)] private StackItem GetNextBlockValidators(ApplicationEngine engine, Array args) { return new Array(engine.ReferenceCounter, GetNextBlockValidators(engine.Snapshot).Select(p => (StackItem)p.ToArray())); diff --git a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs index b4e389676f..6f1164de8c 100644 --- a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs +++ b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs @@ -104,25 +104,25 @@ internal protected virtual void Burn(ApplicationEngine engine, UInt160 account, engine.SendNotification(Hash, new Array(new StackItem[] { "Transfer", account.ToArray(), StackItem.Null, amount })); } - [ContractMethod(0, ContractParameterType.String, Name = "name", SafeMethod = true)] + [ContractMethod(0, ContractParameterType.String, CallFlags.None, Name = "name")] protected StackItem NameMethod(ApplicationEngine engine, Array args) { return Name; } - [ContractMethod(0, ContractParameterType.String, Name = "symbol", SafeMethod = true)] + [ContractMethod(0, ContractParameterType.String, CallFlags.None, Name = "symbol")] protected StackItem SymbolMethod(ApplicationEngine engine, Array args) { return Symbol; } - [ContractMethod(0, ContractParameterType.Integer, Name = "decimals", SafeMethod = true)] + [ContractMethod(0, ContractParameterType.Integer, CallFlags.None, Name = "decimals")] protected StackItem DecimalsMethod(ApplicationEngine engine, Array args) { return (uint)Decimals; } - [ContractMethod(0_01000000, ContractParameterType.Integer, SafeMethod = true)] + [ContractMethod(0_01000000, ContractParameterType.Integer, CallFlags.AllowStates)] protected StackItem TotalSupply(ApplicationEngine engine, Array args) { return TotalSupply(engine.Snapshot); @@ -135,7 +135,7 @@ public virtual BigInteger TotalSupply(StoreView snapshot) return new BigInteger(storage.Value); } - [ContractMethod(0_01000000, ContractParameterType.Integer, ParameterTypes = new[] { ContractParameterType.Hash160 }, ParameterNames = new[] { "account" }, SafeMethod = true)] + [ContractMethod(0_01000000, ContractParameterType.Integer, CallFlags.AllowStates, ParameterTypes = new[] { ContractParameterType.Hash160 }, ParameterNames = new[] { "account" })] protected StackItem BalanceOf(ApplicationEngine engine, Array args) { return BalanceOf(engine.Snapshot, new UInt160(args[0].GetSpan())); @@ -148,7 +148,7 @@ public virtual BigInteger BalanceOf(StoreView snapshot, UInt160 account) return storage.GetInteroperable().Balance; } - [ContractMethod(0_08000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.Hash160, ContractParameterType.Hash160, ContractParameterType.Integer }, ParameterNames = new[] { "from", "to", "amount" })] + [ContractMethod(0_08000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Hash160, ContractParameterType.Hash160, ContractParameterType.Integer }, ParameterNames = new[] { "from", "to", "amount" })] protected StackItem Transfer(ApplicationEngine engine, Array args) { UInt160 from = new UInt160(args[0].GetSpan());