internal bool Invoke(ApplicationEngine engine) { if (!engine.CurrentScriptHash.Equals(Hash)) { return(false); } if (!engine.TryPop(out string operation)) { return(false); } if (!engine.TryPop(out Array args)) { return(false); } if (!methods.TryGetValue(operation, out ContractMethodMetadata method)) { return(false); } ExecutionContextState state = engine.CurrentContext.GetState <ExecutionContextState>(); if (!state.CallFlags.HasFlag(method.RequiredCallFlags)) { return(false); } if (!engine.AddGas(method.Price)) { return(false); } List <object> parameters = new List <object>(); if (method.NeedApplicationEngine) { parameters.Add(engine); } if (method.NeedSnapshot) { parameters.Add(engine.Snapshot); } for (int i = 0; i < method.Parameters.Length; i++) { StackItem item = i < args.Count ? args[i] : StackItem.Null; parameters.Add(engine.Convert(item, method.Parameters[i])); } object returnValue = method.Handler.Invoke(this, parameters.ToArray()); if (method.Handler.ReturnType != typeof(void)) { engine.Push(engine.Convert(returnValue)); } return(true); }
internal async void Invoke(ApplicationEngine engine, byte version) { try { if (version != 0) { throw new InvalidOperationException($"The native contract of version {version} is not active."); } ExecutionContext context = engine.CurrentContext; ContractMethodMetadata method = methods[context.InstructionPointer]; ExecutionContextState state = context.GetState <ExecutionContextState>(); if (!state.CallFlags.HasFlag(method.RequiredCallFlags)) { throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}."); } engine.AddGas(method.CpuFee * Policy.GetExecFeeFactor(engine.Snapshot) + method.StorageFee * Policy.GetStoragePrice(engine.Snapshot)); List <object> parameters = new List <object>(); if (method.NeedApplicationEngine) { parameters.Add(engine); } if (method.NeedSnapshot) { parameters.Add(engine.Snapshot); } for (int i = 0; i < method.Parameters.Length; i++) { parameters.Add(engine.Convert(context.EvaluationStack.Pop(), method.Parameters[i])); } object returnValue = method.Handler.Invoke(this, parameters.ToArray()); if (returnValue is ContractTask task) { await task; returnValue = task.GetResult(); } if (method.Handler.ReturnType != typeof(void) && method.Handler.ReturnType != typeof(ContractTask)) { context.EvaluationStack.Push(engine.Convert(returnValue)); } } catch (Exception ex) { engine.Throw(ex); } }
internal void Invoke(ApplicationEngine engine, byte version) { if (ActiveBlockIndex > Ledger.CurrentIndex(engine.Snapshot)) { throw new InvalidOperationException($"The native contract {Name} is not active."); } if (version != 0) { throw new InvalidOperationException($"The native contract of version {version} is not active."); } ExecutionContext context = engine.CurrentContext; ContractMethodMetadata method = methods[context.InstructionPointer]; ExecutionContextState state = context.GetState <ExecutionContextState>(); if (!state.CallFlags.HasFlag(method.RequiredCallFlags)) { throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}."); } engine.AddGas(method.Price); List <object> parameters = new List <object>(); if (method.NeedApplicationEngine) { parameters.Add(engine); } if (method.NeedSnapshot) { parameters.Add(engine.Snapshot); } for (int i = 0; i < method.Parameters.Length; i++) { parameters.Add(engine.Convert(context.EvaluationStack.Pop(), method.Parameters[i])); } object returnValue = method.Handler.Invoke(this, parameters.ToArray()); if (method.Handler.ReturnType != typeof(void)) { context.EvaluationStack.Push(engine.Convert(returnValue)); } }
internal void Invoke(ApplicationEngine engine) { if (!engine.CurrentScriptHash.Equals(Hash)) { throw new InvalidOperationException("It is not allowed to use Neo.Native.Call directly to call native contracts. System.Contract.Call should be used."); } ExecutionContext context = engine.CurrentContext; string operation = context.EvaluationStack.Pop().GetString(); Array args = context.EvaluationStack.Pop <Array>(); ContractMethodMetadata method = methods[operation]; ExecutionContextState state = context.GetState <ExecutionContextState>(); if (!state.CallFlags.HasFlag(method.RequiredCallFlags)) { throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}."); } engine.AddGas(method.Price); List <object> parameters = new List <object>(); if (method.NeedApplicationEngine) { parameters.Add(engine); } if (method.NeedSnapshot) { parameters.Add(engine.Snapshot); } for (int i = 0; i < method.Parameters.Length; i++) { StackItem item = i < args.Count ? args[i] : StackItem.Null; parameters.Add(engine.Convert(item, method.Parameters[i])); } object returnValue = method.Handler.Invoke(this, parameters.ToArray()); if (method.Handler.ReturnType != typeof(void)) { context.EvaluationStack.Push(engine.Convert(returnValue)); } }