mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 02:39:18 +01:00
Implementing OP_PICK script operation
This commit is contained in:
parent
09458675a4
commit
4aeb30ca6d
4 changed files with 63 additions and 5 deletions
|
@ -48,6 +48,8 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
|
|||
case OP_DROP :: t => loop(opDrop(program))
|
||||
case OP_IFDUP :: t => loop(opIfDup(program))
|
||||
case OP_NIP :: t => loop(opNip(program))
|
||||
case OP_OVER :: t => loop(opOver(program))
|
||||
case OP_PICK :: t => loop(opPick(program))
|
||||
//arithmetic operations
|
||||
case OP_ADD :: t => loop(opAdd(program))
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.scalacoin.script.stack
|
|||
|
||||
import org.scalacoin.script.{ScriptProgramImpl, ScriptProgram}
|
||||
import org.scalacoin.script.constant._
|
||||
import org.scalacoin.util.ScalacoinUtil
|
||||
|
||||
/**
|
||||
* Created by chris on 1/6/16.
|
||||
|
@ -99,8 +100,41 @@ trait StackInterpreter {
|
|||
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)
|
||||
case h :: _ :: t => ScriptProgramImpl(h :: t, program.script.tail, program.transaction, program.altStack)
|
||||
case h :: t => throw new RuntimeException("Stack must have at least two items on it for OP_NIP")
|
||||
case Nil => throw new RuntimeException("Stack must have at least two items on it for OP_NIP")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies the second-to-top stack item to the top.
|
||||
* @param program
|
||||
* @return
|
||||
*/
|
||||
def opOver(program : ScriptProgram) : ScriptProgram = {
|
||||
require(program.script.headOption.isDefined && program.script.head == OP_OVER, "Top of script stack must be OP_OVER")
|
||||
require(program.stack.size > 1,"Stack must have at least two items on it for OP_OVER")
|
||||
program.stack match {
|
||||
case _ :: h1 :: _ => ScriptProgramImpl(h1 :: program.stack, program.script.tail, program.transaction, program.altStack)
|
||||
case h :: t => throw new RuntimeException("Stack must have at least two items on it for OP_OVER")
|
||||
case Nil => throw new RuntimeException("Stack must have at least two items on it for OP_OVER")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The item n back in the stack is copied to the top.
|
||||
* @param program
|
||||
* @return
|
||||
*/
|
||||
def opPick(program : ScriptProgram) : ScriptProgram = {
|
||||
require(program.script.headOption.isDefined && program.script.head == OP_PICK, "Top of script stack must be OP_PICK")
|
||||
require(program.stack.size > 1,"Stack must have at least two items on it for OP_PICK")
|
||||
|
||||
val n = ScalacoinUtil.hexToInt(program.stack.head.hex)
|
||||
val newStackTop = program.stack.tail(n)
|
||||
ScriptProgramImpl(newStackTop :: program.stack.tail, program.script.tail, program.transaction, program.altStack)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.scalacoin.marshallers.script
|
|||
import org.scalacoin.script.arithmetic.OP_ADD
|
||||
import org.scalacoin.script.bitwise.OP_EQUAL
|
||||
import org.scalacoin.script.constant.{ScriptNumberImpl, OP_1, OP_1NEGATE, ScriptConstantImpl}
|
||||
import org.scalacoin.script.stack.OP_PICK
|
||||
import org.scalacoin.util.{ScalacoinUtil, TestUtil}
|
||||
import org.scalatest.{FlatSpec, MustMatchers}
|
||||
|
||||
|
@ -58,10 +59,10 @@ class ScriptParserTest extends FlatSpec with MustMatchers with ScriptParser with
|
|||
parse(str) must equal (List(OP_1NEGATE, ScriptConstantImpl("3e8"), OP_ADD))
|
||||
}
|
||||
|
||||
/* it must "parse a decimal number as a ScriptNumber if it is under 75" in {
|
||||
val str = "ADD 21 EQUAL"
|
||||
parse(str) must equal (List(OP_ADD, ScriptNumberImpl(21), OP_EQUAL))
|
||||
}*/
|
||||
it must "parse an OP_PICK" in {
|
||||
val str = "PICK"
|
||||
parse(str) must equal (List(OP_PICK))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.scalacoin.script.stack
|
||||
|
||||
import org.scalacoin.script.ScriptProgramImpl
|
||||
import org.scalacoin.script.bitwise.OP_EQUAL
|
||||
import org.scalacoin.script.constant.{OP_1, OP_0, ScriptConstantImpl}
|
||||
import org.scalacoin.util.{TestUtil, ScalacoinUtil}
|
||||
import org.scalatest.{FlatSpec, MustMatchers}
|
||||
|
@ -106,6 +107,26 @@ class StackInterpreterTest extends FlatSpec with MustMatchers with StackInterpre
|
|||
|
||||
newProgram.stack must be (List(OP_0))
|
||||
newProgram.script.isEmpty must be (true)
|
||||
}
|
||||
|
||||
it must "evaluate an OP_OVER correctly" in {
|
||||
val stack = List(OP_0,OP_1)
|
||||
val script = List(OP_OVER)
|
||||
val program = ScriptProgramImpl(stack,script,TestUtil.transaction,List())
|
||||
val newProgram = opOver(program)
|
||||
newProgram.stack must be (List(OP_1,OP_0,OP_1))
|
||||
newProgram.script.isEmpty must be (true)
|
||||
}
|
||||
|
||||
it must "evaluate an OP_PICK correctly" in {
|
||||
val stack = List(OP_0, ScriptConstantImpl("14"), ScriptConstantImpl("15"), ScriptConstantImpl("16"))
|
||||
val script = List(OP_PICK)
|
||||
val program = ScriptProgramImpl(stack,script,TestUtil.transaction,List())
|
||||
val newProgram = opPick(program)
|
||||
|
||||
newProgram.stack must be (List(ScriptConstantImpl("14"),ScriptConstantImpl("14"),
|
||||
ScriptConstantImpl("15"), ScriptConstantImpl("16")))
|
||||
newProgram.script.isEmpty must be (true)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue