Esempio n. 1
0
        protected bool Blockchain_GetContract(ExecutionEngine engine)
        {
            UInt160       hash     = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
            ContractState contract = Snapshot.Contracts.TryGet(hash);

            if (contract == null)
            {
                engine.CurrentContext.EvaluationStack.Push(new byte[0]);
            }
            else
            {
                engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(contract));
            }
            return(true);
        }
Esempio n. 2
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]);
            }

            return(context_new);
        }
Esempio n. 3
0
        private ExecutionContext 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, args.Length);

            if (md is null)
            {
                throw new InvalidOperationException($"Method \"{method}\" with {args.Length} parameter(s) doesn't exist in the contract {contractHash}.");
            }
            return(CallContractInternal(contract, md, flags, hasReturnValue, args));
        }
Esempio n. 4
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);
        }
Esempio n. 5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DeployedContract"/> class with the specified <see cref="ContractState"/>.
        /// </summary>
        /// <param name="contract">The <see cref="ContractState"/> corresponding to the contract.</param>
        public DeployedContract(ContractState contract)
        {
            if (contract is null)
            {
                throw new ArgumentNullException(nameof(contract));
            }

            Script     = null;
            ScriptHash = contract.Hash;
            ContractMethodDescriptor descriptor = contract.Manifest.Abi.GetMethod("verify", -1);

            if (descriptor is null)
            {
                throw new NotSupportedException("The smart contract haven't got verify method.");
            }

            ParameterList = descriptor.Parameters.Select(u => u.Type).ToArray();
        }
Esempio n. 6
0
        private bool Contract_GetStorageContext(ExecutionEngine engine)
        {
            ContractState contract = engine.EvaluationStack.Pop().GetInterface <ContractState>();

            if (!contracts_created.TryGetValue(contract.ScriptHash, out UInt160 created))
            {
                return(false);
            }
            if (!created.Equals(new UInt160(engine.CurrentContext.ScriptHash)))
            {
                return(false);
            }
            engine.EvaluationStack.Push(StackItem.FromInterface(new StorageContext
            {
                ScriptHash = contract.ScriptHash
            }));
            return(true);
        }
Esempio n. 7
0
        private bool Contract_Migrate(ExecutionEngine engine)
        {
            if (Trigger != TriggerType.Application)
            {
                return(false);
            }
            byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
            if (script.Length > 1024 * 1024)
            {
                return(false);
            }
            ContractPropertyState contract_properties = (ContractPropertyState)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();
            UInt160       hash     = script.ToScriptHash();
            ContractState contract = Snapshot.Contracts.TryGet(hash);

            if (contract == null)
            {
                contract = new ContractState
                {
                    Script             = script,
                    ContractProperties = contract_properties
                };
                Snapshot.Contracts.Add(hash, contract);
                ContractsCreated.Add(hash, new UInt160(engine.CurrentContext.ScriptHash));
                if (contract.HasStorage)
                {
                    foreach (var pair in Snapshot.Storages.Find(engine.CurrentContext.ScriptHash).ToArray())
                    {
                        Snapshot.Storages.Add(new StorageKey
                        {
                            ScriptHash = hash,
                            Key        = pair.Key.Key
                        }, new StorageItem
                        {
                            Value      = pair.Value.Value,
                            IsConstant = false
                        });
                    }
                }
            }
            engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(contract));
            return(Contract_Destroy(engine));
        }
Esempio n. 8
0
 private bool CheckDynamicInvoke(OpCode nextInstruction)
 {
     if (nextInstruction == OpCode.APPCALL || nextInstruction == OpCode.TAILCALL)
     {
         for (int i = CurrentContext.InstructionPointer + 1; i < CurrentContext.InstructionPointer + 21; i++)
         {
             if (CurrentContext.Script[i] != 0)
             {
                 return(true);
             }
         }
         // if we get this far it is a dynamic call
         // now look at the current executing script
         // to determine if it can do dynamic calls
         ContractState contract = script_table.GetContractState(CurrentContext.ScriptHash);
         return(contract.HasDynamicInvoke);
     }
     return(true);
 }
