refactor num to underlying

This commit is contained in:
Tom McCabe 2016-07-05 13:02:18 -05:00
parent fa80a1096e
commit 0947484e03
12 changed files with 100 additions and 75 deletions

View File

@ -15,6 +15,7 @@ import scala.util.{Failure, Success, Try}
sealed trait Number extends NetworkElement with BitcoinSLogger {
type A
def underlying : A
def toInt : Int
}
/**
@ -79,6 +80,12 @@ sealed trait UInt32 extends UnsignedNumber with NumberOperations[UInt32] {
override def hex = BitcoinSUtil.encodeHex(underlying).slice(8,16)
override def toInt = {
if (underlying > Int.MaxValue) throw new IllegalArgumentException("Overflow error when casting " + this +
" to an integer.")
else underlying.toInt
}
/**
* Checks the result of the arithmetic operation to see if an error occurred
* if an error does occur throw it, else return the [[UInt32]]
@ -124,6 +131,12 @@ sealed trait UInt64 extends UnsignedNumber with NumberOperations[UInt64] {
override def <= (num : UInt64): Boolean = underlying <= num.underlying
override def toInt = {
if (underlying > Int.MaxValue) throw new IllegalArgumentException("Overflow error when casting " + this +
" to an integer.")
else underlying.toInt
}
/**
* Checks the result of the arithmetic operation to see if an error occurred
* if an error does occur throw it, else return the [[UInt64]]
@ -185,6 +198,12 @@ sealed trait Int32 extends SignedNumber with NumberOperations[Int32] {
override def <= (num : Int32): Boolean = underlying <= num.underlying
override def toInt = {
if (underlying > Int.MaxValue) throw new IllegalArgumentException("Overflow error when casting " + this +
" to an integer.")
else underlying.toInt
}
/**
* Checks the result of the arithmetic operation to see if an error occurred
* if an error does occur throw it, else return the [[Int32]]
@ -227,6 +246,12 @@ sealed trait Int64 extends SignedNumber with NumberOperations[Int64] {
override def <= (num : Int64): Boolean = underlying <= num.underlying
override def toInt = {
if (underlying > Int.MaxValue) throw new IllegalArgumentException("Overflow error when casting " + this +
" to an integer.")
else underlying.toInt
}
/**
* Checks the result of the arithmetic operation to see if an error occurred
* if an error does occur throw it, else return the [[Int64]]

View File

@ -73,7 +73,7 @@ trait MultiSignatureScriptPubKey extends ScriptPubKey {
//magic number 2 represents the maxSig operation and the OP_CHECKMULTISIG operation at the end of the asm
val numSigsRequired = asmWithoutPushOps(opCheckMultiSigIndex - maxSigs.toInt - 2)
numSigsRequired match {
case x : ScriptNumber => x.num
case x : ScriptNumber => x.underlying
case _ => throw new RuntimeException("The first element of the multisignature pubkey must be a script number operation\n" +
"operation: " + numSigsRequired +
"\nscriptPubKey: " + this)
@ -91,7 +91,7 @@ trait MultiSignatureScriptPubKey extends ScriptPubKey {
0.toLong
} else {
asm(checkMultiSigIndex - 1) match {
case x : ScriptNumber => x.num
case x : ScriptNumber => x.underlying
case _ => throw new RuntimeException("The element preceding a OP_CHECKMULTISIG operation in a multisignature pubkey must be a script number operation")
}
}

View File

@ -70,7 +70,7 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter {
require(program.script.headOption.isDefined && program.script.head == OP_ABS, "Script top must be OP_ABS")
performUnaryArithmeticOperation(program, x => x match {
case ScriptNumber.zero => ScriptNumber.zero
case _ : ScriptNumber => ScriptNumber(x.num.abs)
case _ : ScriptNumber => ScriptNumber(x.underlying.abs)
})
}
@ -105,7 +105,7 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter {
*/
def op0NotEqual(program : ScriptProgram) : ScriptProgram = {
require(program.script.headOption.isDefined && program.script.head == OP_0NOTEQUAL, "Script top must be OP_0NOTEQUAL")
performUnaryArithmeticOperation(program, x => if(x.num == 0) OP_FALSE else OP_TRUE)
performUnaryArithmeticOperation(program, x => if(x.underlying == 0) OP_FALSE else OP_TRUE)
}
@ -187,7 +187,7 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter {
require(program.script.headOption.isDefined && program.script.head == OP_NUMNOTEQUAL,
"Script top must be OP_NUMNOTEQUAL")
performBinaryBooleanOperation(program, (x,y) => {
x.num != y.num
x.underlying != y.underlying
})
}

