renaming fromOpCode to fromByte inside of ScriptOperationFactory

This commit is contained in:
Chris Stewart 2016-01-18 12:46:30 -06:00
parent 6f4687c50e
commit 2b642deb32
6 changed files with 68 additions and 17 deletions

View File

@ -45,7 +45,7 @@ trait ScriptParser extends ScalacoinUtil {
def loop(bytes : List[Byte], accum : List[ScriptToken]) : List[ScriptToken] = {
bytes match {
case h :: t =>
val op = ScriptOperationFactory.fromOpCode(h).get
val op = ScriptOperationFactory.fromByte(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)

View File

@ -11,6 +11,8 @@ import org.scalacoin.util.ScalacoinUtil
/**
* Created by chris on 1/8/16.
* Responsible for matching script op codes with their given
* hexadecimal representation or byte representation
*/
trait ScriptOperationFactory[T <: ScriptOperation] extends ScalacoinUtil {
@ -28,7 +30,12 @@ trait ScriptOperationFactory[T <: ScriptOperation] extends ScalacoinUtil {
*/
def fromString(str : String) : Option[T] = operations.find(_.toString == str)
def fromOpCode(byte : Byte) : Option[T] = {
/**
* Finds a script operation from a given byte
* @param byte
* @return
*/
def fromByte(byte : Byte) : Option[T] = {
val hex = encodeHex(byte)
operations.find(op => op.hex == hex)
}

View File

@ -5,11 +5,13 @@ package org.scalacoin.script.constant
*/
trait ScriptToken
trait ScriptToken {
def hex : String
}
trait ScriptOperation extends ScriptToken {
def opCode : Int
def hex : String = {
override def hex : String = {
val hex = Integer.toHexString(opCode)
if (hex == "0") "00" else hex
}
@ -19,10 +21,9 @@ sealed trait ScriptConstant extends ScriptToken
/**
* Represent a pubkey or hash of a pub key on our stack
*
* @param str
* @param hex
*/
case class ScriptConstantImpl(str : String) extends ScriptConstant
case class ScriptConstantImpl(hex : String) extends ScriptConstant
/**
* An empty array of bytes is pushed onto the stack. (This is not a no-op: an item is added to the stack.)

View File

@ -1,6 +1,8 @@
package org.scalacoin.script.crypto
import org.scalacoin.script.constant.{ScriptConstantImpl, ScriptConstant, ScriptToken}
import org.scalacoin.protocol.script.ScriptPubKey
import org.scalacoin.protocol.transaction.Transaction
import org.scalacoin.script.constant.{ScriptOperation, ScriptConstantImpl, ScriptConstant, ScriptToken}
import org.scalacoin.util.{CryptoUtil, ScalacoinUtil}
@ -37,7 +39,36 @@ trait CryptoInterpreter extends ScalacoinUtil {
???
}
/*def codeSeparator()*/
/**
* 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(tx : Transaction, scriptPubKey : ScriptPubKey) : Boolean = {
val signature : ScriptToken = tx.inputs.head.scriptSignature.asm.head
val pubKey : ScriptToken = tx.inputs.head.scriptSignature.asm(1)
//delete ECDSA signature
val inputWithoutScriptSig : Seq[ScriptToken] = tx.inputs.head.scriptSignature.asm.tail
val fullScriptWithoutScripgSig : Seq[ScriptToken] = inputWithoutScriptSig ++ scriptPubKey.asm
/*val hashType = HashTypeFactory.factory(ScalacoinUtil.decodeHex(signature.hex).last)*/
//check signature against the tx
???
}
}

View File

@ -15,18 +15,18 @@ import org.scalatest.{FlatSpec, MustMatchers}
class ScriptOperationFactoryTest extends FlatSpec with MustMatchers {
"ScriptOperationFactory" must "match operations with their byte representation" in {
ScriptOperationFactory.fromOpCode(0x00) must be (Some(OP_0))
ScriptOperationFactory.fromOpCode(0x51) must be (Some(OP_1))
ScriptOperationFactory.fromByte(0x00) must be (Some(OP_0))
ScriptOperationFactory.fromByte(0x51) must be (Some(OP_1))
ScriptOperationFactory.fromOpCode(0x63) must be (Some(OP_IF))
ScriptOperationFactory.fromOpCode(0x6b) must be (Some(OP_TOALTSTACK))
ScriptOperationFactory.fromByte(0x63) must be (Some(OP_IF))
ScriptOperationFactory.fromByte(0x6b) must be (Some(OP_TOALTSTACK))
ScriptOperationFactory.fromOpCode(135.toByte) must be (Some(OP_EQUAL))
ScriptOperationFactory.fromByte(135.toByte) must be (Some(OP_EQUAL))
ScriptOperationFactory.fromOpCode(139.toByte) must be (Some(OP_1ADD))
ScriptOperationFactory.fromByte(139.toByte) must be (Some(OP_1ADD))
ScriptOperationFactory.fromOpCode(166.toByte) must be (Some(OP_RIPEMD160))
ScriptOperationFactory.fromOpCode(177.toByte) must be (Some(OP_CHECKLOCKTIMEVERIFY))
ScriptOperationFactory.fromByte(166.toByte) must be (Some(OP_RIPEMD160))
ScriptOperationFactory.fromByte(177.toByte) must be (Some(OP_CHECKLOCKTIMEVERIFY))
}

View File

@ -1,6 +1,7 @@
package org.scalacoin.util
import org.scalacoin.marshallers.script.RawScriptPubKeyParser
import org.scalacoin.marshallers.transaction.RawTransactionParser
import org.scalacoin.protocol.{AssetAddress, BitcoinAddress}
import org.scalacoin.script.bitwise.{OP_EQUAL, OP_EQUALVERIFY}
import org.scalacoin.script.constant.{ScriptToken, OP_0, ScriptConstantImpl}
@ -48,12 +49,23 @@ object TestUtil {
val p2shOutputScriptAsm = List(OP_HASH160, ScriptConstantImpl("eda8ae08b5c9f973f49543e90a7c292367b3337c"), OP_EQUAL)
//txid on testnet 44e504f5b7649d215be05ad9f09026dee95201244a3b218013c504a6a49a26ff
//this tx has multiple inputs and outputs
val rawTransaction = "01000000" +
"02df80e3e6eba7dcd4650281d3c13f140dafbb823a7227a78eb6ee9f6cedd040011b0000006a473044022040f91c48f4011bf2e2edb6621bfa8fb802241de939cb86f1872c99c580ef0fe402204fc27388bc525e1b655b5f5b35f9d601d28602432dd5672f29e0a47f5b8bbb26012102c114f376c98d12a0540c3a81ab99bb1c5234245c05e8239d09f48229f9ebf011ffffffff" +
"df80e3e6eba7dcd4650281d3c13f140dafbb823a7227a78eb6ee9f6cedd04001340000006b483045022100cf317c320d078c5b884c44e7488825dab5bcdf3f88c66314ac925770cd8773a7022033fde60d33cc2842ea73fce5d9cf4f8da6fadf414a75b7085efdcd300407f438012102605c23537b27b80157c770cd23e066cd11db3800d3066a38b9b592fc08ae9c70ffffffff" +
"02c02b00000000000017a914b0b06365c482eb4eabe6e0630029fb8328ea098487e81c0000000000001976a914938da2b50fd6d8acdfa20e30df0e7d8092f0bc7588ac00000000"
val transaction = RawTransactionParser.read(rawTransaction)
//simple raw transaction with only one input and two outputs
//txid 92efdd5abb43efd4fe4f89bd080bcddd287a630e8cb6920388dd7880acf4c964
val simpleRawTransaction = "0100000001ccf318f0cbac588a680bbad075aebdda1f211c94ba28125b0f627f9248310db3000000006b4830450221008337ce3ce0c6ac0ab72509f889c1d52701817a2362d6357457b63e3bdedc0c0602202908963b9cf1a095ab3b34b95ce2bc0d67fb0f19be1cc5f7b3de0b3a325629bf01210241d746ca08da0a668735c3e01c1fa02045f2f399c5937079b6434b5a31dfe353ffffffff0210335d05000000001976a914b1d7591b69e9def0feb13254bace942923c7922d88ac48030000000000001976a9145e690c865c2f6f7a9710a474154ab1423abb5b9288ac00000000"
val simpleTransaction = RawTransactionParser.read(simpleRawTransaction)
//parent to the 'simpleRawTransaction' val in this file. It is referenced by the input,
//which needs to have access to this tx to view the scriptPubKey
//txid b30d3148927f620f5b1228ba941c211fdabdae75d0ba0b688a58accbf018f3cc
val parentSimpleRawTransaction = "0100000001cda741646fada7272b900719f7ac9d68d633d0e8aa9501eed3c90afbd323bd65010000006a4730440220048e15422cf62349dc586ffb8c749d40280781edd5064ff27a5910ff5cf225a802206a82685dbc2cf195d158c29309939d5a3cd41a889db6f766f3809fff35722305012103dcfc9882c1b3ae4e03fb6cac08bdb39e284e81d70c7aa8b27612457b2774509bffffffff026c405d05000000001976a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac809698000000000017a914af575bd77c5ce7eba3bd9ce6f89774713ae62c798700000000"
val parentSimpleTransaction = RawTransactionParser.read(parentSimpleRawTransaction)
//scriptPubKey taken from https://bitcoin.org/en/developer-reference#raw-transaction-format
val rawScriptPubKey = "1976a914cbc20a7664f2f69e5355aa427045bc15e7c6c77288ac"
val scriptPubKey = RawScriptPubKeyParser.read(rawScriptPubKey)