mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-20 10:13:26 +01:00
Adding signature for parse function
This commit is contained in:
parent
3df808a82b
commit
327844fa3b
@ -11,6 +11,17 @@ trait ScriptOperation {
|
|||||||
|
|
||||||
sealed trait Constant extends ScriptOperation
|
sealed trait Constant extends ScriptOperation
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent a pubkey or hash of a pub key on our stack
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
*/
|
||||||
|
case class ConstantImpl(str : String) extends ScriptOperation {
|
||||||
|
//TODO: Get around this op code some how, constants don't have op codes
|
||||||
|
override def opCode = -1
|
||||||
|
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* An empty array of bytes is pushed onto the stack. (This is not a no-op: an item is added to the stack.)
|
* An empty array of bytes is pushed onto the stack. (This is not a no-op: an item is added to the stack.)
|
||||||
*/
|
*/
|
||||||
|
@ -17,6 +17,26 @@ trait CryptoInterpreter extends ScalacoinUtil {
|
|||||||
(hash :: stack, script.tail)
|
(hash :: stack, script.tail)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The entire transaction's outputs, inputs, and script (from the most
|
||||||
|
* recently-executed OP_CODESEPARATOR to the end) are hashed.
|
||||||
|
* The signature used by OP_CHECKSIG must be a valid signature for this hash and public key.
|
||||||
|
* If it is, 1 is returned, 0 otherwise.
|
||||||
|
* @param inputScript
|
||||||
|
* @param script
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
def checkSig(inputScript : List[String], script : List[ScriptOperation]) : Boolean = {
|
||||||
|
require(inputScript.size > 1, "We must have at least 2 inputs for our OP_CHECKSIG operation")
|
||||||
|
require(script.headOption.isDefined && script.head == OP_CHECKSIG, "The top script stack element must be OP_CHECKSIG")
|
||||||
|
val pubKey = inputScript.head
|
||||||
|
val signature = inputScript(1)
|
||||||
|
???
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*def codeSeparator()*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the following computation
|
* Does the following computation
|
||||||
|
@ -1,16 +1,51 @@
|
|||||||
package org.scalacoin.script.interpreter
|
package org.scalacoin.script.interpreter
|
||||||
|
|
||||||
import org.scalacoin.script.ScriptOperation
|
import org.scalacoin.script.{ConstantImpl, ScriptOperation}
|
||||||
import org.scalacoin.script.stack.OP_DUP
|
import org.scalacoin.script.bitwise.{OP_EQUAL, BitwiseInterpreter, OP_EQUALVERIFY}
|
||||||
|
import org.scalacoin.script.control.ControlOperationsInterpreter
|
||||||
|
import org.scalacoin.script.crypto.{OP_CHECKSIG, OP_HASH160, CryptoInterpreter}
|
||||||
|
import org.scalacoin.script.stack.{StackInterpreter, OP_DUP}
|
||||||
|
|
||||||
|
import scala.annotation.tailrec
|
||||||
import scala.collection.immutable.Stack
|
import scala.collection.immutable.Stack
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by chris on 1/6/16.
|
* Created by chris on 1/6/16.
|
||||||
*/
|
*/
|
||||||
trait ScriptInterpreter {
|
trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with ControlOperationsInterpreter
|
||||||
|
with BitwiseInterpreter {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs an entire script though our script programming language and
|
||||||
|
* returns true or false depending on if the script was valid
|
||||||
|
* @param stack
|
||||||
|
* @param script
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
|
||||||
|
def run(inputScript : List[String], outputScript : List[ScriptOperation]) : Boolean = {
|
||||||
|
|
||||||
|
@tailrec
|
||||||
|
def loop(scripts : (List[String], List[ScriptOperation])) : Boolean = {
|
||||||
|
val (inputScript,outputScript) = (scripts._1, scripts._2)
|
||||||
|
outputScript match {
|
||||||
|
case OP_DUP :: t => loop(opDup(inputScript,outputScript))
|
||||||
|
case OP_HASH160 :: t => loop(hash160(inputScript,outputScript))
|
||||||
|
case OP_EQUAL :: t => loop(equal(inputScript, outputScript))
|
||||||
|
//TODO: Implement these
|
||||||
|
case ConstantImpl(x) :: t if x == "1" => throw new RuntimeException("Not implemented yet")
|
||||||
|
case ConstantImpl(x) :: t if x == "0" => throw new RuntimeException("Not implemented yet")
|
||||||
|
//TODO: is this right? I need to just push a constant on the input stack???
|
||||||
|
case ConstantImpl(x) :: t => loop(x :: inputScript, outputScript.tail)
|
||||||
|
//these cases result in our boolean result
|
||||||
|
case OP_EQUALVERIFY :: t => equalVerify(inputScript,outputScript)
|
||||||
|
/*case OP_CHECKSIG :: t => checkSig(inputScript,outputScript)*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loop((inputScript,outputScript))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.scalacoin.script.parsing
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by chris on 1/7/16.
|
||||||
|
*/
|
||||||
|
trait ScriptParser {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a script inside of a transaction
|
||||||
|
* @param str
|
||||||
|
* @tparam T
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
def parse[T](str : String) : List[T] = ???
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
package org.scalacoin.script.interpreter
|
package org.scalacoin.script.interpreter
|
||||||
|
|
||||||
|
import org.scalacoin.script.bitwise.OP_EQUALVERIFY
|
||||||
|
import org.scalacoin.script.{ConstantImpl, ScriptOperation}
|
||||||
|
import org.scalacoin.script.crypto.{OP_CHECKSIG, OP_HASH160}
|
||||||
import org.scalacoin.script.stack.OP_DUP
|
import org.scalacoin.script.stack.OP_DUP
|
||||||
import org.scalatest.{MustMatchers, FlatSpec}
|
import org.scalatest.{MustMatchers, FlatSpec}
|
||||||
|
|
||||||
@ -10,4 +13,17 @@ class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterp
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* "ScriptInterpreter" must "evaluate a valid script to true" in {
|
||||||
|
//this is in asm format, not hex
|
||||||
|
val inputScript =
|
||||||
|
List("3044022016ffdbb7c57634903c5e018fcfc48d59f4e37dc4bc3bbc9ba4e6ee39150bca030220119c2241a931819bc1a75d3596e4029d803d1cd6de123bf8a1a1a2c3665e1fac01",
|
||||||
|
"02af7dad03e682fcd0427b5c24140c220ac9d8abe286c15f8cf5bf77eed19c3652")
|
||||||
|
//this is asm format, not hex
|
||||||
|
val outputScript : List[ScriptOperation] =
|
||||||
|
List(OP_DUP,OP_HASH160,ConstantImpl("e2e7c1ab3f807151e832dd1accb3d4f5d7d19b4b"),OP_EQUALVERIFY, OP_CHECKSIG)
|
||||||
|
val result = run(inputScript, outputScript)
|
||||||
|
result must be (true)
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.scalacoin.script.parsing
|
||||||
|
|
||||||
|
import org.scalacoin.util.TestUtil
|
||||||
|
import org.scalatest.{FlatSpec, MustMatchers}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by chris on 1/7/16.
|
||||||
|
*/
|
||||||
|
class ScriptParserTest extends FlatSpec with MustMatchers with ScriptParser {
|
||||||
|
|
||||||
|
|
||||||
|
"ScriptParser" must "parse an input script" in {
|
||||||
|
val parsedInput = parse(TestUtil.p2khInputScriptNotParsed)
|
||||||
|
parsedInput must be (TestUtil.p2pkhInputScript)
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
package org.scalacoin.util
|
package org.scalacoin.util
|
||||||
|
|
||||||
import org.scalacoin.protocol.{AssetAddress, BitcoinAddress}
|
import org.scalacoin.protocol.{AssetAddress, BitcoinAddress}
|
||||||
|
import org.scalacoin.script.ConstantImpl
|
||||||
|
import org.scalacoin.script.bitwise.OP_EQUALVERIFY
|
||||||
|
import org.scalacoin.script.crypto.{OP_CHECKSIG, OP_HASH160}
|
||||||
|
import org.scalacoin.script.stack.OP_DUP
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by chris on 12/2/15.
|
* Created by chris on 12/2/15.
|
||||||
@ -12,4 +16,12 @@ object TestUtil {
|
|||||||
val bitcoinAddress = BitcoinAddress("1C4kYhyLftmkn48YarSoLupxHfYFo8kp64")
|
val bitcoinAddress = BitcoinAddress("1C4kYhyLftmkn48YarSoLupxHfYFo8kp64")
|
||||||
val multiSigAddress = BitcoinAddress("342ftSRCvFHfCeFFBuz4xwbeqnDw6BGUey")
|
val multiSigAddress = BitcoinAddress("342ftSRCvFHfCeFFBuz4xwbeqnDw6BGUey")
|
||||||
val assetAddress = AssetAddress("akJsoCcyh34FGPotxfEoSXGwFPCNAkyCgTA")
|
val assetAddress = AssetAddress("akJsoCcyh34FGPotxfEoSXGwFPCNAkyCgTA")
|
||||||
|
|
||||||
|
val p2khInputScriptNotParsed =
|
||||||
|
"3044022016ffdbb7c57634903c5e018fcfc48d59f4e37dc4bc3bbc9ba4e6ee39150bca030220119c2241a931819bc1a75d3596e4029d803d1cd6de123bf8a1a1a2c3665e1fac01" +
|
||||||
|
" 02af7dad03e682fcd0427b5c24140c220ac9d8abe286c15f8cf5bf77eed19c365
|
||||||
|
val p2khInputScript = List("3044022016ffdbb7c57634903c5e018fcfc48d59f4e37dc4bc3bbc9ba4e6ee39150bca030220119c2241a931819bc1a75d3596e4029d803d1cd6de123bf8a1a1a2c3665e1fac01",
|
||||||
|
"02af7dad03e682fcd0427b5c24140c220ac9d8abe286c15f8cf5bf77eed19c3652")2"
|
||||||
|
val p2pkhOutputScriptNotParsed = "OP_DUP OP_HASH160 e2e7c1ab3f807151e832dd1accb3d4f5d7d19b4b OP_EQUALVERIFY OP_CHECKSI
|
||||||
|
val p2khOutputScript = List(OP_DUP,OP_HASH160,ConstantImpl("e2e7c1ab3f807151e832dd1accb3d4f5d7d19b4b"),OP_EQUALVERIFY, OP_CHECKSIG)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user