示例#1
0
        private void OpLeft(ParsedOpCode op)
        {
            var high = MainStack.PopInt32();
            var data = MainStack.Pop();

            if (data.Length == 0 || high == 0)
            {
                MainStack.Push(new byte[0]);
            }
            else if (high < 0)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "upper boundary less than zero");
            }
            else if (high > data.Length)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "upper boundary greater than array length");
            }
            else if (high < 0)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "upper boundary less than zero");
            }
            else
            {
                var bytes = data.Take(high).ToArray();
                MainStack.Push(bytes);
            }
        }
示例#2
0
        private void OpSubStr(ParsedOpCode op)
        {
            var startIndex        = MainStack.PopInt32();
            var endIndexExclusive = MainStack.PopInt32();
            var array             = MainStack.Pop();

            if (array.Length == 0)
            {
                MainStack.Push(new byte[0]);
            }
            else if (startIndex < 0 || endIndexExclusive < 0)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "Negative substring index");
            }
            else if (startIndex > array.Length || endIndexExclusive > array.Length)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "Substring index out of bounds");
            }
            else if (startIndex > endIndexExclusive)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "Start index is greater than end index");
            }
            else if (startIndex == endIndexExclusive)
            {
                MainStack.Push(new byte[0]);
            }
            else
            {
                var substr = array.Skip(startIndex).Take(endIndexExclusive - startIndex).ToArray();
                MainStack.Push(substr);
            }
        }
示例#3
0
        private void OpNumNotEqual(ParsedOpCode obj)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            MainStack.Push(a != b ? 1 : 0);
        }
示例#4
0
 private void OpNop(ParsedOpCode op)
 {
     if (Options.DiscourageUpgradableNops)
     {
         throw new ReservedOpCodeException(op.Code);
     }
 }
示例#5
0
        private void OpEqual(ParsedOpCode op)
        {
            var a = MainStack.Pop();
            var b = MainStack.Pop();

            MainStack.Push(a.SequenceEqual(b));
        }
示例#6
0
        private void OpXor(ParsedOpCode op)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            MainStack.Push(a ^ b);
        }
示例#7
0
        private void OpNumEqual(ParsedOpCode op)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            MainStack.Push(a == b ? 1 : 0);
        }
示例#8
0
        public void OpCheckSig(ParsedOpCode op, MsgTx transaction)
        {
            try
            {
                var rawPublicKey = MainStack.Pop();
                var rawSignature = MainStack.Pop();

                if (rawSignature.Length < 1)
                {
                    MainStack.Push(false);
                    return;
                }

                var signature     = rawSignature.Take(rawSignature.Length - 1).ToArray();
                var signatureType = (SignatureHashType)rawSignature.Last();

                AssertSignatureHashType(signatureType);
                AssertSignatureEncoding(signature);
                AssertPublicKeyEncoding(rawPublicKey);

                var subScript = _script.GetOpCodesWithoutData(rawSignature);
                var hash      = CalculateSignatureHash(subScript, signatureType, (MsgTx)transaction.Clone(), _txIndex);

                var ecSignature      = new ECSignature(signature);
                var securityService  = new ECPublicSecurityService(rawPublicKey);
                var isValidSignature = securityService.VerifySignature(hash, ecSignature);

                MainStack.Push(isValidSignature);
            }
            catch (ScriptException)
            {
                MainStack.Push(false);
            }
        }
示例#9
0
        /// <summary>
        /// Multiplies top two numbers on the stack.
        /// </summary>
        /// <param name="obj"></param>
        private void OpMul(ParsedOpCode obj)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            MainStack.Push(a * b);
        }
示例#10
0
        private void OpLessThan(ParsedOpCode obj)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            MainStack.Push(b < a ? 1 : 0);
        }
示例#11
0
        private void OpGreaterThanOrEqual(ParsedOpCode obj)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            MainStack.Push(b > a ? 1 : 0);
        }
示例#12
0
        private void Execute(ParsedOpCode op)
        {
            if (!_opCodeLookup.TryGetValue(op.Code, out var action))
            {
                throw new ScriptSyntaxErrorException(($"Attempted to execute unknown op code 0x{(byte) op.Code:X}"));
            }

            if (op.Code.IsReserved())
            {
                throw new ReservedOpCodeException(op.Code);
            }

            try
            {
                action(op);
            }
            catch (ScriptException)
            {
                throw;
            }

            catch (Exception ex)
            {
                throw new Exception(
                          "Unexpected error while running script. " +
                          $"OpCode: {op.Code} " +
                          $"Data: '{Hex.ToHexString(op.Data)}'",
                          ex);
            }
        }
