Пример #1
0
        public static ApplicationEngine Run(byte[] script, StoreView snapshot,
                                            IVerifiable container = null, Block persistingBlock = null, bool testMode = false, long extraGAS = default)
        {
            snapshot.PersistingBlock = persistingBlock ?? snapshot.PersistingBlock ?? CreateDummyBlock(snapshot);
            ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, container, snapshot, extraGAS, testMode);

            engine.LoadScript(script);
            engine.Execute();
            return(engine);
        }
Пример #2
0
        internal static bool VerifyWitnesses(this IVerifiable verifiable, Snapshot 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++)
            {
                byte[] verification = verifiable.Witnesses[i].VerificationScript;
                if (verification.Length == 0)
                {
                    verification = snapshot.Contracts.TryGet(hashes[i])?.Script;
                    if (verification is null)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (hashes[i] != verifiable.Witnesses[i].ScriptHash)
                    {
                        return(false);
                    }
                }
                using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, verifiable, snapshot, gas))
                {
                    engine.LoadScript(verification);
                    engine.LoadScript(verifiable.Witnesses[i].InvocationScript);
                    if (engine.Execute().HasFlag(VMState.FAULT))
                    {
                        return(false);
                    }
                    if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean())
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Пример #3
0
 internal static bool VerifyWitnesses(this IVerifiable verifiable, Snapshot snapshot)
 {
     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++)
     {
         byte[] verification = verifiable.Witnesses[i].VerificationScript;
         if (verification.Length == 0)
         {
             using (ScriptBuilder sb = new ScriptBuilder())
             {
                 sb.EmitAppCall(hashes[i].ToArray());
                 verification = sb.ToArray();
             }
         }
         else
         {
             if (hashes[i] != verifiable.Witnesses[i].ScriptHash)
             {
                 return(false);
             }
         }
         using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, verifiable, snapshot, Fixed8.Zero))
         {
             engine.LoadScript(verification);
             engine.LoadScript(verifiable.Witnesses[i].InvocationScript);
             engine.Execute();
             if (engine.State.HasFlag(VMState.FAULT))
             {
                 return(false);
             }
             if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean())
             {
                 return(false);
             }
         }
     }
     return(true);
 }
Пример #4
0
        public static ApplicationEngine Run(byte[] script, IScriptContainer container = null)
        {
            DataCache <UInt160, AccountState>   accounts   = blockchain.GetTable <UInt160, AccountState>();
            DataCache <ECPoint, ValidatorState> validators = blockchain.GetTable <ECPoint, ValidatorState>();
            DataCache <UInt256, AssetState>     assets     = blockchain.GetTable <UInt256, AssetState>();
            DataCache <UInt160, ContractState>  contracts  = blockchain.GetTable <UInt160, ContractState>();
            DataCache <StorageKey, StorageItem> storages   = blockchain.GetTable <StorageKey, StorageItem>();
            CachedScriptTable script_table = new CachedScriptTable(contracts);
            StateMachine      service      = new StateMachine(accounts, validators, assets, contracts, storages);
            ApplicationEngine engine       = new ApplicationEngine(TriggerType.Application, container, script_table, service, Fixed8.Zero, true);

            engine.LoadScript(script, false);
            return(engine.Execute() ? engine : null);
        }
Пример #5
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);
        }
Пример #6
0
        public static ApplicationEngine Run(byte[] script, UInt256 ChainHash, IScriptContainer container = null, Block persisting_block = null)
        {
            BlockchainBase Chain = BlockchainBase.GetBlockchain(ChainHash);

            if (persisting_block == null)
            {
                persisting_block = new Block(ChainHash)
                {
                    Version       = 0,
                    PrevHash      = Chain.CurrentBlockHash,
                    MerkleRoot    = new UInt256(),
                    Timestamp     = Chain.GetHeader(Chain.Height).Timestamp + Chain.SecondsPerBlock,
                    Index         = Chain.Height + 1,
                    ConsensusData = 0,
                    NextConsensus = Chain.GetHeader(Chain.Height).NextConsensus,
                    Script        = new Witness
                    {
                        InvocationScript   = new byte[0],
                        VerificationScript = new byte[0]
                    },
                    Transactions = new Transaction[0]
                }
            }
            ;
            DataCache <UInt160, AccountState>   accounts  = Chain.GetStates <UInt160, AccountState>();
            DataCache <UInt256, AssetState>     assets    = Chain.GetStates <UInt256, AssetState>();
            DataCache <UInt160, ContractState>  contracts = Chain.GetStates <UInt160, ContractState>();
            DataCache <StorageKey, StorageItem> storages  = Chain.GetStates <StorageKey, StorageItem>();
            CachedScriptTable script_table = new CachedScriptTable(contracts);

            using (StateMachine service = new StateMachine(persisting_block, accounts, assets, contracts, storages))
            {
                ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, container, script_table, service, Fixed8.Zero, true);
                engine.LoadScript(script, false);
                engine.Execute();
                return(engine);
            }
        }
    }
Пример #7
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);
        }
Пример #8
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);
        }
Пример #9
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);
        }
Пример #10
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);
        }
Пример #11
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);
        }