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); }
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); }
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); }
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); }
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); }