定义 仅在表头进行插入和删除操作的线性表 操作 压栈push、出栈pop 特点 后进先出LIFO(Last In First Out)
锁定脚本(ScriptPubKey) DUP HASH160 <公钥哈希> EQUALVERIFY CHECKSIG 解锁脚本(ScriptSig) <签名> <公钥> 验证方式 【解锁脚本+锁定脚本】一起放入栈虚拟机运行 期望结果为“成功”(true)
(点开以下动图详细了解这三个安全特性)
比特币栈虚拟机被故意设计成图灵不完全 故所有验证都可以在可预测的时间内完成 对验证区块有威胁的操作符也被禁止使用
OP_CAT OP_SUBSTR OP_LEFT OP_RIGHT OP_2MUL OP_2DIV OP_MUL OP_DIV OP_MOD OP_LSHIFT OP_RSHIFT
public enum OpCode : byte { Object, CheckSignature, }
public class ScriptToken { public const string TOKEN_PREFIX = "OC_"; public bool IsOpCode { get => this.OpCode != OpCode.Object; } public OpCode OpCode { get; set; } = OpCode.Object; public string Object { get; set; } public ScriptToken(object obj) { if (obj is OpCode opcode) { this.OpCode = opcode; } else if (obj is string str) { if (str.StartsWith(TOKEN_PREFIX)) { this.OpCode = (OpCode)Enum.Parse(typeof(OpCode), str.Remove(0, TOKEN_PREFIX.Length)); } else { this.Object = str; } } else { this.Object = obj.ToString(); } } public string GetValue() public static ScriptToken CreateToken(object obj) public override bool Equals(object obj) public override int GetHashCode() }
public class UnlockScripts : ReadOnlyCollection<ScriptToken> { public UnlockScripts(IList<ScriptToken> list) : base(list) { } }
public class LockScripts : ReadOnlyCollection<ScriptToken> { public LockScripts(IList<ScriptToken> list) : base(list) { } }
public class WholeScripts : ReadOnlyCollection<ScriptToken> { public WholeScripts(IList<ScriptToken> list) : base(list) { } }
public static WholeScripts operator +(UnlockScripts us, LockScripts ls) => new WholeScripts(us.Concat(ls).ToList());
public static T Evaluate<T>(ScriptToken[] tokens, Transaction transaction, ISignAlgorithm algorithm) { var ret = Evaluate(tokens, transaction, algorithm); if (typeof(T) == typeof(Boolean)) { var s = ret.ToString().ToLower(); return (T)(object)(s == "true"); } return (T)Convert.ChangeType(ret, typeof(T)); }
public static object Evaluate(ScriptToken[] tokens, Transaction transaction, ISignAlgorithm algorithm) { var stack = new Stack<ScriptToken>(); foreach (var token in tokens) { if (!token.IsOpCode) { stack.Push(token); continue; } switch (token.OpCode) { case OpCode.CheckSignature: { if (!stack.CanPop()) return false; var pubKey = PublicKey.ParseBase58(stack.Pop().GetValue()); if (!stack.CanPop()) return false; var sig = Signature.ParseBase58(stack.Pop().GetValue()); var ret = algorithm.Verify(new[] { (byte[])transaction.GetLockHash() }, pubKey, sig); stack.Push(ScriptToken.CreateToken(ret)); break; } default: break; } } if (!stack.CanPop()) return false; return stack.Pop().GetValue(); }
public static bool TryExecuteAsync(this WholeScripts scripts, Transaction trans, ISignAlgorithm signAlgorithm = null) { signAlgorithm = signAlgorithm ?? new ECDsaSignAlgorithm(); var eval = Evaluator.Evaluate<bool>(scripts, trans, signAlgorithm); return eval; }
public static bool CanPop(this Stack<ScriptToken> stack) { return stack.Count > 0; }
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8