Implementing OP_HASH160, OP_DUP and adding in some util functions

This commit is contained in:
Chris Stewart 2016-01-06 15:01:42 -06:00
parent 190992ee3b
commit a062ac8e14
5 changed files with 123 additions and 0 deletions

View file

@ -0,0 +1,33 @@
package org.scalacoin.script.crypto
import org.scalacoin.script.ScriptOperation
import org.scalacoin.util.ScalacoinUtil
/**
* Created by chris on 1/6/16.
*/
trait CryptoInterpreter extends ScalacoinUtil {
def hash160(stack : List[String], script : List[ScriptOperation]) : (List[String], List[ScriptOperation]) = {
require(stack.headOption.isDefined, "The top of the stack must be defined")
require(script.headOption.isDefined && script.head == OP_HASH160, "Script operation must be OP_HASH160")
val stackTop = stack.head
val hash = sha256Hash160(stackTop)
(hash :: stack, script.tail)
}
/**
* Does the following computation
* RIPEMD160(SHA256(hex))
* @param hex
* @return
*/
private def sha256Hash160(hex : String) = {
val bytes = decodeHex(hex)
val hash = org.bitcoinj.core.Utils.sha256hash160(bytes)
encodeHex(hash)
}
}

View file

@ -0,0 +1,16 @@
package org.scalacoin.script.interpreter
import org.scalacoin.script.ScriptOperation
import org.scalacoin.script.stack.OP_DUP
import scala.collection.immutable.Stack
/**
* Created by chris on 1/6/16.
*/
trait ScriptInterpreter {
}

View file

@ -0,0 +1,24 @@
package org.scalacoin.script.stack
import org.scalacoin.script.ScriptOperation
/**
* Created by chris on 1/6/16.
*/
trait StackInterpreter {
/**
* Duplicates the element on top of the stack
* expects the first element in script to be the OP_DUP operation
* @param stack
* @param script
* @return
*/
def opDup(stack : List[String], script : List[ScriptOperation]) : (List[String], List[ScriptOperation]) = {
require(script.headOption.isDefined && script.head == OP_DUP, "Top of the script stack must be OP_DUP")
require(stack.headOption.isDefined, "Cannot duplicate the top element on an empty stack")
stack match {
case h :: t => (h :: stack, script.tail)
case Nil => throw new RuntimeException("Received an empty stack! Cannot duplicate an element on an empty stack")
}
}
}

View file

@ -0,0 +1,13 @@
package org.scalacoin.script.interpreter
import org.scalacoin.script.stack.OP_DUP
import org.scalatest.{MustMatchers, FlatSpec}
/**
* Created by chris on 1/6/16.
*/
class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterpreter {
}

View file

@ -0,0 +1,37 @@
package org.scalacoin.script.stack
import org.scalatest.{FlatSpec, MustMatchers}
/**
* Created by chris on 1/6/16.
*/
class StackInterpreterTest extends FlatSpec with MustMatchers with StackInterpreter {
"StackInterpreter" must "duplicate elements on top of the stack" in {
val stack = List("Hello","World")
val script = List(OP_DUP)
val (newStack,newScript) = opDup(stack,script)
newStack.head must be ("Hello")
newStack(1) must be ("Hello")
newStack(2) must be ("World")
}
it must "throw an exception when calling opDup without an OP_DUP on top of the script stack" in {
intercept[IllegalArgumentException] {
val stack = List("Hello","World")
val script = List()
val (newStack,newScript) = opDup(stack,script)
}
}
it must "throw an exception when calling opDup without an element on top of the stack" in {
intercept[IllegalArgumentException] {
val stack = List()
val script = List(OP_DUP)
val (newStack,newScript) = opDup(stack,script)
}
}
}