Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas)
        {
            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++)
            {
                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 = ApplicationEngine.Create(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.Count != 1 || !engine.ResultStack.Pop().GetBoolean())
                    {
                        return(false);
                    }
                    gas -= engine.GasConsumed;
                }
            }
            return(true);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
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);
        }