Esempio n. 9
0
        private bool Contract_Destroy(ExecutionEngine engine)
        {
            UInt160       hash     = new UInt160(engine.CurrentContext.ScriptHash);
            ContractState contract = contracts.TryGet(hash);

            if (contract == null)
            {
                return(true);
            }
            contracts.Delete(hash);
            if (contract.HasStorage)
            {
                foreach (var pair in storages.Find(hash.ToArray()))
                {
                    storages.Delete(pair.Key);
                }
            }
            return(true);
        }
Esempio n. 10
0
        private static bool Contract_Create(ApplicationEngine engine)
        {
            if (engine.Trigger != TriggerType.Application)
            {
                return(false);
            }
            byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
            if (script.Length > 1024 * 1024)
            {
                return(false);
            }

            var manifest = engine.CurrentContext.EvaluationStack.Pop().GetString();

            if (manifest.Length > ContractManifest.MaxLength)
            {
                return(false);
            }

            UInt160       hash     = script.ToScriptHash();
            ContractState contract = engine.Snapshot.Contracts.TryGet(hash);

            if (contract != null)
            {
                return(false);
            }
            contract = new ContractState
            {
                Script   = script,
                Manifest = ContractManifest.Parse(manifest)
            };

            if (!contract.Manifest.IsValid(hash))
            {
                return(false);
            }

            engine.Snapshot.Contracts.Add(hash, contract);
            engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(contract));
            return(true);
        }
Esempio n. 11
0
        protected override ExecutionContext LoadToken(ushort tokenId)
        {
            ContractState contract = CurrentContext.GetState <ExecutionContextState>().Contract;

            if (contract is null || tokenId >= contract.Nef.Tokens.Length)
            {
                throw new InvalidOperationException();
            }
            MethodToken token = contract.Nef.Tokens[tokenId];

            if (token.ParametersCount > CurrentContext.EvaluationStack.Count)
            {
                throw new InvalidOperationException();
            }
            StackItem[] args = new StackItem[token.ParametersCount];
            for (int i = 0; i < token.ParametersCount; i++)
            {
                args[i] = Pop();
            }
            return(CallContractInternal(token.Hash, token.Method, token.CallFlags, token.HasReturnValue, args));
        }
Esempio n. 12
0
        public ExecutionContext LoadContract(ContractState contract, ContractMethodDescriptor method, CallFlags callFlags)
        {
            ExecutionContext context = LoadScript(contract.Script,
                                                  rvcount: method.ReturnType == ContractParameterType.Void ? 0 : 1,
                                                  initialPosition: method.Offset,
                                                  configureState: p =>
            {
                p.CallFlags  = callFlags;
                p.ScriptHash = contract.Hash;
                p.Contract   = contract;
            });

            // Call initialization
            var init = contract.Manifest.Abi.GetMethod("_initialize", 0);

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

            return(context);
        }
Esempio n. 13
0
 protected bool Contract_GetStorageContext(ExecutionEngine engine)
 {
     if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface)
     {
         ContractState contract = _interface.GetInterface <ContractState>();
         if (!ContractsCreated.TryGetValue(contract.ScriptHash, out UInt160 created))
         {
             return(false);
         }
         if (!created.Equals(new UInt160(engine.CurrentContext.ScriptHash)))
         {
             return(false);
         }
         engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(new StorageContext
         {
             ScriptHash = contract.ScriptHash,
             IsReadOnly = false
         }));
         return(true);
     }
     return(false);
 }
Esempio n. 14
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]);
                }
            }
        }
Esempio n. 15
0
        protected virtual bool Storage_Get(ExecutionEngine engine)
        {
            StorageContext context  = engine.EvaluationStack.Pop().GetInterface <StorageContext>();
            ContractState  contract = Blockchain.Default.GetContract(context.ScriptHash);

            if (contract == null)
            {
                return(false);
            }
            if (!contract.HasStorage)
            {
                return(false);
            }
            byte[]      key  = engine.EvaluationStack.Pop().GetByteArray();
            StorageItem item = Blockchain.Default.GetStorageItem(new StorageKey
            {
                ScriptHash = context.ScriptHash,
                Key        = key
            });

            engine.EvaluationStack.Push(item?.Value ?? new byte[0]);
            return(true);
        }
