mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-20 10:13:26 +01:00
Adding 'asmBytes' val to ScriptSignature -- this is the raw byte array from the scriptSig WITHOUT the a CompactSizeUInt bytes at the beginning
This commit is contained in:
parent
974829cc2d
commit
ed0a1b37e7
@ -27,6 +27,8 @@ sealed trait ScriptSignature extends NetworkElement with BitcoinSLogger {
|
||||
*/
|
||||
lazy val asm : Seq[ScriptToken] = ScriptParser.fromBytes(bytes.splitAt(compactSizeUInt.size.toInt)._2)
|
||||
|
||||
/** Byte vector for script program WITHOUT the [[CompactSizeUInt]], this is the raw byte vector that can be run */
|
||||
lazy val asmBytes = asm.flatMap(_.bytes)
|
||||
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,7 @@ import org.bitcoins.core.crypto.{BaseTransactionSignatureComponent, TransactionS
|
||||
import org.bitcoins.core.currency.CurrencyUnit
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptWitness, SignatureVersion}
|
||||
import org.bitcoins.core.protocol.transaction.{Transaction, WitnessTransaction}
|
||||
import org.bitcoins.core.protocol.transaction.{BaseTransaction, Transaction, WitnessTransaction}
|
||||
import org.bitcoins.core.script.constant._
|
||||
import org.bitcoins.core.script.flag.ScriptFlag
|
||||
import org.bitcoins.core.script.result._
|
||||
@ -328,6 +328,14 @@ object ScriptProgram {
|
||||
script,originalScript, altStack,flags, witness, txSigComponent.sigVersion, amount)
|
||||
}
|
||||
|
||||
|
||||
def apply(transaction: BaseTransaction, scriptPubKey: ScriptPubKey, inputIndex: UInt32, stack: Seq[ScriptToken],
|
||||
script: Seq[ScriptToken], originalScript: Seq[ScriptToken], altStack: Seq[ScriptToken],
|
||||
flags: Seq[ScriptFlag]): PreExecutionScriptProgram = {
|
||||
val t = TransactionSignatureComponent(transaction,inputIndex,scriptPubKey,flags)
|
||||
PreExecutionScriptProgramImpl(t,stack.toList,script.toList,originalScript.toList,altStack.toList,flags)
|
||||
}
|
||||
|
||||
/** Creates a fresh instance of [[org.bitcoins.core.script.PreExecutionScriptProgram]] */
|
||||
def apply(transaction: Transaction, scriptPubKey: ScriptPubKey, inputIndex: UInt32, flags: Seq[ScriptFlag]): PreExecutionScriptProgram = {
|
||||
val t = TransactionSignatureComponent(transaction,inputIndex,scriptPubKey,flags)
|
||||
|
@ -4,6 +4,7 @@ import org.bitcoins.core.script.constant.ScriptToken
|
||||
import org.bitcoins.core.consensus.Consensus
|
||||
import org.bitcoins.core.crypto.{BaseTransactionSignatureComponent, WitnessV0TransactionSignatureComponent}
|
||||
import org.bitcoins.core.currency.{CurrencyUnit, CurrencyUnits}
|
||||
import org.bitcoins.core.protocol.CompactSizeUInt
|
||||
import org.bitcoins.core.protocol.script._
|
||||
import org.bitcoins.core.protocol.transaction.{EmptyTransactionOutPoint, Transaction}
|
||||
import org.bitcoins.core.script._
|
||||
@ -115,7 +116,9 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
|
||||
//we need to run the deserialized redeemScript & the scriptSignature without the serialized redeemScript
|
||||
val stack = scriptPubKeyExecutedProgram.stack
|
||||
logger.debug("P2sh stack: " + stack)
|
||||
val redeemScript = ScriptPubKey(stack.head.bytes)
|
||||
val redeemScriptBytes = stack.head.bytes
|
||||
val c = CompactSizeUInt.calculateCompactSizeUInt(redeemScriptBytes)
|
||||
val redeemScript = ScriptPubKey(c.bytes ++ redeemScriptBytes)
|
||||
logger.debug("Redeem script asm: " + redeemScript.asm)
|
||||
val p2shRedeemScriptProgram = ScriptProgram(scriptPubKeyExecutedProgram.txSignatureComponent,stack.tail,
|
||||
redeemScript.asm)
|
||||
@ -411,8 +414,8 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
|
||||
val noDuplicateInputs = prevOutputTxIds.distinct.size == prevOutputTxIds.size
|
||||
|
||||
val isValidScriptSigForCoinbaseTx = transaction.isCoinbase match {
|
||||
case true => transaction.inputs.head.scriptSignature.size >= 2 &&
|
||||
transaction.inputs.head.scriptSignature.size <= 100
|
||||
case true => transaction.inputs.head.scriptSignature.asmBytes.size >= 2 &&
|
||||
transaction.inputs.head.scriptSignature.asmBytes.size <= 100
|
||||
case false =>
|
||||
//since this is not a coinbase tx we cannot have any empty previous outs inside of inputs
|
||||
!transaction.inputs.exists(_.previousOutput == EmptyTransactionOutPoint)
|
||||
|
@ -13,7 +13,7 @@ import org.scalacheck.{Prop, Properties}
|
||||
* Created by chris on 7/25/16.
|
||||
*/
|
||||
class TransactionSignatureCreatorSpec extends Properties("TransactionSignatureCreatorSpec") with BitcoinSLogger {
|
||||
/* property("Must generate a valid signature for a p2pk transaction") =
|
||||
property("Must generate a valid signature for a p2pk transaction") =
|
||||
Prop.forAll(TransactionGenerators.signedP2PKTransaction) {
|
||||
case (txSignatureComponent: TransactionSignatureComponent, _) =>
|
||||
//run it through the interpreter
|
||||
@ -40,7 +40,7 @@ class TransactionSignatureCreatorSpec extends Properties("TransactionSignatureCr
|
||||
val result = ScriptInterpreter.run(program)
|
||||
|
||||
result == ScriptOk
|
||||
}*/
|
||||
}
|
||||
|
||||
property("generate a valid signature for a p2sh transaction") =
|
||||
Prop.forAll(TransactionGenerators.signedP2SHTransaction) {
|
||||
@ -52,7 +52,7 @@ class TransactionSignatureCreatorSpec extends Properties("TransactionSignatureCr
|
||||
Seq(ScriptOk, ScriptErrorPushSize).contains(result)
|
||||
}
|
||||
|
||||
/* property("generate a valid signature for a valid and spendable cltv transaction") =
|
||||
property("generate a valid signature for a valid and spendable cltv transaction") =
|
||||
Prop.forAllNoShrink(TransactionGenerators.spendableCLTVTransaction :| "cltv_spendable") {
|
||||
case (txSignatureComponent: TransactionSignatureComponent, _, scriptNumber) =>
|
||||
//run it through the interpreter
|
||||
@ -93,5 +93,5 @@ class TransactionSignatureCreatorSpec extends Properties("TransactionSignatureCr
|
||||
val result = ScriptInterpreter.run(program)
|
||||
Seq(ScriptErrorUnsatisfiedLocktime, ScriptErrorPushSize).contains(result)
|
||||
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|
||||
| "010000000200010000000000000000000000000000000000000000000000000000000000000000000049483045022100d180fd2eb9140aeb4210c9204d3f358766eb53842b2a9473db687fa24b12a3cc022079781799cd4f038b85135bbe49ec2b57f306b2bb17101b17f71f000fcab2b6fb01ffffffff0002000000000000000000000000000000000000000000000000000000000000000000004847304402205f7530653eea9b38699e476320ab135b74771e1c48b81a5d041e2ca84b9be7a802200ac8d1f40fb026674fe5a5edd3dea715c27baa9baca51ed45ea750ac9dc0a55e81ffffffff010100000000000000015100000000", "P2SH"]
|
||||
|
|
||||
|]
|
||||
""".stripMargin*/
|
||||
""".stripMargin */
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
val json = lines.parseJson
|
||||
val testCasesOpt : Seq[Option[CoreTransactionTestCase]] = json.convertTo[Seq[Option[CoreTransactionTestCase]]]
|
||||
@ -97,6 +97,7 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
it must "read all of the tx_invalid.json's contents and return a ScriptError" in {
|
||||
|
||||
|
||||
@ -107,8 +108,8 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|
||||
/* val lines =
|
||||
"""
|
||||
|[
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
|
||||
"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0151ffffffff010000000000000000015100000000", "P2SH"]
|
||||
|[[["6ca7ec7b1847f6bdbd737176050e6a08d66ccd55bb94ad24f4018024107a5827", 0, "0x41 0x043b640e983c9690a14c039a2037ecc3467b27a0dcd58f19d76c7bc118d09fec45adc5370a1c5bf8067ca9f5557a4cf885fdb0fe0dcc9c3a7137226106fbc779a5 CHECKSIG VERIFY 1"]],
|
||||
|"010000000127587a10248001f424ad94bb55cd6cd6086a0e05767173bdbdf647187beca76c000000004948304502201b822ad10d6adc1a341ae8835be3f70a25201bbff31f59cbb9c5353a5f0eca18022100ea7b2f7074e9aa9cf70aa8d0ffee13e6b45dddabf1ab961bda378bcdb778fa4701ffffffff0100f2052a010000001976a914fc50c5907d86fed474ba5ce8b12a66e0a4c139d888ac00000000", "P2SH"]
|
||||
|]
|
||||
""".stripMargin*/
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
@ -140,7 +141,7 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|
||||
}
|
||||
withClue(testCase.raw) {
|
||||
//only one input is required to be false to make the transaction invalid
|
||||
txInputValidity.exists(_ == false) must be (false)
|
||||
txInputValidity.exists(_ == false) must be (true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package org.bitcoins.core.script.crypto
|
||||
|
||||
import org.bitcoins.core.currency.CurrencyUnits
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptSignature, SigVersionBase}
|
||||
import org.bitcoins.core.protocol.script.{P2SHScriptSignature, ScriptPubKey, ScriptSignature, SigVersionBase}
|
||||
import org.bitcoins.core.protocol.transaction._
|
||||
import org.bitcoins.core.script._
|
||||
import org.bitcoins.core.script.constant._
|
||||
@ -16,7 +16,7 @@ import org.scalatest.{FlatSpec, MustMatchers}
|
||||
*/
|
||||
class CryptoInterpreterTest extends FlatSpec with MustMatchers with CryptoInterpreter with BitcoinSLogger {
|
||||
val stack = List(ScriptConstant("02218AD6CDC632E7AE7D04472374311CEBBBBF0AB540D2D08C3400BB844C654231".toLowerCase))
|
||||
/*
|
||||
|
||||
"CryptoInterpreter" must "evaluate OP_HASH160 correctly when it is on top of the script stack" in {
|
||||
|
||||
val script = List(OP_HASH160)
|
||||
@ -134,44 +134,8 @@ class CryptoInterpreterTest extends FlatSpec with MustMatchers with CryptoInterp
|
||||
newProgram.script.isEmpty must be (true)
|
||||
newProgram.isInstanceOf[ExecutedScriptProgram] must be (false)
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
it must "evaluate an OP_CHECKMULTISIG for a p2sh transaction" in {
|
||||
val rawScriptSig = "fc0047304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf80014730440220563e5b3b1fc11662a84bc5ea2a32cc3819703254060ba30d639a1aaf2d5068ad0220601c1f47ddc76d93284dd9ed68f7c9974c4a0ea7cbe8a247d6bc3878567a5fca014c6952210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae"
|
||||
val p2shScriptSig = ScriptSignature(rawScriptSig)
|
||||
|
||||
val rawScriptPubKey = "17a914c9e4a896d149702d0d1695434feddd52e24ad78d87"
|
||||
val p2shScriptPubKey = ScriptPubKey(rawScriptPubKey)
|
||||
|
||||
val (creditingTx,outputIndex) = TransactionTestUtil.buildCreditingTransaction(p2shScriptPubKey)
|
||||
val (spendingTx,inputIndex) = TransactionTestUtil.buildSpendingTransaction(creditingTx,p2shScriptSig,outputIndex)
|
||||
|
||||
val stack = List(ScriptNumber(3),
|
||||
ScriptConstant("03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640"),
|
||||
ScriptConstant("038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508"),
|
||||
ScriptConstant("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),
|
||||
ScriptNumber(2),
|
||||
ScriptConstant("30440220563e5b3b1fc11662a84bc5ea2a32cc3819703254060ba30d639a1aaf2d5068ad0220601c1f47ddc76d93284dd9ed68f7c9974c4a0ea7cbe8a247d6bc3878567a5fca01"),
|
||||
ScriptConstant("304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001"),
|
||||
OP_0)
|
||||
|
||||
val script = List(OP_CHECKMULTISIG)
|
||||
|
||||
val baseProgram = ScriptProgram(spendingTx,creditingTx.outputs(0).scriptPubKey,UInt32.zero,
|
||||
ScriptFlagFactory.empty)
|
||||
|
||||
val program = ScriptProgram(baseProgram,stack,script)
|
||||
val newProgram = opCheckMultiSig(program)
|
||||
newProgram.stackTopIsTrue must be (true)
|
||||
newProgram.stack.size must be (1)
|
||||
|
||||
newProgram.script.isEmpty must be (true)
|
||||
}
|
||||
|
||||
|
||||
/* it must "mark a transaction invalid when the NULLDUMMY flag is set for a OP_CHECKMULTISIG operation & the scriptSig does not begin with OP_0" in {
|
||||
it must "mark a transaction invalid when the NULLDUMMY flag is set for a OP_CHECKMULTISIG operation & the scriptSig does not begin with OP_0" in {
|
||||
val flags = Seq(ScriptVerifyNullDummy)
|
||||
val scriptSig = ScriptSignature.fromAsm(Seq(OP_1))
|
||||
val input = TransactionInput(EmptyTransactionOutPoint, scriptSig, TransactionConstants.sequence)
|
||||
@ -206,6 +170,6 @@ class CryptoInterpreterTest extends FlatSpec with MustMatchers with CryptoInterp
|
||||
val program = ScriptProgram(ScriptProgram(TestUtil.testProgramExecutionInProgress,stack,script),script,ScriptProgram.OriginalScript)
|
||||
val newProgram = ScriptProgramTestUtil.toExecutionInProgressScriptProgram(opCodeSeparator(program))
|
||||
newProgram.lastCodeSeparator must be (Some(0))
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user