示例#13
0
        private void OpHash160(ParsedOpCode obj)
        {
            var value = MainStack.Pop();
            var hash  = HashUtil.Ripemd160(HashUtil.Blake256(value));

            MainStack.Push(hash);
        }
示例#14
0
        public void AddData(byte[] data)
        {
            var opCode       = OpCodeUtil.CanonicalOpCodeForData(data);
            var parsedOpCode = new ParsedOpCode(opCode, data);

            AddOpCode(parsedOpCode);
        }
示例#15
0
        private void OpMax(ParsedOpCode obj)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            MainStack.Push(Math.Max(a, b));
        }
示例#16
0
        private void OpSub(ParsedOpCode obj)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            MainStack.Push(b - a);
        }
示例#17
0
        private void OpBoolOr(ParsedOpCode obj)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            MainStack.Push(a != 0 || b != 0 ? 1 : 0);
        }
示例#18
0
        private void OpWithin(ParsedOpCode obj)
        {
            var max  = MainStack.PopInt32();
            var min  = MainStack.PopInt32();
            var test = MainStack.PopInt32();

            MainStack.Push(min <= test && test < max ? 1 : 0);
        }
示例#19
0
        private void OpCat(ParsedOpCode op)
        {
            var first  = MainStack.Pop();
            var second = MainStack.Pop();

            var bytes = second.Concat(first).ToArray();

            MainStack.Push(bytes);
        }
示例#20
0
        private bool CanExecuteNextOpCode(ParsedOpCode op)
        {
            // Ensure that disabled opcodes are always executed.
            var branchOp = BranchStack.Peek();

            return(branchOp == BranchOption.True ||
                   op.Code.IsConditional() ||
                   op.Code.IsDisabled());
        }
示例#21
0
 private void OpPushData(ParsedOpCode op)
 {
     if (op.Code.IsOpN())
     {
         var value = (op.Code - OpCode.OP_1) + 1;
         MainStack.Push(value);
     }
     else
     {
         MainStack.Push(op.Data);
     }
 }
示例#22
0
        private void OpMod(ParsedOpCode op)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            if (a == 0)
            {
                throw new ArithemeticException(op.Code, "Division by zero");
            }

            MainStack.Push(b % a);
        }
示例#23
0
        private void OpSha256(ParsedOpCode op)
        {
            if (!Options.EnableSha256)
            {
                OpNop(op);
                return;
            }

            var data = MainStack.Pop();
            var hash = HashUtil.Sha256(data);

            MainStack.Push(hash);
        }
示例#24
0
        private void OpRShift(ParsedOpCode op)
        {
            var a = MainStack.PopInt32();
            var b = MainStack.PopInt32();

            if (a < 0)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "Negative shift");
            }
            if (a > 32)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "Shift overflow");
            }

            MainStack.Push(b >> a);
        }
示例#25
0
        private void OpRotl(ParsedOpCode op)
        {
            var rotate = MainStack.PopInt32();
            var value  = MainStack.PopInt32();

            if (rotate < 0)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "attempted to rotate by negative value");
            }
            if (rotate > 31)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "attempted to rotate by value > 31");
            }

            var rotatedValue = (value << rotate) | (value >> (32 - rotate));

            MainStack.Push(rotatedValue);
        }
示例#26
0
        private void OpRight(ParsedOpCode op)
        {
            var index = MainStack.PopInt32();
            var data  = MainStack.Pop();

            if (data.Length == 0 || index == data.Length)
            {
                MainStack.Push(new byte[0]);
            }
            else if (index < 0)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "upper boundary less than zero");
            }
            else if (index > data.Length)
            {
                throw new ScriptIndexOutOfRangeException(op.Code, "upper boundary greater than array length");
            }
            else
            {
                MainStack.Push(data.Skip(index).ToArray());
            }
        }
示例#27
0
 public void AddOpCode(ParsedOpCode opCode)
 {
     _scriptBytes.AddRange(opCode.Serialize());
 }
示例#28
0
 private void OpInvalid(ParsedOpCode op)
 {
     throw new InvalidOpCodeException(op.Code);
 }
示例#29
0
        private void OpHash256(ParsedOpCode obj)
        {
            var value = MainStack.Pop();

            MainStack.Push(HashUtil.Blake256D(value));
        }
示例#30
0
 private void OpCheckSigVerify(ParsedOpCode op, MsgTx transaction)
 {
     OpCheckSig(op, transaction);
     OpVerify();
 }