Esempio n. 16
0
        private static bool Contract_Destroy(ApplicationEngine engine)
        {
            if (engine.Trigger != TriggerType.Application)
            {
                return(false);
            }
            UInt160       hash     = engine.CurrentScriptHash;
            ContractState contract = engine.Snapshot.Contracts.TryGet(hash);

            if (contract == null)
            {
                return(true);
            }
            engine.Snapshot.Contracts.Delete(hash);
            if (contract.HasStorage)
            {
                foreach (var pair in engine.Snapshot.Storages.Find(hash.ToArray()))
                {
                    engine.Snapshot.Storages.Delete(pair.Key);
                }
            }
            return(true);
        }
Esempio n. 17
0
        protected bool Contract_Destroy(ExecutionEngine engine)
        {
            if (Trigger != TriggerType.Application)
            {
                return(false);
            }
            UInt160       hash     = new UInt160(engine.CurrentContext.ScriptHash);
            ContractState contract = Snapshot.Contracts.TryGet(hash);

            if (contract == null)
            {
                return(true);
            }
            Snapshot.Contracts.Delete(hash);
            if (contract.HasStorage)
            {
                foreach (var pair in Snapshot.Storages.Find(hash.ToArray()))
                {
                    Snapshot.Storages.Delete(pair.Key);
                }
            }
            return(true);
        }
Esempio n. 18
0
        private static bool Contract_Update(ApplicationEngine engine)
        {
            if (engine.Trigger != TriggerType.Application)
            {
                return(false);
            }

            byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
            if (script.Length > 1024 * 1024)
            {
                return(false);
            }
            var manifest = engine.CurrentContext.EvaluationStack.Pop().GetString();

            if (manifest.Length > ContractManifest.MaxLength)
            {
                return(false);
            }

            var contract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash);

            if (contract is null)
            {
                return(false);
            }

            if (script.Length > 0)
            {
                UInt160 hash_new = script.ToScriptHash();
                if (hash_new.Equals(engine.CurrentScriptHash))
                {
                    return(false);
                }
                if (engine.Snapshot.Contracts.TryGet(hash_new) != null)
                {
                    return(false);
                }
                contract = new ContractState
                {
                    Script   = script,
                    Manifest = contract.Manifest
                };
                contract.Manifest.Abi.Hash = hash_new;
                engine.Snapshot.Contracts.Add(hash_new, contract);
                if (contract.HasStorage)
                {
                    foreach (var pair in engine.Snapshot.Storages.Find(engine.CurrentScriptHash.ToArray()).ToArray())
                    {
                        engine.Snapshot.Storages.Add(new StorageKey
                        {
                            ScriptHash = hash_new,
                            Key        = pair.Key.Key
                        }, new StorageItem
                        {
                            Value      = pair.Value.Value,
                            IsConstant = false
                        });
                    }
                }
                Contract_Destroy(engine);
            }
            if (manifest.Length > 0)
            {
                contract          = engine.Snapshot.Contracts.GetAndChange(contract.ScriptHash);
                contract.Manifest = ContractManifest.Parse(manifest);
                if (!contract.Manifest.IsValid(contract.ScriptHash))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 19
0
        internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All)
        {
            if (gas < 0)
            {
                return(false);
            }
            if (gas > MaxVerificationGas)
            {
                gas = MaxVerificationGas;
            }

            UInt160[] hashes;
            try
            {
                hashes = verifiable.GetScriptHashesForVerifying(snapshot);
            }
            catch (InvalidOperationException)
            {
                return(false);
            }
            if (hashes.Length != verifiable.Witnesses.Length)
            {
                return(false);
            }
            for (int i = 0; i < hashes.Length; i++)
            {
                WitnessFlag flag = verifiable.Witnesses[i].StateDependent ? WitnessFlag.StateDependent : WitnessFlag.StateIndependent;
                if (!filter.HasFlag(flag))
                {
                    gas -= verifiable.Witnesses[i].GasConsumed;
                    if (gas < 0)
                    {
                        return(false);
                    }
                    continue;
                }

                using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.Clone(), gas))
                {
                    CallFlags callFlags    = verifiable.Witnesses[i].StateDependent ? CallFlags.AllowStates : CallFlags.None;
                    byte[]    verification = verifiable.Witnesses[i].VerificationScript;

                    if (verification.Length == 0)
                    {
                        ContractState cs = snapshot.Contracts.TryGet(hashes[i]);
                        if (cs is null)
                        {
                            return(false);
                        }
                        if (engine.LoadContract(cs, "verify", callFlags, true) is null)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (NativeContract.IsNative(hashes[i]))
                        {
                            return(false);
                        }
                        if (hashes[i] != verifiable.Witnesses[i].ScriptHash)
                        {
                            return(false);
                        }
                        engine.LoadScript(verification, callFlags, hashes[i], 0);
                    }

                    engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None);
                    if (engine.Execute() == VMState.FAULT)
                    {
                        return(false);
                    }
                    if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean())
                    {
                        return(false);
                    }
                    gas -= engine.GasConsumed;
                    verifiable.Witnesses[i].GasConsumed = engine.GasConsumed;
                }
            }
            return(true);
        }
