Adding AddressType

This commit is contained in:
Chris Stewart 2016-01-13 09:27:09 -06:00
parent 63a0b5cfaf
commit eac24ded52
5 changed files with 83 additions and 11 deletions

View File

@ -0,0 +1,27 @@
package org.scalacoin.marshallers.script
import org.scalacoin.marshallers.RawBitcoinSerializer
import org.scalacoin.protocol.script.{ScriptPubKeyImpl, ScriptPubKey}
import org.scalacoin.script.constant.ScriptToken
import org.scalacoin.util.ScalacoinUtil
/**
* Created by chris on 1/12/16.
*/
trait RawScriptPubKeyParser extends RawBitcoinSerializer[ScriptPubKey] with ScriptParser {
override def read(hex : String) : ScriptPubKey = {
require(hex.size > 0, "Cannot parse a scriptPubKey from an empty string")
val bytes = ScalacoinUtil.decodeHex(hex)
//first byte indicates how many bytes the script is
val scriptSize = bytes.head
val script : List[ScriptToken] = parse(bytes.tail)
//not sure how to get addresses from a scriptPubKey
ScriptPubKeyImpl(script,hex,Seq())
}
override def write(scriptPubKey : ScriptPubKey) : String = ???
}

View File

@ -17,8 +17,8 @@ trait ScriptParser extends ScalacoinUtil {
* @return
*/
def parse(str : String) : List[ScriptToken] = {
require(ScriptOperationFactory.fromString(str.split(" ").head).isDefined,
"String for parsing was not given in asm format. Needs to have a asm operation, for example OP_DUP")
/* require(ScriptOperationFactory.fromString(str.split(" ").head).isDefined,
"String for parsing was not given in asm format. Needs to have a asm operation, for example OP_DUP")*/
@tailrec
def loop(operations : List[String], accum : List[ScriptToken]) : List[ScriptToken] = {
operations match {
@ -47,9 +47,9 @@ trait ScriptParser extends ScalacoinUtil {
case h :: t =>
val op = ScriptOperationFactory.fromOpCode(h).get
//means that we need to push x amount of bytes on to the stack
if (ScriptNumberFactory.operations.contains(op)) {
val (constant,tail) = pushConstant(ScriptNumberImpl(op.opCode),t)
loop(tail, constant :: accum)
if (ScriptNumberFactory.operations.contains(op)) {
val (constant,tail) = pushConstant(ScriptNumberImpl(op.opCode),t)
loop(tail, constant :: accum)
} else loop(t, op :: accum)
case Nil => accum
}

View File

@ -1,7 +1,10 @@
package org.scalacoin.protocol.script
import org.scalacoin.protocol.BitcoinAddress
import org.scalacoin.script.constant.ScriptToken
import org.scalacoin.protocol._
import org.scalacoin.script.bitwise.{OP_EQUAL, OP_EQUALVERIFY}
import org.scalacoin.script.constant.{ScriptConstantImpl, ScriptToken}
import org.scalacoin.script.crypto.{OP_CHECKSIG, OP_HASH160}
import org.scalacoin.script.stack.OP_DUP
/**
* Created by chris on 12/26/15.
@ -9,11 +12,25 @@ import org.scalacoin.script.constant.ScriptToken
trait ScriptPubKey extends ScriptSignature {
def reqSigs : Int
def addressType : String
def reqSigs : Option[Int] = {
addressType match {
case P2PKH => Some(1)
//TODO: Figure out how many signatures are actually required by the scriptPubKey
case P2SH => None
case NonStandard => None
}
}
def addressType : AddressType = {
asm match {
case List(OP_DUP, OP_HASH160, ScriptConstantImpl(pubKeyHash), OP_EQUALVERIFY, OP_CHECKSIG) => P2PKH
case List(OP_HASH160, ScriptConstantImpl(scriptHash), OP_EQUAL) => P2SH
case _ => NonStandard
}
}
//the addresses that the bitcoins correlated to the output
def addresses : Seq[BitcoinAddress]
}
case class ScriptPubKeyImpl(asm : List[ScriptToken], hex : String, reqSigs : Int,
addressType : String, addresses : Seq[BitcoinAddress]) extends ScriptPubKey
case class ScriptPubKeyImpl(asm : List[ScriptToken], hex : String, addresses : Seq[BitcoinAddress]) extends ScriptPubKey

View File

@ -0,0 +1,27 @@
package org.scalacoin.marshallers.script
import org.scalacoin.protocol.script.ScriptPubKey
import org.scalacoin.script.bitwise.OP_EQUALVERIFY
import org.scalacoin.script.constant.ScriptConstantImpl
import org.scalacoin.script.crypto.{OP_CHECKSIG, OP_HASH160}
import org.scalacoin.script.stack.OP_DUP
import org.scalatest.{FlatSpec, MustMatchers}
/**
* Created by chris on 1/12/16.
*/
class RawScriptPubKeyParserTest extends FlatSpec with MustMatchers with RawScriptPubKeyParser {
//scriptPubKey taken from https://bitcoin.org/en/developer-reference#raw-transaction-format
val rawScriptPubKey = "1976a914cbc20a7664f2f69e5355aa427045bc15e7c6c77288ac"
"RawScriptPubKeyParser" must "parse a hex string into a scriptPubKey" in {
val scriptPubKey : ScriptPubKey = read(rawScriptPubKey)
println(encodeBase58(decodeHex("cbc20a7664f2f69e5355aa427045bc15e7c6c772")))
scriptPubKey.asm must be (Seq(OP_DUP,OP_HASH160,ScriptConstantImpl("cbc20a7664f2f69e5355aa427045bc15e7c6c772"),OP_EQUALVERIFY,OP_CHECKSIG))
}
}

View File

@ -18,6 +18,7 @@ object TestUtil {
val assetAddress = AssetAddress("akJsoCcyh34FGPotxfEoSXGwFPCNAkyCgTA")
val p2pkhInputScript = "473044022016ffdbb7c57634903c5e018fcfc48d59f4e37dc4bc3bbc9ba4e6ee39150bca030220119c2241a931819bc1a75d3596e4029d803d1cd6de123bf8a1a1a2c3665e1fac012102af7dad03e682fcd0427b5c24140c220ac9d8abe286c15f8cf5bf77eed19c3652"
val p2pkhInputScriptNotParsedAsm =
"3044022016ffdbb7c57634903c5e018fcfc48d59f4e37dc4bc3bbc9ba4e6ee39150bca030220119c2241a931819bc1a75d3596e4029d803d1cd6de123bf8a1a1a2c3665e1fac01" +
" 02af7dad03e682fcd0427b5c24140c220ac9d8abe286c15f8cf5bf77eed19c3652"