/// <summary>
        /// Removes top three stack items and converts them to <see cref="long"/>s: value, Min, Max.
        /// Pushes 1 if value was in range, otherwise 0.
        /// Return value indicates success.
        /// </summary>
        /// <param name="opData">Data to use</param>
        /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure)</param>
        /// <returns>True if operation was successful, false if otherwise</returns>
        public override bool Run(IOpData opData, out string error)
        {
            if (opData.ItemCount < 3)
            {
                error = "Invalid number of elements in stack.";
                return(false);
            }

            // Stack is: x then min then max so we pop max first
            if (!OpHelper.TryConvertByteArrayToInt(opData.Pop(), out long max, true))
            {
                error = "Couldn't convert to number.";
                return(false);
            }
            if (!OpHelper.TryConvertByteArrayToInt(opData.Pop(), out long min, true))
            {
                error = "Couldn't convert to number.";
                return(false);
            }
            if (!OpHelper.TryConvertByteArrayToInt(opData.Pop(), out long x, true))
            {
                error = "Couldn't convert to number.";
                return(false);
            }

            int c = (x >= min && x < max) ? 1 : 0;

            opData.Push(OpHelper.IntToByteArray(c));

            error = null;
            return(true);
        }
        protected bool TrySetLockTime(IOpData opData, out string error)
        {
            if (opData.ItemCount < 1)
            {
                error = "Not enough items left in the stack.";
                return(false);
            }

            // The two locktime OPs (CheckLocktimeVerify and CheckSequenceVerify) used to be NOPs. NOPs don't do anything.
            // For backward compatibility of the softfork, Run Peeks at the top item of the stack instead of Poping it.
            byte[] data = opData.Peek();

            // TODO: move this check to OpHelper
            // (for locktimes max length is 5 for others it is 4)
            if (data.Length > 5)
            {
                error = "Data length for locktimes can not be bigger than 5.";
                return(false);
            }

            if (!OpHelper.TryConvertByteArrayToInt(data, out lt, true))
            {
                error = "Invalid number format.";
                return(false);
            }

            if (lt < 0)
            {
                error = "Locktime can not be negative.";
                return(false);
            }

            error = null;
            return(true);
        }
        protected bool TrySetValue(IOpData opData, out string error)
        {
            if (opData.ItemCount < 1)
            {
                error = "Not enough items left in the stack.";
                return(false);
            }

            if (!OpHelper.TryConvertByteArrayToInt(opData.Pop(), out a, true))
            {
                error = "Invalid number format.";
                return(false);
            }

            error = null;
            return(true);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Copies the nth item from top of the stack to the top. Return value indicates success.
        /// </summary>
        /// <param name="opData">Data to use</param>
        /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure)</param>
        /// <returns>True if operation was successful, false if otherwise</returns>
        public override bool Run(IOpData opData, out string error)
        {
            if (opData.ItemCount < 2) // At least 2 items is needed. 1 telling us the index and the other to copy
            {
                error = "There was not enough items left in the stack to copy to top.";
                return(false);
            }

            byte[] data = opData.Pop();
            if (data.Length > 4) // Initial test to reject any huge numbers
            {
                error = "'n' is too big.";
                return(false);
            }

            if (!OpHelper.TryConvertByteArrayToInt(data, out long n, true)) // TODO: set isStrict field base don BIP62
            {
                error = "Invalid number format.";
                return(false);
            }

            if (n < 0)
            {
                error = "'n' can not be negative.";
                return(false);
            }
            if (opData.ItemCount <= n) // 'n' is index so it can't be equal to ItemCount
            {
                error = "There was not enough items left in the stack to copy to top.";
                return(false);
            }

            opData.Push(opData.PeekAtIndex((int)n));

            error = null;
            return(true);
        }