示例#1
0
        internal bool Invoke(ApplicationEngine engine)
        {
            if (!engine.CurrentScriptHash.Equals(Hash))
            {
                return(false);
            }
            string operation = engine.CurrentContext.EvaluationStack.Pop().GetString();
            Array  args      = (Array)engine.CurrentContext.EvaluationStack.Pop();

            if (!methods.TryGetValue(operation, out ContractMethodMetadata method))
            {
                return(false);
            }
            ExecutionContextState state = engine.CurrentContext.GetState <ExecutionContextState>();

            if (!state.CallFlags.HasFlag(method.RequiredCallFlags))
            {
                return(false);
            }
            if (!engine.AddGas(method.Price))
            {
                return(false);
            }
            StackItem result = method.Delegate(engine, args);

            engine.CurrentContext.EvaluationStack.Push(result);
            return(true);
        }
示例#2
0
        internal bool Invoke(ApplicationEngine engine)
        {
            if (!engine.CurrentScriptHash.Equals(Hash))
            {
                return(false);
            }
            if (!engine.TryPop(out string operation))
            {
                return(false);
            }
            if (!engine.TryPop(out Array args))
            {
                return(false);
            }
            if (!methods.TryGetValue(operation, out ContractMethodMetadata method))
            {
                return(false);
            }
            ExecutionContextState state = engine.CurrentContext.GetState <ExecutionContextState>();

            if (!state.CallFlags.HasFlag(method.RequiredCallFlags))
            {
                return(false);
            }
            if (!engine.AddGas(method.Price))
            {
                return(false);
            }
            List <object> parameters = new List <object>();

            if (method.NeedApplicationEngine)
            {
                parameters.Add(engine);
            }
            if (method.NeedSnapshot)
            {
                parameters.Add(engine.Snapshot);
            }
            for (int i = 0; i < method.Parameters.Length; i++)
            {
                StackItem item = i < args.Count ? args[i] : StackItem.Null;
                parameters.Add(engine.Convert(item, method.Parameters[i]));
            }
            object returnValue = method.Handler.Invoke(this, parameters.ToArray());

            if (method.Handler.ReturnType != typeof(void))
            {
                engine.Push(engine.Convert(returnValue));
            }
            return(true);
        }
示例#3
0
 internal async void Invoke(ApplicationEngine engine, byte version)
 {
     try
     {
         if (version != 0)
         {
             throw new InvalidOperationException($"The native contract of version {version} is not active.");
         }
         ExecutionContext       context = engine.CurrentContext;
         ContractMethodMetadata method  = methods[context.InstructionPointer];
         ExecutionContextState  state   = context.GetState <ExecutionContextState>();
         if (!state.CallFlags.HasFlag(method.RequiredCallFlags))
         {
             throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}.");
         }
         engine.AddGas(method.CpuFee * Policy.GetExecFeeFactor(engine.Snapshot) + method.StorageFee * Policy.GetStoragePrice(engine.Snapshot));
         List <object> parameters = new List <object>();
         if (method.NeedApplicationEngine)
         {
             parameters.Add(engine);
         }
         if (method.NeedSnapshot)
         {
             parameters.Add(engine.Snapshot);
         }
         for (int i = 0; i < method.Parameters.Length; i++)
         {
             parameters.Add(engine.Convert(context.EvaluationStack.Pop(), method.Parameters[i]));
         }
         object returnValue = method.Handler.Invoke(this, parameters.ToArray());
         if (returnValue is ContractTask task)
         {
             await task;
             returnValue = task.GetResult();
         }
         if (method.Handler.ReturnType != typeof(void) && method.Handler.ReturnType != typeof(ContractTask))
         {
             context.EvaluationStack.Push(engine.Convert(returnValue));
         }
     }
     catch (Exception ex)
     {
         engine.Throw(ex);
     }
 }
示例#4
0
        internal void Invoke(ApplicationEngine engine, byte version)
        {
            if (ActiveBlockIndex > Ledger.CurrentIndex(engine.Snapshot))
            {
                throw new InvalidOperationException($"The native contract {Name} is not active.");
            }
            if (version != 0)
            {
                throw new InvalidOperationException($"The native contract of version {version} is not active.");
            }
            ExecutionContext       context = engine.CurrentContext;
            ContractMethodMetadata method  = methods[context.InstructionPointer];
            ExecutionContextState  state   = context.GetState <ExecutionContextState>();

            if (!state.CallFlags.HasFlag(method.RequiredCallFlags))
            {
                throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}.");
            }
            engine.AddGas(method.Price);
            List <object> parameters = new List <object>();

            if (method.NeedApplicationEngine)
            {
                parameters.Add(engine);
            }
            if (method.NeedSnapshot)
            {
                parameters.Add(engine.Snapshot);
            }
            for (int i = 0; i < method.Parameters.Length; i++)
            {
                parameters.Add(engine.Convert(context.EvaluationStack.Pop(), method.Parameters[i]));
            }
            object returnValue = method.Handler.Invoke(this, parameters.ToArray());

            if (method.Handler.ReturnType != typeof(void))
            {
                context.EvaluationStack.Push(engine.Convert(returnValue));
            }
        }
示例#5
0
        internal void Invoke(ApplicationEngine engine)
        {
            if (!engine.CurrentScriptHash.Equals(Hash))
            {
                throw new InvalidOperationException("It is not allowed to use Neo.Native.Call directly to call native contracts. System.Contract.Call should be used.");
            }
            ExecutionContext       context   = engine.CurrentContext;
            string                 operation = context.EvaluationStack.Pop().GetString();
            Array                  args      = context.EvaluationStack.Pop <Array>();
            ContractMethodMetadata method    = methods[operation];
            ExecutionContextState  state     = context.GetState <ExecutionContextState>();

            if (!state.CallFlags.HasFlag(method.RequiredCallFlags))
            {
                throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}.");
            }
            engine.AddGas(method.Price);
            List <object> parameters = new List <object>();

            if (method.NeedApplicationEngine)
            {
                parameters.Add(engine);
            }
            if (method.NeedSnapshot)
            {
                parameters.Add(engine.Snapshot);
            }
            for (int i = 0; i < method.Parameters.Length; i++)
            {
                StackItem item = i < args.Count ? args[i] : StackItem.Null;
                parameters.Add(engine.Convert(item, method.Parameters[i]));
            }
            object returnValue = method.Handler.Invoke(this, parameters.ToArray());

            if (method.Handler.ReturnType != typeof(void))
            {
                context.EvaluationStack.Push(engine.Convert(returnValue));
            }
        }