예제 #1
0
        public ExecutionContext LoadContract(ContractState contract, string method, CallFlags callFlags, bool packParameters = false)
        {
            ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method);

            if (md is null)
            {
                return(null);
            }

            ExecutionContext context = LoadScript(contract.Script, callFlags, contract.Hash, md.Offset);

            if (NativeContract.IsNative(contract.Hash))
            {
                if (packParameters)
                {
                    using ScriptBuilder sb = new ScriptBuilder();
                    sb.Emit(OpCode.DEPTH, OpCode.PACK);
                    sb.EmitPush(md.Name);
                    LoadScript(sb.ToArray(), CallFlags.None);
                }
            }
            else
            {
                // Call initialization

                var init = contract.Manifest.Abi.GetMethod("_initialize");

                if (init != null)
                {
                    LoadContext(context.Clone(init.Offset), false);
                }
            }

            return(context);
        }
예제 #2
0
 internal void CallNativeContract(string name)
 {
     if (!NativeContract.GetContract(name).Invoke(this))
     {
         throw new InvalidOperationException();
     }
 }
예제 #3
0
        public static StackItem Call(this NativeContract contract, StoreView snapshot, IVerifiable container, string method, params ContractParameter[] args)
        {
            var engine = ApplicationEngine.Create(TriggerType.Application, container, snapshot);

            engine.LoadScript(contract.Script);

            var script = new ScriptBuilder();

            for (var i = args.Length - 1; i >= 0; i--)
            {
                script.EmitPush(args[i]);
            }

            script.EmitPush(args.Length);
            script.Emit(OpCode.PACK);
            script.EmitPush(method);
            engine.LoadScript(script.ToArray());

            if (engine.Execute() != VMState.HALT)
            {
                Exception exception = engine.FaultException;
                while (exception?.InnerException != null)
                {
                    exception = exception.InnerException;
                }
                throw exception ?? new InvalidOperationException();
            }

            if (0 < engine.ResultStack.Count)
            {
                return(engine.ResultStack.Pop());
            }
            return(null);
        }
예제 #4
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);
            }
        }
예제 #5
0
        public static bool Transfer(this NativeContract contract, StoreView snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom)
        {
            var engine = ApplicationEngine.Create(TriggerType.Application,
                                                  new ManualWitness(signFrom ? new UInt160(from) : null), snapshot);

            engine.LoadScript(contract.Script);

            var script = new ScriptBuilder();

            script.EmitPush(amount);
            script.EmitPush(to);
            script.EmitPush(from);
            script.EmitPush(3);
            script.Emit(OpCode.PACK);
            script.EmitPush("transfer");
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(false);
            }

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Boolean));

            return(result.GetBoolean());
        }
예제 #6
0
        public static StackItem Call(this NativeContract contract, StoreView snapshot, IVerifiable container, string method, params ContractParameter[] args)
        {
            var engine = new ApplicationEngine(TriggerType.Application, container, snapshot, 0, true);

            engine.LoadScript(contract.Script);

            var script = new ScriptBuilder();

            for (var i = args.Length - 1; i >= 0; i--)
            {
                script.EmitPush(args[i]);
            }

            script.EmitPush(args.Length);
            script.Emit(OpCode.PACK);
            script.EmitPush(method);
            engine.LoadScript(script.ToArray());

            if (engine.Execute() != VMState.HALT)
            {
                throw new InvalidOperationException();
            }

            return(engine.ResultStack.Pop());
        }
예제 #7
0
파일: TestUtils.cs 프로젝트: xurxogp/neo
 public static StorageKey CreateStorageKey(this NativeContract contract, byte prefix, ISerializable key)
 {
     return(new StorageKey
     {
         Id = contract.Id,
         Key = key.ToArray().Prepend(prefix).ToArray()
     });
 }
예제 #8
0
파일: TestUtils.cs 프로젝트: zhmkof/neo
        public static StorageKey CreateStorageKey(this NativeContract contract, byte prefix, ISerializable key = null)
        {
            var k = new KeyBuilder(contract.Id, prefix);

            if (key != null)
            {
                k = k.Add(key);
            }
            return(k);
        }
예제 #9
0
        protected internal void CallNativeContract(byte version)
        {
            NativeContract contract = NativeContract.GetContract(CurrentScriptHash);

            if (contract is null)
            {
                throw new InvalidOperationException("It is not allowed to use \"System.Contract.CallNative\" directly.");
            }
            contract.Invoke(this, version);
        }
예제 #10
0
        protected internal void CallNativeContract(string name)
        {
            NativeContract contract = NativeContract.GetContract(name);

            if (contract is null || contract.ActiveBlockIndex > Snapshot.PersistingBlock.Index)
            {
                throw new InvalidOperationException();
            }
            contract.Invoke(this);
        }
