private void CallContractInternal(ContractState contract, ContractMethodDescriptor method, CallFlags flags, bool hasReturnValue, StackItem[] args) { if (invocationCounter.TryGetValue(contract.Hash, out var counter)) { invocationCounter[contract.Hash] = counter + 1; } else { invocationCounter[contract.Hash] = 1; } ExecutionContextState state = CurrentContext.GetState <ExecutionContextState>(); UInt160 callingScriptHash = state.ScriptHash; CallFlags callingFlags = state.CallFlags; if (args.Length != method.Parameters.Length) { throw new InvalidOperationException($"Method {method.Name} Expects {method.Parameters.Length} Arguments But Receives {args.Length} Arguments"); } ExecutionContext context_new = LoadContract(contract, method.Name, flags & callingFlags, hasReturnValue, (ushort)args.Length); state = context_new.GetState <ExecutionContextState>(); state.CallingScriptHash = callingScriptHash; for (int i = args.Length - 1; i >= 0; i--) { context_new.EvaluationStack.Push(args[i]); } if (NativeContract.IsNative(contract.Hash)) { context_new.EvaluationStack.Push(method.Name); } }
internal void CallFromNativeContract(UInt160 callingScriptHash, UInt160 hash, string method, params StackItem[] args) { CallContractInternal(hash, method, new VMArray(ReferenceCounter, args), CallFlags.All, ReturnTypeConvention.EnsureIsEmpty); ExecutionContextState state = CurrentContext.GetState <ExecutionContextState>(); state.CallingScriptHash = callingScriptHash; StepOut(); }
internal void CallFromNativeContract(UInt160 callingScriptHash, UInt160 hash, string method, params StackItem[] args) { CallContractInternal(hash, method, CallFlags.All, false, args); ExecutionContextState state = CurrentContext.GetState <ExecutionContextState>(); state.CallingScriptHash = callingScriptHash; StepOut(); }
internal T CallFromNativeContract <T>(UInt160 callingScriptHash, UInt160 hash, string method, params StackItem[] args) { CallContractInternal(hash, method, CallFlags.All, true, args); ExecutionContextState state = CurrentContext.GetState <ExecutionContextState>(); state.CallingScriptHash = callingScriptHash; StepOut(); return((T)Convert(Pop(), new InteropParameterDescriptor(typeof(T)))); }
internal ContractTask <T> CallFromNativeContract <T>(UInt160 callingScriptHash, UInt160 hash, string method, params StackItem[] args) { ExecutionContext context_new = CallContractInternal(hash, method, CallFlags.All, true, args); ExecutionContextState state = context_new.GetState <ExecutionContextState>(); state.CallingScriptHash = callingScriptHash; ContractTask <T> task = new ContractTask <T>(); contractTasks.Add(context_new, task.GetAwaiter()); return(task); }
internal void CallFromNativeContract(UInt160 callingScriptHash, UInt160 hash, string method, params StackItem[] args) { ExecutionContext context_current = CurrentContext; ExecutionContext context_new = CallContractInternal(hash, method, CallFlags.All, false, args); ExecutionContextState state = context_new.GetState <ExecutionContextState>(); state.CallingScriptHash = callingScriptHash; while (CurrentContext != context_current) { StepOut(); } }
private ExecutionContext CallContractInternal(ContractState contract, ContractMethodDescriptor method, CallFlags flags, bool hasReturnValue, IReadOnlyList <StackItem> args) { if (method.Safe) { flags &= ~CallFlags.WriteStates; } else { ContractState currentContract = NativeContract.ContractManagement.GetContract(Snapshot, CurrentScriptHash); if (currentContract?.CanCall(contract, method.Name) == false) { throw new InvalidOperationException($"Cannot Call Method {method} Of Contract {contract.Hash} From Contract {CurrentScriptHash}"); } } if (invocationCounter.TryGetValue(contract.Hash, out var counter)) { invocationCounter[contract.Hash] = counter + 1; } else { invocationCounter[contract.Hash] = 1; } ExecutionContextState state = CurrentContext.GetState <ExecutionContextState>(); UInt160 callingScriptHash = state.ScriptHash; CallFlags callingFlags = state.CallFlags; if (args.Count != method.Parameters.Length) { throw new InvalidOperationException($"Method {method} Expects {method.Parameters.Length} Arguments But Receives {args.Count} Arguments"); } if (hasReturnValue ^ (method.ReturnType != ContractParameterType.Void)) { throw new InvalidOperationException("The return value type does not match."); } ExecutionContext context_new = LoadContract(contract, method, flags & callingFlags); state = context_new.GetState <ExecutionContextState>(); state.CallingScriptHash = callingScriptHash; for (int i = args.Count - 1; i >= 0; i--) { context_new.EvaluationStack.Push(args[i]); } if (NativeContract.IsNative(contract.Hash)) { context_new.EvaluationStack.Push(method.Name); } return(context_new); }
internal static bool Invoke(ApplicationEngine engine, uint method) { if (!methods.TryGetValue(method, out InteropDescriptor descriptor)) { return(false); } if (!descriptor.AllowedTriggers.HasFlag(engine.Trigger)) { return(false); } ExecutionContextState state = engine.CurrentContext.GetState <ExecutionContextState>(); if (!state.CallFlags.HasFlag(descriptor.RequiredCallFlags)) { return(false); } return(descriptor.Handler(engine)); }