mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 09:52:09 +01:00
implmenting OP_NIP and OP_IFDUP
This commit is contained in:
parent
1ca36bfb85
commit
09458675a4
@ -46,6 +46,8 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
|
||||
case OP_TOALTSTACK :: t => loop(opToAltStack(program))
|
||||
case OP_FROMALTSTACK :: t => loop(opFromAltStack(program))
|
||||
case OP_DROP :: t => loop(opDrop(program))
|
||||
case OP_IFDUP :: t => loop(opIfDup(program))
|
||||
case OP_NIP :: t => loop(opNip(program))
|
||||
//arithmetic operations
|
||||
case OP_ADD :: t => loop(opAdd(program))
|
||||
|
||||
|
@ -25,6 +25,20 @@ trait StackInterpreter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the top stack value is not 0, duplicate it.
|
||||
* @param program
|
||||
* @return
|
||||
*/
|
||||
def opIfDup(program : ScriptProgram) : ScriptProgram = {
|
||||
require(program.script.headOption.isDefined && program.script.head == OP_IFDUP, "Top of the script stack must be OP_DUP")
|
||||
require(program.stack.headOption.isDefined, "Cannot duplicate the top element on an empty stack")
|
||||
if (program.stack.head == OP_0) {
|
||||
ScriptProgramImpl(program.stack,program.script.tail, program.transaction,program.altStack)
|
||||
} else ScriptProgramImpl(program.stack.head :: program.stack,
|
||||
program.script.tail, program.transaction,program.altStack)
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the number of stack items onto the stack.
|
||||
* @param program
|
||||
@ -75,4 +89,18 @@ trait StackInterpreter {
|
||||
ScriptProgramImpl(program.stack.tail,program.script.tail,program.transaction,program.altStack)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the second-to-top stack item
|
||||
* @param program
|
||||
* @return
|
||||
*/
|
||||
def opNip(program : ScriptProgram) : ScriptProgram = {
|
||||
require(program.script.headOption.isDefined && program.script.head == OP_NIP, "Top of script stack must be OP_NIP")
|
||||
require(program.stack.size > 1,"Stack must have at least two items on it for OP_NIP")
|
||||
program.stack match {
|
||||
case h :: h1 :: t => ScriptProgramImpl(h :: t, program.script.tail, program.transaction, program.altStack)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,13 +54,13 @@ class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterp
|
||||
val source = scala.io.Source.fromFile("src/test/scala/org/scalacoin/script/interpreter/script_valid.json")
|
||||
|
||||
//use this to represent a single test case from script_valid.json
|
||||
val lines =
|
||||
"""
|
||||
|
|
||||
|[["10 0 11 TOALTSTACK DROP FROMALTSTACK", "ADD 21 EQUAL", "P2SH,STRICTENC"]]
|
||||
""".stripMargin
|
||||
/* val lines =
|
||||
"""
|
||||
|
|
||||
|[["10 0 11 TOALTSTACK DROP FROMALTSTACK", "ADD 21 EQUAL", "P2SH,STRICTENC"]]
|
||||
""".stripMargin*/
|
||||
|
||||
//val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
val json = lines.parseJson
|
||||
val testCasesOpt : Seq[Option[CoreTestCase]] = json.convertTo[Seq[Option[CoreTestCase]]]
|
||||
val testCases : Seq[CoreTestCase] = testCasesOpt.flatten
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.scalacoin.script.stack
|
||||
|
||||
import org.scalacoin.script.ScriptProgramImpl
|
||||
import org.scalacoin.script.constant.{OP_0, ScriptConstantImpl}
|
||||
import org.scalacoin.script.constant.{OP_1, OP_0, ScriptConstantImpl}
|
||||
import org.scalacoin.util.{TestUtil, ScalacoinUtil}
|
||||
import org.scalatest.{FlatSpec, MustMatchers}
|
||||
|
||||
@ -78,4 +78,34 @@ class StackInterpreterTest extends FlatSpec with MustMatchers with StackInterpre
|
||||
newProgram.stack.isEmpty must be (true)
|
||||
newProgram.script.isEmpty must be (true)
|
||||
}
|
||||
|
||||
it must "evaluate an OP_IFDUP correctly" in {
|
||||
val stack = List(OP_0)
|
||||
val script = List(OP_IFDUP)
|
||||
val program = ScriptProgramImpl(stack,script,TestUtil.transaction, List())
|
||||
val newProgram = opIfDup(program)
|
||||
|
||||
newProgram.stack must be (stack)
|
||||
newProgram.script.isEmpty must be (true)
|
||||
|
||||
val stack1 = List(OP_1)
|
||||
val program1 = ScriptProgramImpl(stack1,script,TestUtil.transaction,List())
|
||||
val newProgram1 = opIfDup(program1)
|
||||
newProgram1.stack must be (List(OP_1,OP_1))
|
||||
newProgram1.script.isEmpty must be (true)
|
||||
|
||||
}
|
||||
|
||||
it must "evaluate an OP_NIP correctly" in {
|
||||
val stack = List(OP_0,OP_1)
|
||||
val script = List(OP_NIP)
|
||||
|
||||
val program = ScriptProgramImpl(stack,script,TestUtil.transaction,List())
|
||||
|
||||
val newProgram = opNip(program)
|
||||
|
||||
newProgram.stack must be (List(OP_0))
|
||||
newProgram.script.isEmpty must be (true)
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user