예제 #11
0
        protected internal void CallNativeContract(int id)
        {
            NativeContract contract = NativeContract.GetContract(id);

            if (contract is null || contract.ActiveBlockIndex > Snapshot.Height)
            {
                throw new InvalidOperationException();
            }
            contract.Invoke(this);
        }
예제 #12
0
 public static JObject NativeContractToJson(this NativeContract contract, ProtocolSettings settings)
 {
     return(new JObject
     {
         ["id"] = contract.Id,
         ["hash"] = contract.Hash.ToString(),
         ["nef"] = contract.Nef.ToJson(),
         ["manifest"] = contract.Manifest.ToJson(),
         ["updatehistory"] = settings.NativeUpdateHistory[contract.Name].Select(p => (JObject)p).ToArray()
     });
 }
예제 #13
0
 public static JObject NativeContractToJson(this NativeContract contract)
 {
     return(new JObject
     {
         ["id"] = contract.Id,
         ["hash"] = contract.Hash.ToString(),
         ["nef"] = contract.Nef.ToJson(),
         ["manifest"] = contract.Manifest.ToJson(),
         ["activeblockindex"] = contract.ActiveBlockIndex
     });
 }
예제 #14
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);
        }
        public static BigInteger TotalSupply(this NativeContract contract, DataCache snapshot)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings);

            using var script = new ScriptBuilder();
            script.EmitDynamicCall(contract.Hash, "totalSupply");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Integer));

            return(result.GetInteger());
        }
예제 #16
0
        protected internal void CallNativeContract(byte version)
        {
            NativeContract contract = NativeContract.GetContract(CurrentScriptHash);

            if (contract is null)
            {
                throw new InvalidOperationException("It is not allowed to use \"System.Contract.CallNative\" directly.");
            }
            uint activeIndex = ProtocolSettings.NativeUpdateHistory[contract.Name][0];

            if (activeIndex > NativeContract.Ledger.CurrentIndex(Snapshot))
            {
                throw new InvalidOperationException($"The native contract {contract.Name} is not active.");
            }
            contract.Invoke(this, version);
        }
        public static BigInteger BalanceOf(this NativeContract contract, DataCache snapshot, byte[] account)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

            using var script = new ScriptBuilder();
            script.EmitDynamicCall(contract.Hash, "balanceOf", account);
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Integer));

            return(result.GetInteger());
        }
        public static string Symbol(this NativeContract contract, DataCache snapshot)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

            using var script = new ScriptBuilder();
            script.EmitDynamicCall(contract.Hash, "symbol");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.ByteString));

            return(result.GetString());
        }
예제 #19
0
        internal static bool VerifyWitness(this IVerifiable verifiable, StoreView snapshot, UInt160 hash, Witness witness, long gas, out long fee)
        {
            fee = 0;
            using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.Clone(), gas))
            {
                CallFlags callFlags    = !witness.VerificationScript.IsStandardContract() ? CallFlags.ReadStates : CallFlags.None;
                byte[]    verification = witness.VerificationScript;

                if (verification.Length == 0)
                {
                    ContractState cs = NativeContract.Management.GetContract(snapshot, hash);
                    if (cs is null)
                    {
                        return(false);
                    }
                    if (engine.LoadContract(cs, "verify", callFlags, true) is null)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (NativeContract.IsNative(hash))
                    {
                        return(false);
                    }
                    if (hash != witness.ScriptHash)
                    {
                        return(false);
                    }
                    engine.LoadScript(verification, callFlags, hash, 0);
                }

                engine.LoadScript(witness.InvocationScript, CallFlags.None);
                if (engine.Execute() == VMState.FAULT)
                {
                    return(false);
                }
                if (engine.ResultStack.Count != 1 || !engine.ResultStack.Peek().GetBoolean())
                {
                    return(false);
                }
                fee = engine.GasConsumed;
            }
            return(true);
        }
예제 #20
0
        public static BigInteger TotalSupply(this NativeContract contract, StoreView snapshot)
        {
            var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

            engine.LoadScript(contract.Script, pcount: 0, configureState: p => p.ScriptHash = contract.Hash);

            var script = new ScriptBuilder();

            script.EmitPush("totalSupply");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Integer));

            return(result.GetInteger());
        }
        public static bool Transfer(this NativeContract contract, DataCache snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom, Block persistingBlock)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application,
                                                        new ManualWitness(signFrom ? new UInt160(from) : null), snapshot, persistingBlock);

            using var script = new ScriptBuilder();
            script.EmitDynamicCall(contract.Hash, "transfer", from, to, amount, null);
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(false);
            }

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Boolean));

            return(result.GetBoolean());
        }