Esempio n. 20
0
        internal static bool VerifyWitness(this IVerifiable verifiable, ProtocolSettings settings, DataCache snapshot, UInt160 hash, Witness witness, long gas, out long fee)
        {
            fee = 0;
            Script invocationScript;

            try
            {
                invocationScript = new Script(witness.InvocationScript, true);
            }
            catch (BadScriptException)
            {
                return(false);
            }
            using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.CreateSnapshot(), null, settings, gas))
            {
                if (witness.VerificationScript.Length == 0)
                {
                    ContractState cs = NativeContract.ContractManagement.GetContract(snapshot, hash);
                    if (cs is null)
                    {
                        return(false);
                    }
                    ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod("verify", -1);
                    if (md?.ReturnType != ContractParameterType.Boolean)
                    {
                        return(false);
                    }
                    engine.LoadContract(cs, md, CallFlags.ReadOnly);
                }
                else
                {
                    if (NativeContract.IsNative(hash))
                    {
                        return(false);
                    }
                    if (hash != witness.ScriptHash)
                    {
                        return(false);
                    }
                    Script verificationScript;
                    try
                    {
                        verificationScript = new Script(witness.VerificationScript, true);
                    }
                    catch (BadScriptException)
                    {
                        return(false);
                    }
                    engine.LoadScript(verificationScript, initialPosition: 0, configureState: p =>
                    {
                        p.CallFlags  = CallFlags.ReadOnly;
                        p.ScriptHash = hash;
                    });
                }

                engine.LoadScript(invocationScript, configureState: p => p.CallFlags = CallFlags.None);

                if (engine.Execute() == VMState.FAULT)
                {
                    return(false);
                }
                if (!engine.ResultStack.Peek().GetBoolean())
                {
                    return(false);
                }
                fee = engine.GasConsumed;
            }
            return(true);
        }
