Ejemplo n.º 1
0
        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]);
                }
            }
        }
Ejemplo n.º 2
0
        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);
        }