mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-20 02:11:40 +01:00
Adding transaction test utilility functions to build transactions for tests
This commit is contained in:
parent
0c486b303b
commit
5c8d915755
@ -3,6 +3,7 @@ package org.scalacoin.protocol.transaction
|
||||
import org.scalacoin.currency.Satoshis
|
||||
import org.scalacoin.marshallers.transaction.TransactionElement
|
||||
import org.scalacoin.protocol.{NetworkVarInt, VarInt}
|
||||
import org.scalacoin.util.ScalacoinUtil
|
||||
|
||||
/**
|
||||
* Created by chris on 7/14/15.
|
||||
@ -19,6 +20,7 @@ trait Transaction extends TransactionElement {
|
||||
def inputsSize = inputs.map(_.size).sum
|
||||
def outputsSize = outputs.map(_.size).sum
|
||||
|
||||
|
||||
//https://bitcoin.org/en/developer-reference#raw-transaction-format
|
||||
override def size = 4 + inputsSize + outputsSize + 4
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
package org.scalacoin.protocol.transaction
|
||||
|
||||
/**
|
||||
* Created by chris on 2/12/16.
|
||||
*/
|
||||
object TransactionConstants {
|
||||
|
||||
val version = 1
|
||||
val lockTime = 0
|
||||
}
|
@ -71,50 +71,23 @@ trait CryptoInterpreter extends ControlOperationsInterpreter with ScalacoinUtil
|
||||
ScriptProgramFactory.factory(program, newStackTop :: program.stack.tail, program.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[ScriptToken], script : List[ScriptToken], fullScript : List[ScriptToken]) : 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)
|
||||
???
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L818
|
||||
* @param program
|
||||
* @return
|
||||
*/
|
||||
def checkSig(tx : Transaction, scriptPubKey : ScriptPubKey) : Boolean = {
|
||||
val inputIndex = 0
|
||||
val signature : ScriptToken = tx.inputs.head.scriptSignature.asm.head
|
||||
val pubKey : ScriptToken = tx.inputs.head.scriptSignature.asm(1)
|
||||
def opCheckSig(program : ScriptProgram) : ScriptProgram = {
|
||||
require(program.script.headOption.isDefined && program.script.head == OP_CHECKSIG, "Script top must be OP_CHECKSIG")
|
||||
require(program.stack.size > 1, "Stack must have at least 2 items on it for OP_CHECKSIG")
|
||||
val pubKey = program.stack.head
|
||||
val signature = program.stack.tail.head
|
||||
val hashType = HashTypeFactory.fromByte(ScalacoinUtil.decodeHex(signature.hex.last))
|
||||
|
||||
//delete ECDSA signature
|
||||
val inputWithoutScriptSig : Seq[ScriptToken] = tx.inputs.head.scriptSignature.asm.tail
|
||||
|
||||
val fullScriptWithoutScripgSig : Seq[ScriptToken] = inputWithoutScriptSig ++ scriptPubKey.asm
|
||||
|
||||
val hashTypeOpt : Option[HashType] = HashTypeFactory.fromByte(ScalacoinUtil.decodeHex(signature.hex).last)
|
||||
require(hashTypeOpt.isDefined, "We must have a hash type be the last byte on the given signature")
|
||||
val hashType = hashTypeOpt.get
|
||||
|
||||
//hash for signature
|
||||
val hash : String = hashForSignature(inputWithoutScriptSig,tx,inputIndex,hashType)
|
||||
???
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,8 @@ class ConstantInterpreterTest extends FlatSpec with MustMatchers with ConstantIn
|
||||
val script = List(OP_PUSHDATA4, ScriptConstantImpl("01000000"), ScriptNumberImpl(9), OP_9, OP_EQUAL)
|
||||
val program = ScriptProgramFactory.factory(TestUtil.testProgram, stack,script)
|
||||
val newProgram = opPushData4(program)
|
||||
newProgram.stack must be (List(ScriptNumberImpl(9)))
|
||||
newProgram.script must be (List(OP_9, OP_EQUAL))
|
||||
newProgram.stack must be (List())
|
||||
newProgram.script must be (List(ScriptNumberImpl(9),OP_9, OP_EQUAL))
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,13 +63,13 @@ class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterp
|
||||
val source = scala.io.Source.fromFile("src/test/scala/org/scalacoin/script/interpreter/script_valid.json")
|
||||
|
||||
//use this to represent a single test case from script_valid.json
|
||||
/* val lines =
|
||||
val lines =
|
||||
"""
|
||||
|
|
||||
|[["0x4c 0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC"]]
|
||||
""".stripMargin*/
|
||||
|[["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC"]]
|
||||
""".stripMargin
|
||||
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
//val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
val json = lines.parseJson
|
||||
val testCasesOpt : Seq[Option[CoreTestCase]] = json.convertTo[Seq[Option[CoreTestCase]]]
|
||||
val testCases : Seq[CoreTestCase] = testCasesOpt.flatten
|
||||
|
44
src/test/scala/org/scalacoin/util/TransactionTestUtil.scala
Normal file
44
src/test/scala/org/scalacoin/util/TransactionTestUtil.scala
Normal file
@ -0,0 +1,44 @@
|
||||
package org.scalacoin.util
|
||||
|
||||
import org.scalacoin.currency.CurrencyUnits
|
||||
import org.scalacoin.protocol.script.{ScriptSignatureImpl, ScriptPubKey, ScriptPubKeyImpl, ScriptSignature}
|
||||
import org.scalacoin.protocol.transaction._
|
||||
import org.scalacoin.script.constant.{OP_0, ScriptToken}
|
||||
|
||||
/**
|
||||
* Created by chris on 2/12/16.
|
||||
*/
|
||||
trait TransactionTestUtil {
|
||||
|
||||
/**
|
||||
* Mimics the test utility found in bitcoin core
|
||||
* https://github.com/bitcoin/bitcoin/blob/605c17844ea32b6d237db6d83871164dc7d59dab/src/test/script_tests.cpp#L73
|
||||
* @param scriptSignature
|
||||
* @param tx
|
||||
*/
|
||||
def buildSpendingTransaction(scriptSignature : ScriptSignature, tx : Transaction) : Transaction = {
|
||||
val outpoint = TransactionOutPointImpl(tx.txId,0)
|
||||
val input = TransactionInputImpl(outpoint,scriptSignature,0xFFFFFFFF)
|
||||
//empty script pubkey
|
||||
val scriptPubKey = ScriptPubKeyImpl(Seq(),"",Seq())
|
||||
val output = TransactionOutputImpl(CurrencyUnits.oneSatoshi,0,scriptPubKey)
|
||||
TransactionImpl("",TransactionConstants.version,Seq(input),Seq(output),TransactionConstants.lockTime)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mimics this test utility found in bitcoin core
|
||||
* https://github.com/bitcoin/bitcoin/blob/605c17844ea32b6d237db6d83871164dc7d59dab/src/test/script_tests.cpp#L57
|
||||
* @param scriptPubKey
|
||||
* @return
|
||||
*/
|
||||
def buildCreditingTransaction(scriptPubKey : ScriptPubKey) : Transaction = {
|
||||
val outpoint = TransactionOutPointImpl("",0)
|
||||
|
||||
val scriptSignature = ScriptSignatureImpl(Seq(OP_0,OP_0),"0000")
|
||||
val input = TransactionInputImpl(outpoint,scriptSignature,0xFFFFFFFF)
|
||||
val output = TransactionOutputImpl(CurrencyUnits.oneSatoshi,0,scriptPubKey)
|
||||
|
||||
TransactionImpl("",TransactionConstants.version,Seq(input),Seq(output),TransactionConstants.lockTime)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user