Esempio n. 21
0
        private bool Contract_Migrate(ExecutionEngine engine)
        {
            byte[] script = engine.EvaluationStack.Pop().GetByteArray();
            if (script.Length > 1024 * 1024)
            {
                return(false);
            }
            ContractParameterType[] parameter_list = engine.EvaluationStack.Pop().GetByteArray().Select(p => (ContractParameterType)p).ToArray();
            if (parameter_list.Length > 252)
            {
                return(false);
            }
            ContractParameterType return_type         = (ContractParameterType)(byte)engine.EvaluationStack.Pop().GetBigInteger();
            ContractPropertyState contract_properties = (ContractPropertyState)(byte)engine.EvaluationStack.Pop().GetBigInteger();

            if (engine.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string name = Encoding.UTF8.GetString(engine.EvaluationStack.Pop().GetByteArray());

            if (engine.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string version = Encoding.UTF8.GetString(engine.EvaluationStack.Pop().GetByteArray());

            if (engine.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string author = Encoding.UTF8.GetString(engine.EvaluationStack.Pop().GetByteArray());

            if (engine.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string email = Encoding.UTF8.GetString(engine.EvaluationStack.Pop().GetByteArray());

            if (engine.EvaluationStack.Peek().GetByteArray().Length > 65536)
            {
                return(false);
            }
            string        description = Encoding.UTF8.GetString(engine.EvaluationStack.Pop().GetByteArray());
            UInt160       hash        = script.ToScriptHash();
            ContractState contract    = contracts.TryGet(hash);

            if (contract == null)
            {
                contract = new ContractState
                {
                    Script             = script,
                    ParameterList      = parameter_list,
                    ReturnType         = return_type,
                    ContractProperties = contract_properties,
                    Name        = name,
                    CodeVersion = version,
                    Author      = author,
                    Email       = email,
                    Description = description
                };
                contracts.Add(hash, contract);
                contracts_created.Add(hash, new UInt160(engine.CurrentContext.ScriptHash));
                if (contract.HasStorage)
                {
                    foreach (var pair in storages.Find(engine.CurrentContext.ScriptHash).ToArray())
                    {
                        storages.Add(new StorageKey
                        {
                            ScriptHash = hash,
                            Key        = pair.Key.Key
                        }, new StorageItem
                        {
                            Value = pair.Value.Value
                        });
                    }
                }
            }
            engine.EvaluationStack.Push(StackItem.FromInterface(contract));
            return(Contract_Destroy(engine));
        }
Esempio n. 22
0
 /// <summary>
 /// Return true if is allowed
 /// </summary>
 /// <param name="targetContract">The contract that we are calling</param>
 /// <param name="targetMethod">The method that we are calling</param>
 /// <returns>Return true or false</returns>
 public bool CanCall(ContractState targetContract, string targetMethod)
 {
     return(Manifest.Permissions.Any(u => u.IsAllowed(targetContract, targetMethod)));
 }
Esempio n. 23
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(), null, gas))
            {
                CallFlags callFlags    = !witness.VerificationScript.IsStandardContract() ? CallFlags.ReadStates : CallFlags.None;
                byte[]    verification = witness.VerificationScript;

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

                engine.LoadScript(witness.InvocationScript, configureState: p => p.CallFlags = CallFlags.None);

                if (NativeContract.IsNative(hash))
                {
                    try
                    {
                        engine.StepOut();
                        engine.Push("verify");
                    }
                    catch { }
                }

                if (engine.Execute() == VMState.FAULT)
                {
                    return(false);
                }
                if (!engine.ResultStack.Peek().GetBoolean())
                {
                    return(false);
                }
                fee = engine.GasConsumed;
            }
            return(true);
        }
Esempio n. 24
0
        private bool Contract_Create(ExecutionEngine engine)
        {
            if (Trigger != TriggerType.Application)
            {
                return(false);
            }
            byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
            if (script.Length > 1024 * 1024)
            {
                return(false);
            }
            ContractParameterType[] parameter_list = engine.CurrentContext.EvaluationStack.Pop().GetByteArray().Select(p => (ContractParameterType)p).ToArray();
            if (parameter_list.Length > 252)
            {
                return(false);
            }
            ContractParameterType return_type         = (ContractParameterType)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();
            ContractPropertyState contract_properties = (ContractPropertyState)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string name = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string version = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string author = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string email = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 65536)
            {
                return(false);
            }
            string        description = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
            UInt160       hash        = script.ToScriptHash();
            ContractState contract    = Snapshot.Contracts.TryGet(hash);

            if (contract == null)
            {
                contract = new ContractState
                {
                    Script             = script,
                    ParameterList      = parameter_list,
                    ReturnType         = return_type,
                    ContractProperties = contract_properties,
                    Name        = name,
                    CodeVersion = version,
                    Author      = author,
                    Email       = email,
                    Description = description
                };
                Snapshot.Contracts.Add(hash, contract);
                ContractsCreated.Add(hash, new UInt160(engine.CurrentContext.ScriptHash));
            }
            engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(contract));
            return(true);
        }
