示例#1
0
        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);
            }
        }
示例#2
0
        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();
        }
示例#3
0
        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();
        }
示例#4
0
        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))));
        }
示例#5
0
        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);
        }
示例#6
0
        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();
            }
        }
示例#7
0
        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);
        }
示例#8
0
        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));
        }