private void CallContractInternal(ContractState contract, ContractMethodDescriptor method, Array args, CallFlags flags, ReturnTypeConvention convention) { if (invocationCounter.TryGetValue(contract.Hash, out var counter)) { invocationCounter[contract.Hash] = counter + 1; } else { invocationCounter[contract.Hash] = 1; } GetInvocationState(CurrentContext).Convention = convention; ExecutionContextState state = CurrentContext.GetState <ExecutionContextState>(); UInt160 callingScriptHash = state.ScriptHash; CallFlags callingFlags = state.CallFlags; if (args.Count != method.Parameters.Length) { throw new InvalidOperationException($"Method {method.Name} Expects {method.Parameters.Length} Arguments But Receives {args.Count} Arguments"); } ExecutionContext context_new = LoadContract(contract, method.Name, flags & callingFlags, false); state = context_new.GetState <ExecutionContextState>(); state.CallingScriptHash = callingScriptHash; if (NativeContract.IsNative(contract.Hash)) { context_new.EvaluationStack.Push(args); context_new.EvaluationStack.Push(method.Name); } else { for (int i = args.Count - 1; i >= 0; i--) { context_new.EvaluationStack.Push(args[i]); } } }
private void CallContractInternal(UInt160 contractHash, string method, Array args, CallFlags flags, ReturnTypeConvention convention) { if (method.StartsWith('_')) { throw new ArgumentException($"Invalid Method Name: {method}"); } ContractState contract = NativeContract.Management.GetContract(Snapshot, contractHash); if (contract is null) { throw new InvalidOperationException($"Called Contract Does Not Exist: {contractHash}"); } ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method); if (md is null) { throw new InvalidOperationException($"Method {method} Does Not Exist In Contract {contractHash}"); } if (md.Safe) { flags &= ~CallFlags.WriteStates; } else { ContractState currentContract = NativeContract.Management.GetContract(Snapshot, CurrentScriptHash); if (currentContract?.CanCall(contract, method) == false) { throw new InvalidOperationException($"Cannot Call Method {method} Of Contract {contractHash} From Contract {CurrentScriptHash}"); } } CallContractInternal(contract, md, args, flags, convention); }