예제 #22
0
        public static BigInteger Decimals(this NativeContract contract, StoreView snapshot)
        {
            var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

            engine.LoadScript(contract.Script, CallFlags.All, contract.Hash);

            var script = new ScriptBuilder();

            script.EmitPush(0);
            script.Emit(OpCode.PACK);
            script.EmitPush("decimals");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Integer));

            return(result.GetInteger());
        }
예제 #23
0
        public static string Symbol(this NativeContract contract)
        {
            var engine = ApplicationEngine.Create(TriggerType.Application, null, null);

            engine.LoadScript(contract.Script);

            var script = new ScriptBuilder();

            script.EmitPush(0);
            script.Emit(OpCode.PACK);
            script.EmitPush("symbol");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.ByteString));

            return(result.GetString());
        }
예제 #24
0
        public static BigInteger TotalSupply(this NativeContract contract, Persistence.Snapshot snapshot)
        {
            var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);

            engine.LoadScript(contract.Script);

            var script = new ScriptBuilder();

            script.EmitPush(0);
            script.Emit(OpCode.PACK);
            script.EmitPush("totalSupply");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Integer));

            return((result as VM.Types.Integer).GetBigInteger());
        }
예제 #25
0
        public static BigInteger Decimals(this NativeContract contract)
        {
            var engine = new ApplicationEngine(TriggerType.Application, null, null, 0);

            engine.LoadScript(contract.Script);

            var script = new ScriptBuilder();

            script.EmitPush(0);
            script.Emit(OpCode.PACK);
            script.EmitPush("decimals");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Integer));

            return((result as VM.Types.Integer).GetBigInteger());
        }
예제 #26
0
        public static string Name(this NativeContract contract)
        {
            var engine = new ApplicationEngine(TriggerType.Application, null, null, 0);

            engine.LoadScript(contract.Script);

            var script = new ScriptBuilder();

            script.EmitPush(0);
            script.Emit(OpCode.PACK);
            script.EmitPush("name");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.ByteArray));

            return(Encoding.UTF8.GetString((result as VM.Types.ByteArray).GetByteArray()));
        }
예제 #27
0
        public static BigInteger BalanceOf(this NativeContract contract, StoreView snapshot, byte[] account)
        {
            var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

            engine.LoadScript(contract.Script);

            var script = new ScriptBuilder();

            script.EmitPush(account);
            script.EmitPush(1);
            script.Emit(OpCode.PACK);
            script.EmitPush("balanceOf");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Integer));

            return(result.GetInteger());
        }
예제 #28
0
        public static StackItem Call(this NativeContract contract, StoreView snapshot, IVerifiable container, Block persistingBlock, string method, params ContractParameter[] args)
        {
            var engine        = ApplicationEngine.Create(TriggerType.Application, container, snapshot, persistingBlock);
            var contractState = NativeContract.ContractManagement.GetContract(snapshot, contract.Hash);

            if (contractState == null)
            {
                throw new InvalidOperationException();
            }
            var md = contract.Manifest.Abi.GetMethod(method, args.Length);

            var script = new ScriptBuilder();

            for (var i = args.Length - 1; i >= 0; i--)
            {
                script.EmitPush(args[i]);
            }

            script.EmitPush(method);
            engine.LoadContract(contractState, md, CallFlags.All);
            engine.LoadScript(script.ToArray());

            if (engine.Execute() != VMState.HALT)
            {
                Exception exception = engine.FaultException;
                while (exception?.InnerException != null)
                {
                    exception = exception.InnerException;
                }
                throw exception ?? new InvalidOperationException();
            }

            if (0 < engine.ResultStack.Count)
            {
                return(engine.ResultStack.Pop());
            }
            return(null);
        }
예제 #29
0
        public static string[] SupportedStandards(this NativeContract contract)
        {
            var engine = new ApplicationEngine(TriggerType.Application, null, null, 0);

            engine.LoadScript(contract.Script);

            var script = new ScriptBuilder();

            script.EmitPush(0);
            script.Emit(OpCode.PACK);
            script.EmitPush("supportedStandards");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Array));

            return((result as VM.Types.Array).ToArray()
                   .Select(u => Encoding.ASCII.GetString(u.GetByteArray()))
                   .ToArray());
        }
예제 #30
0
        public static StackItem Call(this NativeContract contract, DataCache snapshot, IVerifiable container, Block persistingBlock, string method, params ContractParameter[] args)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, container, snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings);
            using var script = new ScriptBuilder();
            script.EmitDynamicCall(contract.Hash, method, args);
            engine.LoadScript(script.ToArray());

            if (engine.Execute() != VMState.HALT)
            {
                Exception exception = engine.FaultException;
                while (exception?.InnerException != null)
                {
                    exception = exception.InnerException;
                }
                throw exception ?? new InvalidOperationException();
            }

            if (0 < engine.ResultStack.Count)
            {
                return(engine.ResultStack.Pop());
            }
            return(null);
        }