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