Esempio n. 25
0
        internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas)
        {
            if (gas < 0)
            {
                return(false);
            }

            UInt160[] hashes;
            try
            {
                hashes = verifiable.GetScriptHashesForVerifying(snapshot);
            }
            catch (InvalidOperationException)
            {
                return(false);
            }
            if (hashes.Length != verifiable.Witnesses.Length)
            {
                return(false);
            }
            for (int i = 0; i < hashes.Length; i++)
            {
                int    offset;
                byte[] verification = verifiable.Witnesses[i].VerificationScript;
                if (verification.Length == 0)
                {
                    ContractState cs = snapshot.Contracts.TryGet(hashes[i]);
                    if (cs is null)
                    {
                        return(false);
                    }
                    ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod("verify");
                    if (md is null)
                    {
                        return(false);
                    }
                    verification = cs.Script;
                    offset       = md.Offset;
                }
                else
                {
                    if (hashes[i] != verifiable.Witnesses[i].ScriptHash)
                    {
                        return(false);
                    }
                    offset = 0;
                }
                using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, verifiable, snapshot, gas))
                {
                    engine.LoadScript(verification, CallFlags.ReadOnly).InstructionPointer = offset;
                    engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None);
                    if (engine.Execute() == VMState.FAULT)
                    {
                        return(false);
                    }
                    if (!engine.ResultStack.TryPop(out StackItem result) || !result.ToBoolean())
                    {
                        return(false);
                    }
                    gas -= engine.GasConsumed;
                }
            }
            return(true);
        }
Esempio n. 26
0
        internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All)
        {
            if (gas < 0)
            {
                return(false);
            }
            if (gas > MaxVerificationGas)
            {
                gas = MaxVerificationGas;
            }

            UInt160[] hashes;
            try
            {
                hashes = verifiable.GetScriptHashesForVerifying(snapshot);
            }
            catch (InvalidOperationException)
            {
                return(false);
            }
            if (hashes.Length != verifiable.Witnesses.Length)
            {
                return(false);
            }
            for (int i = 0; i < hashes.Length; i++)
            {
                WitnessFlag flag = verifiable.Witnesses[i].StateDependent ? WitnessFlag.StateDependent : WitnessFlag.StateIndependent;
                if (!filter.HasFlag(flag))
                {
                    gas -= verifiable.Witnesses[i].GasConsumed;
                    if (gas < 0)
                    {
                        return(false);
                    }
                    continue;
                }

                int offset;
                ContractMethodDescriptor init = null;
                byte[] verification           = verifiable.Witnesses[i].VerificationScript;
                if (verification.Length == 0)
                {
                    ContractState cs = snapshot.Contracts.TryGet(hashes[i]);
                    if (cs is null)
                    {
                        return(false);
                    }
                    ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod("verify");
                    if (md is null)
                    {
                        return(false);
                    }
                    verification = cs.Script;
                    offset       = md.Offset;
                    init         = cs.Manifest.Abi.GetMethod("_initialize");
                }
                else
                {
                    if (NativeContract.IsNative(hashes[i]))
                    {
                        return(false);
                    }
                    if (hashes[i] != verifiable.Witnesses[i].ScriptHash)
                    {
                        return(false);
                    }
                    offset = 0;
                }
                using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.Clone(), gas))
                {
                    CallFlags        callFlags = verifiable.Witnesses[i].StateDependent ? CallFlags.AllowStates : CallFlags.None;
                    ExecutionContext context   = engine.LoadScript(verification, callFlags, offset);
                    if (NativeContract.IsNative(hashes[i]))
                    {
                        using ScriptBuilder sb = new ScriptBuilder();
                        sb.Emit(OpCode.DEPTH, OpCode.PACK);
                        sb.EmitPush("verify");
                        engine.LoadScript(sb.ToArray(), CallFlags.None);
                    }
                    else if (init != null)
                    {
                        engine.LoadContext(context.Clone(init.Offset), false);
                    }
                    engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None);
                    if (engine.Execute() == VMState.FAULT)
                    {
                        return(false);
                    }
                    if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean())
                    {
                        return(false);
                    }
                    gas -= engine.GasConsumed;
                    verifiable.Witnesses[i].GasConsumed = engine.GasConsumed;
                }
            }
            return(true);
        }