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); }
private void CallContractInternal(UInt160 contractHash, string method, CallFlags flags, bool hasReturnValue, StackItem[] args) { ContractState contract = NativeContract.ContractManagement.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.ContractManagement.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, flags, hasReturnValue, args); }
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); }