View File

@ -29,13 +29,13 @@ trait BitwiseInterpreter extends ControlOperationsInterpreter {
val h1 = program.stack.tail.head
val result = (h,h1) match {
case (OP_0,ScriptNumber.zero) | (ScriptNumber.zero, OP_0) =>
OP_0.num == ScriptNumber.zero.num
OP_0.underlying == ScriptNumber.zero.underlying
case (OP_FALSE,ScriptNumber.zero) | (ScriptNumber.zero, OP_FALSE) =>
OP_FALSE.num == ScriptNumber.zero.num
OP_FALSE.underlying == ScriptNumber.zero.underlying
case (OP_TRUE,ScriptNumber.one) | (ScriptNumber.one, OP_TRUE) =>
OP_TRUE.num == ScriptNumber.one.num
OP_TRUE.underlying == ScriptNumber.one.underlying
case (OP_1, ScriptNumber.one) | (ScriptNumber.one, OP_1) =>
OP_1.num == ScriptNumber.one.num
OP_1.underlying == ScriptNumber.one.underlying
case _ => h.bytes == h1.bytes
}
val scriptBoolean = if (result) OP_TRUE else OP_FALSE

View File

@ -159,7 +159,7 @@ trait ConstantInterpreter extends BitcoinSLogger {
*/
private def bytesNeededForPushOp(token : ScriptToken) : Long = token match {
case scriptNumber: BytesToPushOntoStack => scriptNumber.opCode
case scriptNumber: ScriptNumber => scriptNumber.num
case scriptNumber: ScriptNumber => scriptNumber.underlying
case scriptConstant : ScriptConstant =>
val constantFlippedEndianess = BitcoinSUtil.flipEndianess(scriptConstant.hex)
java.lang.Long.parseLong(constantFlippedEndianess,16)

View File

@ -64,22 +64,22 @@ sealed trait ScriptNumber extends ScriptConstant {
* The underlying number of the ScriptNumber
* @return
*/
def num : Long
def underlying : Long
def + (that : ScriptNumber) : ScriptNumber = ScriptNumber(num + that.num)
def + (that : ScriptNumber) : ScriptNumber = ScriptNumber(underlying + that.underlying)
def - = ScriptNumber(-num)
def - (that : ScriptNumber) : ScriptNumber = ScriptNumber(num - that.num)
def * (that : ScriptNumber) : ScriptNumber = ScriptNumber(num * that.num)
def - = ScriptNumber(-underlying)
def - (that : ScriptNumber) : ScriptNumber = ScriptNumber(underlying - that.underlying)
def * (that : ScriptNumber) : ScriptNumber = ScriptNumber(underlying * that.underlying)
def < (that : ScriptNumber) : Boolean = num < that.num
def <= (that : ScriptNumber) : Boolean = num <= that.num
def > (that : ScriptNumber) : Boolean = num > that.num
def >= (that : ScriptNumber) : Boolean = num >= that.num
def < (that : ScriptNumber) : Boolean = underlying < that.underlying
def <= (that : ScriptNumber) : Boolean = underlying <= that.underlying
def > (that : ScriptNumber) : Boolean = underlying > that.underlying
def >= (that : ScriptNumber) : Boolean = underlying >= that.underlying
def &(that : ScriptNumber) : ScriptNumber = ScriptNumber(num & that.num)
def &(that : ScriptNumber) : ScriptNumber = ScriptNumber(underlying & that.underlying)
def | (that : ScriptNumber) : ScriptNumber = ScriptNumber(num | that.num)
def | (that : ScriptNumber) : ScriptNumber = ScriptNumber(underlying | that.underlying)
/**
* This equality just checks that the underlying scala numbers are equivalent, NOT if the numbers
@ -88,9 +88,9 @@ sealed trait ScriptNumber extends ScriptConstant {
* @param that
* @return
*/
def numEqual(that : ScriptNumber) : Boolean = num == that.num
def numEqual(that : ScriptNumber) : Boolean = underlying == that.underlying
override def toLong = num match {
override def toLong = underlying match {
case 0 => 0L
case _ : Long => super.toLong
}
@ -104,11 +104,11 @@ object ScriptNumber extends Factory[ScriptNumber] {
/**
* This represents a script number inside of bitcoin
*
* @param num the number being represented
* @param underlying the number being represented
* @param hex the hex representation of the number - this can be different than the obvious value for
* the number. For instance we could have padded the number with another word of zeros
*/
private case class ScriptNumberImpl(num : Long, override val hex : String) extends ScriptNumber
private case class ScriptNumberImpl(underlying : Long, override val hex : String) extends ScriptNumber
/**
* Represents the number zero inside of bitcoin's script language
@ -138,8 +138,8 @@ object ScriptNumber extends Factory[ScriptNumber] {
else ScriptNumberImpl(ScriptNumberUtil.toLong(bytes), BitcoinSUtil.encodeHex(bytes))
}
def apply(num : Long) : ScriptNumber = {
if (num == 0) zero else apply(ScriptNumberUtil.longToHex(num))
def apply(underlying : Long) : ScriptNumber = {
if (underlying == 0) zero else apply(ScriptNumberUtil.longToHex(underlying))
}
def apply(hex : String, requireMinimal : Boolean) : Try[ScriptNumber] = {
@ -160,7 +160,7 @@ object ScriptNumber extends Factory[ScriptNumber] {
* ScriptNumberImpl case class
*/
private object ScriptNumberImpl {
def apply(num : Long) : ScriptNumber = ScriptNumberImpl(num, ScriptNumberUtil.longToHex(num))
def apply(underlying : Long) : ScriptNumber = ScriptNumberImpl(underlying, ScriptNumberUtil.longToHex(underlying))
def apply(hex : String) : ScriptNumber = ScriptNumberImpl(ScriptNumberUtil.toLong(hex), hex)
def apply(bytes : Seq[Byte]) : ScriptNumber = ScriptNumberImpl(ScriptNumberUtil.toLong(bytes))
}
@ -226,7 +226,7 @@ sealed trait ScriptNumberOperation extends ScriptNumber with ScriptOperation {
case object OP_0 extends ScriptNumberOperation {
override def opCode = 0
override def hex = "00"
override def num = 0
override def underlying = 0
}
/**
* An empty array of bytes is pushed onto the stack. (This is not a no-op: an item is added to the stack.)
@ -234,7 +234,7 @@ case object OP_0 extends ScriptNumberOperation {
case object OP_FALSE extends ScriptNumberOperation {
override def opCode = OP_0.opCode
override def hex = OP_0.hex
override def num = OP_0.num
override def underlying = OP_0.underlying
override def bytes = OP_0.bytes
}
@ -243,7 +243,7 @@ case object OP_FALSE extends ScriptNumberOperation {
*/
case object OP_TRUE extends ScriptNumberOperation {
override def opCode = 81
override def num = 1
override def underlying = 1
}
/**
@ -251,7 +251,7 @@ case object OP_TRUE extends ScriptNumberOperation {
*/
case object OP_1NEGATE extends ScriptNumberOperation {
override def opCode = 79
override def num = -1
override def underlying = -1
}
@ -260,7 +260,7 @@ case object OP_1NEGATE extends ScriptNumberOperation {
*/
case object OP_1 extends ScriptNumberOperation {
override def opCode = OP_TRUE.opCode
override def num = OP_TRUE.num
override def underlying = OP_TRUE.underlying
}
/**
@ -268,7 +268,7 @@ case object OP_1 extends ScriptNumberOperation {
*/
case object OP_2 extends ScriptNumberOperation {
override def opCode = 82
override def num = 2
override def underlying = 2
}
/**
@ -276,7 +276,7 @@ case object OP_2 extends ScriptNumberOperation {
*/
case object OP_3 extends ScriptNumberOperation {
override def opCode = 83
override def num = 3
override def underlying = 3
}
/**
@ -284,7 +284,7 @@ case object OP_3 extends ScriptNumberOperation {
*/
case object OP_4 extends ScriptNumberOperation {
override def opCode = 84
override def num = 4
override def underlying = 4
}
/**
@ -292,7 +292,7 @@ case object OP_4 extends ScriptNumberOperation {
*/
case object OP_5 extends ScriptNumberOperation {
override def opCode = 85
override def num = 5
override def underlying = 5
}
/**
@ -300,7 +300,7 @@ case object OP_5 extends ScriptNumberOperation {
*/
case object OP_6 extends ScriptNumberOperation {
override def opCode = 86
override def num = 6
override def underlying = 6
}
/**
@ -308,7 +308,7 @@ case object OP_6 extends ScriptNumberOperation {
*/
case object OP_7 extends ScriptNumberOperation {
override def opCode = 87
override def num = 7
override def underlying = 7
}
/**
@ -316,7 +316,7 @@ case object OP_7 extends ScriptNumberOperation {
*/
case object OP_8 extends ScriptNumberOperation {
override def opCode = 88
override def num = 8
override def underlying = 8
}
/**
@ -324,7 +324,7 @@ case object OP_8 extends ScriptNumberOperation {
*/
case object OP_9 extends ScriptNumberOperation {
override def opCode = 89
override def num = 9
override def underlying = 9
}
/**
@ -332,7 +332,7 @@ case object OP_9 extends ScriptNumberOperation {
*/
case object OP_10 extends ScriptNumberOperation {
override def opCode = 90
override def num = 10
override def underlying = 10
}
/**
@ -340,7 +340,7 @@ case object OP_10 extends ScriptNumberOperation {
*/
case object OP_11 extends ScriptNumberOperation {
override def opCode = 91
override def num = 11
override def underlying = 11
}
/**
@ -348,7 +348,7 @@ case object OP_11 extends ScriptNumberOperation {
*/
case object OP_12 extends ScriptNumberOperation {
override def opCode = 92
override def num = 12
override def underlying = 12
}
/**
@ -356,7 +356,7 @@ case object OP_12 extends ScriptNumberOperation {
*/
case object OP_13 extends ScriptNumberOperation {
override def opCode = 93
override def num = 13
override def underlying = 13
}
/**
@ -364,7 +364,7 @@ case object OP_13 extends ScriptNumberOperation {
*/
case object OP_14 extends ScriptNumberOperation {
override def opCode = 94
override def num = 14
override def underlying = 14
}
/**
@ -372,7 +372,7 @@ case object OP_14 extends ScriptNumberOperation {
*/
case object OP_15 extends ScriptNumberOperation {
override def opCode = 95
override def num = 15
override def underlying = 15
}
/**
@ -380,7 +380,7 @@ case object OP_15 extends ScriptNumberOperation {
*/
case object OP_16 extends ScriptNumberOperation {
override def opCode = 96
override def num = 16
override def underlying = 16
}
@ -391,10 +391,10 @@ object ScriptNumberOperation extends ScriptOperationFactory[ScriptNumberOperatio
/**
* Finds the script number operation based on the given integer
*
* @param num
* @param underlying
* @return
*/
def fromNumber(num : Int) : Option[ScriptNumberOperation] = operations.find(_.num == num)
def fromNumber(underlying : Int) : Option[ScriptNumberOperation] = operations.find(_.underlying == underlying)
}

View File

@ -226,8 +226,8 @@ trait CryptoInterpreter extends ControlOperationsInterpreter with BitcoinSLogger
}
logger.debug("nPossibleSignatures: " + nPossibleSignatures)
val (pubKeysScriptTokens, stackWithoutPubKeys) =
(program.stack.tail.slice(0, nPossibleSignatures.num.toInt),
program.stack.tail.slice(nPossibleSignatures.num.toInt, program.stack.tail.size))
(program.stack.tail.slice(0, nPossibleSignatures.underlying.toInt),
program.stack.tail.slice(nPossibleSignatures.underlying.toInt, program.stack.tail.size))
val pubKeys = pubKeysScriptTokens.map(key => ECPublicKey(key.bytes))
logger.debug("Public keys on the stack: " + pubKeys)
@ -235,13 +235,13 @@ trait CryptoInterpreter extends ControlOperationsInterpreter with BitcoinSLogger
logger.debug("mRequiredSignatures: " + mRequiredSignatures)
//+1 is for the fact that we have the # of sigs + the script token indicating the # of sigs
val signaturesScriptTokens = program.stack.tail.slice(nPossibleSignatures.num.toInt + 1,
nPossibleSignatures.num.toInt + mRequiredSignatures.num.toInt + 1)
val signaturesScriptTokens = program.stack.tail.slice(nPossibleSignatures.underlying.toInt + 1,
nPossibleSignatures.underlying.toInt + mRequiredSignatures.underlying.toInt + 1)
val signatures = signaturesScriptTokens.map(token => ECDigitalSignature(token.bytes))
logger.debug("Signatures on the stack: " + signatures)
//this contains the extra Script OP that is required for OP_CHECKMULTISIG
val stackWithoutPubKeysAndSignatures = stackWithoutPubKeys.tail.slice(mRequiredSignatures.num.toInt, stackWithoutPubKeys.tail.size)
val stackWithoutPubKeysAndSignatures = stackWithoutPubKeys.tail.slice(mRequiredSignatures.underlying.toInt, stackWithoutPubKeys.tail.size)
logger.debug("stackWithoutPubKeysAndSignatures: " + stackWithoutPubKeysAndSignatures)
if (pubKeys.size > ScriptSettings.maxPublicKeysPerMultiSig) {
logger.error("We have more public keys than the maximum amount of public keys allowed")
@ -265,7 +265,7 @@ trait CryptoInterpreter extends ControlOperationsInterpreter with BitcoinSLogger
val isValidSignatures: TransactionSignatureCheckerResult =
TransactionSignatureChecker.multiSignatureEvaluator(executionInProgressScriptProgram.txSignatureComponent,
removedOpCodeSeparatorsScript, signatures,
pubKeys, program.flags, mRequiredSignatures.num)
pubKeys, program.flags, mRequiredSignatures.underlying)
//remove the extra op for OP_CHECKMULTISIG from the stack
val restOfStack = stackWithoutPubKeysAndSignatures.tail

View File

@ -259,7 +259,7 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
case OP_0 :: t => loop(ScriptProgram(p, ScriptNumber.zero :: p.stack, t))
case (scriptNumberOp : ScriptNumberOperation) :: t =>
loop(ScriptProgram(p, ScriptNumber(scriptNumberOp.num) :: p.stack, t))
loop(ScriptProgram(p, ScriptNumber(scriptNumberOp.underlying) :: p.stack, t))
case (bytesToPushOntoStack: BytesToPushOntoStack) :: t =>
loop(pushScriptNumberBytesToStack(p))
case (scriptNumber: ScriptNumber) :: t =>
@ -294,10 +294,10 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
//script was marked invalid for other reasons, don't need to update the opcount
loop(newProgram)
case newProgram : ExecutionInProgressScriptProgram =>
opCount = opCount + BitcoinScriptUtil.numPossibleSignaturesOnStack(program).num.toInt
opCount = opCount + BitcoinScriptUtil.numPossibleSignaturesOnStack(program).underlying.toInt
loop(newProgram)
case newProgram : PreExecutionScriptProgram =>
opCount = opCount + BitcoinScriptUtil.numPossibleSignaturesOnStack(program).num.toInt
opCount = opCount + BitcoinScriptUtil.numPossibleSignaturesOnStack(program).underlying.toInt
loop(newProgram)
}
@ -307,10 +307,10 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
//script was marked invalid for other reasons, don't need to update the opcount
loop(newProgram)
case newProgram : ExecutionInProgressScriptProgram =>
opCount = opCount + BitcoinScriptUtil.numPossibleSignaturesOnStack(program).num.toInt
opCount = opCount + BitcoinScriptUtil.numPossibleSignaturesOnStack(program).underlying.toInt
loop(newProgram)
case newProgram : PreExecutionScriptProgram =>
opCount = opCount + BitcoinScriptUtil.numPossibleSignaturesOnStack(program).num.toInt
opCount = opCount + BitcoinScriptUtil.numPossibleSignaturesOnStack(program).underlying.toInt
loop(newProgram)
}
//reserved operations

View File

@ -160,9 +160,9 @@ trait LockTimeInterpreter extends BitcoinSLogger {
// the nSequenceMasked in the transaction.
if (!(
(txToSequenceMasked.underlying < TransactionConstants.sequenceLockTimeTypeFlag &&
nSequenceMasked.num < TransactionConstants.sequenceLockTimeTypeFlag) ||
nSequenceMasked.underlying < TransactionConstants.sequenceLockTimeTypeFlag) ||
(txToSequenceMasked.underlying >= TransactionConstants.sequenceLockTimeTypeFlag &&
nSequenceMasked.num >= TransactionConstants.sequenceLockTimeTypeFlag)
nSequenceMasked.underlying >= TransactionConstants.sequenceLockTimeTypeFlag)
)) {
logger.error("The nSequence mask is not the same as it was in the transaction")
return false
@ -170,7 +170,7 @@ trait LockTimeInterpreter extends BitcoinSLogger {
// Now that we know we're comparing apples-to-apples, the
// comparison is a simple numeric one.
if (nSequenceMasked.num > txToSequenceMasked.underlying) {
if (nSequenceMasked.underlying > txToSequenceMasked.underlying) {
logger.error("OP_CSV fails because locktime in transaction has not been met yet")
return false
}
@ -197,13 +197,13 @@ trait LockTimeInterpreter extends BitcoinSLogger {
val transaction = program.txSignatureComponent.transaction
val input = transaction.inputs(program.txSignatureComponent.inputIndex.underlying.toInt)
if (!(
(transaction.lockTime < TransactionConstants.locktimeThreshold && UInt32(locktime.num) < TransactionConstants.locktimeThreshold) ||
(transaction.lockTime >= TransactionConstants.locktimeThreshold && UInt32(locktime.num) >= TransactionConstants.locktimeThreshold)
(transaction.lockTime < TransactionConstants.locktimeThreshold && UInt32(locktime.underlying) < TransactionConstants.locktimeThreshold) ||
(transaction.lockTime >= TransactionConstants.locktimeThreshold && UInt32(locktime.underlying) >= TransactionConstants.locktimeThreshold)
)) return false
// Now that we know we're comparing apples-to-apples, the
// comparison is a simple numeric one.
if (locktime.num > Int64(transaction.lockTime.underlying).underlying) return false
if (locktime.underlying > Int64(transaction.lockTime.underlying).underlying) return false
// Finally the nLockTime feature can be disabled and thus
// CHECKLOCKTIMEVERIFY bypassed if every txin has been
@ -226,5 +226,5 @@ trait LockTimeInterpreter extends BitcoinSLogger {
* @param s
* @return
*/
def isLockTimeBitOff(s : ScriptNumber) : Boolean = (s.num & TransactionConstants.locktimeDisabledFlag) == 0
def isLockTimeBitOff(s : ScriptNumber) : Boolean = (s.underlying & TransactionConstants.locktimeDisabledFlag) == 0
}

View File

@ -170,9 +170,9 @@ trait StackInterpreter extends BitcoinSLogger {
executeOpWithStackTopAsNumberArg(program, { number : ScriptNumber =>
logger.info("Script number for OP_PICK: " + number)
//check if n is within the bound of the script
(number.num >= 0 && number.num < program.stack.tail.size) match {
(number.underlying >= 0 && number.underlying < program.stack.tail.size) match {
case true =>
val newStackTop = program.stack.tail(number.num.toInt)
val newStackTop = program.stack.tail(number.underlying.toInt)
ScriptProgram(program, newStackTop :: program.stack.tail, program.script.tail)
case false =>
logger.error("The index for OP_PICK would have caused an index out of bounds exception")
@ -191,9 +191,9 @@ trait StackInterpreter extends BitcoinSLogger {
require(program.script.headOption.isDefined && program.script.head == OP_ROLL, "Top of script stack must be OP_ROLL")
require(program.stack.size > 0,"Stack must have at least one items on it for OP_ROLL")
executeOpWithStackTopAsNumberArg(program, (number : ScriptNumber) =>
(number.num >= 0 && number.num < program.stack.tail.size) match {
(number.underlying >= 0 && number.underlying < program.stack.tail.size) match {
case true =>
val newStackTop = program.stack.tail(number.num.toInt)
val newStackTop = program.stack.tail(number.underlying.toInt)
//removes the old instance of the stack top, appends the new index to the head
val newStack = newStackTop :: program.stack.tail.diff(List(newStackTop))
ScriptProgram(program,newStack,program.script.tail)

View File

@ -76,7 +76,7 @@ trait BitcoinScriptUtil {
val multiSigCount : Long = script.zipWithIndex.map { case (token, index) =>
if (multiSigOps.contains(token) && index != 0) {
script(index-1) match {
case scriptNum : ScriptNumber => scriptNum.num
case scriptNum : ScriptNumber => scriptNum.underlying
case scriptConstant : ScriptConstant => ScriptNumberUtil.toLong(scriptConstant.hex)
case _ : ScriptToken => ScriptSettings.maxPublicKeysPerMultiSig
}
@ -117,7 +117,7 @@ trait BitcoinScriptUtil {
require(program.script.headOption == Some(OP_CHECKMULTISIG) || program.script.headOption == Some(OP_CHECKMULTISIGVERIFY),
"We can only parse the nubmer of signatures the stack when we are executing a OP_CHECKMULTISIG or OP_CHECKMULTISIGVERIFY op")
val nPossibleSignatures = numPossibleSignaturesOnStack(program)
val stackWithoutPubKeys = program.stack.tail.slice(nPossibleSignatures.num.toInt,program.stack.tail.size)
val stackWithoutPubKeys = program.stack.tail.slice(nPossibleSignatures.underlying.toInt,program.stack.tail.size)
val mRequiredSignatures : ScriptNumber = stackWithoutPubKeys.head match {
case s: ScriptNumber => s
case s : ScriptConstant => ScriptNumber(s.bytes)

View File

@ -23,7 +23,7 @@ class ScriptNumberFactoryTest extends FlatSpec with MustMatchers {
it must "create a negative number from hex" in {
val hex = "008080"
val number = -32768
ScriptNumber(hex).num must be (number)
ScriptNumber(hex).underlying must be (number)
}
it must "create a negative number from hex and have the same underlying hex representation" in {