mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-24 23:08:31 +01:00
properly generate both spendable and unspendable csv transactions, add factory to CSV/CLTVScriptSignatures
This commit is contained in:
parent
10d4041efb
commit
bb806716cb
7 changed files with 119 additions and 131 deletions
|
@ -376,9 +376,13 @@ object CLTVScriptPubKey extends Factory[CLTVScriptPubKey] {
|
|||
CLTVScriptPubKey(asm)
|
||||
}
|
||||
|
||||
def isCLTVScriptPubKey(asm : Seq[ScriptToken]) : Boolean = asm.slice(0,4) match {
|
||||
case List(lockTimeBytesToPush : BytesToPushOntoStack, lockTime : ScriptConstant, OP_CHECKLOCKTIMEVERIFY, OP_DROP) => true
|
||||
case _ => false
|
||||
def isCLTVScriptPubKey(asm : Seq[ScriptToken]) : Boolean = {
|
||||
val tailTokens = asm.slice(4, asm.length)
|
||||
if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKLOCKTIMEVERIFY)) return false
|
||||
asm.slice(0,4) match {
|
||||
case List(lockTimeBytesToPush : BytesToPushOntoStack, lockTime : ScriptConstant, OP_CHECKLOCKTIMEVERIFY, OP_DROP) => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -429,10 +433,15 @@ object CSVScriptPubKey extends Factory[CSVScriptPubKey] {
|
|||
CSVScriptPubKey(asm)
|
||||
}
|
||||
|
||||
def isCSVScriptPubKey(asm : Seq[ScriptToken]) : Boolean = asm.slice(0,4) match {
|
||||
case List(lockTimeBytesToPush : BytesToPushOntoStack, lockTime : ScriptConstant, OP_CHECKSEQUENCEVERIFY, OP_DROP) => true
|
||||
case _ => false
|
||||
def isCSVScriptPubKey(asm : Seq[ScriptToken]) : Boolean = {
|
||||
val tailTokens = asm.slice(4, asm.length)
|
||||
if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKSEQUENCEVERIFY)) return false
|
||||
asm.slice(0,4) match {
|
||||
case List(lockTimeBytesToPush : BytesToPushOntoStack, lockTime : ScriptConstant, OP_CHECKSEQUENCEVERIFY, OP_DROP) => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sealed trait NonStandardScriptPubKey extends ScriptPubKey
|
||||
|
|
|
@ -416,52 +416,56 @@ object CLTVScriptSignature extends Factory[CLTVScriptSignature] {
|
|||
* of [[ECPublicKey]] needed to satisfy the scriptPubKey. If a [[P2SHScriptPubKey]] is provided, a redeemScript must also be provided.
|
||||
* @return
|
||||
*/
|
||||
def apply(scriptPubKey: ScriptPubKey, sigs : Seq[ECDigitalSignature], pubKeys : Seq[ECPublicKey], redeemScript : Option[ScriptPubKey]) : CLTVScriptSignature = scriptPubKey match {
|
||||
def apply(scriptPubKey: ScriptPubKey, sigs : Seq[ECDigitalSignature], pubKeys : Seq[ECPublicKey]) : CLTVScriptSignature = scriptPubKey match {
|
||||
case p2pkScriptPubKey : P2PKScriptPubKey => CLTVScriptSignature(P2PKScriptSignature(sigs.head))
|
||||
case p2pkhScriptPubKey : P2PKHScriptPubKey => CLTVScriptSignature(P2PKHScriptSignature(sigs.head, pubKeys.head))
|
||||
case multiSigScriptPubKey : MultiSignatureScriptPubKey => CLTVScriptSignature(MultiSignatureScriptSignature(sigs))
|
||||
case cltvScriptPubKey : CLTVScriptPubKey => apply(cltvScriptPubKey.scriptPubKeyAfterCLTV, sigs, pubKeys, redeemScript)
|
||||
case csvScriptPubKey : CSVScriptPubKey => apply(csvScriptPubKey.scriptPubKeyAfterCSV, sigs, pubKeys, redeemScript)
|
||||
case p2shScriptPubKey : P2SHScriptPubKey =>
|
||||
require(redeemScript.isDefined, "If the underlying scriptSig is a P2SHScriptSignature, a redeemScript must be defined.")
|
||||
val cltvScriptSigBeforeRedeemScript = apply(redeemScript.get, sigs, pubKeys, None)
|
||||
CLTVScriptSignature(P2SHScriptSignature(cltvScriptSigBeforeRedeemScript, redeemScript.get))
|
||||
case cltvScriptPubKey : CLTVScriptPubKey => apply(cltvScriptPubKey.scriptPubKeyAfterCLTV, sigs, pubKeys)
|
||||
case csvScriptPubKey : CSVScriptPubKey => apply(csvScriptPubKey.scriptPubKeyAfterCSV, sigs, pubKeys)
|
||||
case EmptyScriptPubKey => CLTVScriptSignature(EmptyScriptSignature)
|
||||
case nonstandard : NonStandardScriptPubKey => throw new IllegalArgumentException("A NonStandardScriptSignature cannot be" +
|
||||
"the underlying scriptSig in a CLTVScriptSignature.")
|
||||
case _ : NonStandardScriptPubKey | _ : P2SHScriptPubKey => throw new IllegalArgumentException("A NonStandardScriptSignature or P2SHScriptSignature cannot be" +
|
||||
"the underlying scriptSig in a CLTVScriptSignature. Got: " + this)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sealed trait CSVScriptSignature extends ScriptSignature {
|
||||
def scriptSig : ScriptSignature
|
||||
def scriptSig : ScriptSignature = ScriptSignature(hex)
|
||||
|
||||
override def signatures : Seq[ECDigitalSignature] = scriptSig.signatures
|
||||
|
||||
override def hex = scriptSig.hex
|
||||
}
|
||||
|
||||
object CSVScriptSignature {
|
||||
private case class CSVScriptSignatureImpl(scriptSig : ScriptSignature) extends CSVScriptSignature
|
||||
object CSVScriptSignature extends Factory[CSVScriptSignature] {
|
||||
private case class CSVScriptSignatureImpl(override val hex : String) extends CSVScriptSignature
|
||||
|
||||
override def fromBytes(bytes : Seq[Byte]) : CSVScriptSignature = {
|
||||
val hex = BitcoinSUtil.encodeHex(bytes)
|
||||
fromHex(hex)
|
||||
}
|
||||
|
||||
override def fromHex(hex : String) : CSVScriptSignature = {
|
||||
CSVScriptSignatureImpl(hex)
|
||||
}
|
||||
|
||||
def apply(scriptSig : ScriptSignature) : CSVScriptSignature = {
|
||||
fromHex(scriptSig.hex)
|
||||
}
|
||||
/**
|
||||
* Creates a CSVScriptSignature out the [[ScriptPubKey]] we are satisfying, a sequence of [[ECDigitalSignature]], and a sequence
|
||||
* of [[ECPublicKey]] needed to satisfy the scriptPubKey. If a [[P2SHScriptPubKey]] is provided, a redeemScript must also be provided.
|
||||
* @return
|
||||
*/
|
||||
def apply(scriptPubKey: ScriptPubKey, sigs : Seq[ECDigitalSignature], pubKeys : Seq[ECPublicKey], redeemScript : Option[ScriptPubKey]) : CSVScriptSignature = scriptPubKey match {
|
||||
case p2pkScriptPubKey : P2PKScriptPubKey => CSVScriptSignatureImpl(P2PKScriptSignature(sigs.head))
|
||||
case p2pkhScriptPubKey : P2PKHScriptPubKey => CSVScriptSignatureImpl(P2PKHScriptSignature(sigs.head, pubKeys.head))
|
||||
case multiSigScriptPubKey : MultiSignatureScriptPubKey => CSVScriptSignatureImpl(MultiSignatureScriptSignature(sigs))
|
||||
case cltvScriptPubKey : CLTVScriptPubKey => apply(cltvScriptPubKey.scriptPubKeyAfterCLTV, sigs, pubKeys, redeemScript)
|
||||
case csvScriptPubKey : CSVScriptPubKey => apply(csvScriptPubKey.scriptPubKeyAfterCSV, sigs, pubKeys, redeemScript)
|
||||
case p2shScriptPubKey : P2SHScriptPubKey =>
|
||||
require(redeemScript.isDefined, "If the underlying scriptSig is a P2SHScriptSignature, a redeemScript must be defined.")
|
||||
val csvScriptSigBeforeRedeemScript = apply(redeemScript.get, sigs, pubKeys, None)
|
||||
CSVScriptSignatureImpl(P2SHScriptSignature(csvScriptSigBeforeRedeemScript, redeemScript.get))
|
||||
case EmptyScriptPubKey => CSVScriptSignatureImpl(EmptyScriptSignature)
|
||||
case nonstandard : NonStandardScriptPubKey => throw new IllegalArgumentException("A NonStandardScriptSignature cannot be" +
|
||||
"the underlying scriptSig in a CSVScriptSignature.")
|
||||
def apply(scriptPubKey: ScriptPubKey, sigs : Seq[ECDigitalSignature], pubKeys : Seq[ECPublicKey]) : CSVScriptSignature = scriptPubKey match {
|
||||
case p2pkScriptPubKey : P2PKScriptPubKey => CSVScriptSignature(P2PKScriptSignature(sigs.head))
|
||||
case p2pkhScriptPubKey : P2PKHScriptPubKey => CSVScriptSignature(P2PKHScriptSignature(sigs.head, pubKeys.head))
|
||||
case multiSigScriptPubKey : MultiSignatureScriptPubKey => CSVScriptSignature(MultiSignatureScriptSignature(sigs))
|
||||
case cltvScriptPubKey : CLTVScriptPubKey => apply(cltvScriptPubKey.scriptPubKeyAfterCLTV, sigs, pubKeys)
|
||||
case csvScriptPubKey : CSVScriptPubKey => apply(csvScriptPubKey.scriptPubKeyAfterCSV, sigs, pubKeys)
|
||||
case EmptyScriptPubKey => CSVScriptSignature(EmptyScriptSignature)
|
||||
case _ : NonStandardScriptPubKey | _ : P2SHScriptPubKey => throw new IllegalArgumentException("A NonStandardScriptSignature or P2SHScriptSignature cannot be" +
|
||||
"the underlying scriptSig in a CSVScriptSignature. Got: " + this)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ trait LockTimeInterpreter extends BitcoinSLogger {
|
|||
*/
|
||||
@tailrec
|
||||
final def opCheckLockTimeVerify(program : ScriptProgram) : ScriptProgram = {
|
||||
logger.warn("+_+_+_+_!+_+_!!!!+_+_+_+_!+_+_!!!!+_+_+_+_!+_+_!!!!+_+_+_+_!+_+_!!!!+_+_+_+_!+_+_!!!!+_+_+_+_!+_+_!!!!+_+_+_+_!+_+_!!!!+_+_+_+_!+_+_!!!!")
|
||||
require(program.script.headOption.isDefined && program.script.head == OP_CHECKLOCKTIMEVERIFY,
|
||||
"Script top must be OP_CHECKLOCKTIMEVERIFY")
|
||||
val input = program.txSignatureComponent.transaction.inputs(program.txSignatureComponent.inputIndex.toInt)
|
||||
|
@ -176,7 +175,7 @@ trait LockTimeInterpreter extends BitcoinSLogger {
|
|||
(txToSequenceMasked >= Int64(TransactionConstants.sequenceLockTimeTypeFlag.underlying) &&
|
||||
nSequenceMasked >= Int64(TransactionConstants.sequenceLockTimeTypeFlag.underlying))
|
||||
)) {
|
||||
logger.error("The nSequence mask is not the same as it was in the transaction")
|
||||
logger.error("The txSequence and nSequence (OP_CSV value) are not of the same type (timestamp/block-height).")
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -216,7 +215,6 @@ trait LockTimeInterpreter extends BitcoinSLogger {
|
|||
|
||||
// Now that we know we're comparing apples-to-apples, the
|
||||
// comparison is a simple numeric one.
|
||||
println("cltvLocktime: " + locktime + " and txLocktime: " + transaction.lockTime)
|
||||
if (locktime > Int64(transaction.lockTime.underlying)) return false
|
||||
|
||||
// Finally the nLockTime feature can be disabled and thus
|
||||
|
@ -231,10 +229,7 @@ trait LockTimeInterpreter extends BitcoinSLogger {
|
|||
// required to prove correct CHECKLOCKTIMEVERIFY execution.
|
||||
if (input.sequence == TransactionConstants.sequence) {
|
||||
false
|
||||
} else {
|
||||
println("it passed")
|
||||
true
|
||||
}
|
||||
} else true
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.bitcoins.core.crypto
|
||||
|
||||
import org.bitcoins.core.gen.TransactionGenerators
|
||||
import org.bitcoins.core.number.Int64
|
||||
import org.bitcoins.core.protocol.script.{CLTVScriptPubKey, P2SHScriptPubKey}
|
||||
import org.bitcoins.core.script.interpreter.ScriptInterpreter
|
||||
import org.bitcoins.core.script.result.{ScriptErrorUnsatisfiedLocktime, ScriptErrorPushSize, ScriptOk}
|
||||
|
@ -12,59 +13,58 @@ 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") =
|
||||
// Prop.forAll(TransactionGenerators.signedP2PKTransaction) {
|
||||
// case (txSignatureComponent: TransactionSignatureComponent, _) =>
|
||||
// //run it through the interpreter
|
||||
// val program: PreExecutionScriptProgram = ScriptProgram(txSignatureComponent)
|
||||
// val result = ScriptInterpreter.run(program)
|
||||
// result == ScriptOk
|
||||
// }
|
||||
//
|
||||
// property("generate a valid signature for a p2pkh transaction") =
|
||||
// Prop.forAll(TransactionGenerators.signedP2PKHTransaction) {
|
||||
// case (txSignatureComponent: TransactionSignatureComponent, _) =>
|
||||
// //run it through the interpreter
|
||||
// val program = ScriptProgram(txSignatureComponent)
|
||||
// val result = ScriptInterpreter.run(program)
|
||||
// result == ScriptOk
|
||||
// }
|
||||
//
|
||||
// property("generate valid signatures for a multisignature transaction") =
|
||||
// Prop.forAllNoShrink(TransactionGenerators.signedMultiSigTransaction) {
|
||||
// case (txSignatureComponent: TransactionSignatureComponent, _) =>
|
||||
// //run it through the interpreter
|
||||
// val program = ScriptProgram(txSignatureComponent)
|
||||
//
|
||||
// val result = ScriptInterpreter.run(program)
|
||||
//
|
||||
// result == ScriptOk
|
||||
// }
|
||||
//
|
||||
// property("generate a valid signature for a p2sh transaction") =
|
||||
// Prop.forAll(TransactionGenerators.signedP2SHTransaction) {
|
||||
// case (txSignatureComponent: TransactionSignatureComponent, _) =>
|
||||
// //run it through the interpreter
|
||||
// val program = ScriptProgram(txSignatureComponent)
|
||||
// val result = ScriptInterpreter.run(program)
|
||||
// //can be ScriptErrorPushSize if the redeemScript is larger than 520 bytes
|
||||
// Seq(ScriptOk, ScriptErrorPushSize).contains(result)
|
||||
// }
|
||||
//
|
||||
// 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
|
||||
// require(txSignatureComponent.transaction.lockTime.underlying >= scriptNumber.underlying, "TxLocktime must be satisifed so it should be greater than or equal to " +
|
||||
// "the cltv value. Got TxLockTime : " + txSignatureComponent.transaction.lockTime.underlying + " , and cltv Value: " +
|
||||
// scriptNumber.underlying)
|
||||
// val program = ScriptProgram(txSignatureComponent)
|
||||
// val result = ScriptInterpreter.run(program)
|
||||
// val cltv = CLTVScriptPubKey(txSignatureComponent.scriptPubKey.hex)
|
||||
// if (cltv.scriptPubKeyAfterCLTV.isInstanceOf[P2SHScriptPubKey]) Seq(ScriptOk, ScriptErrorPushSize).contains(result)
|
||||
// else Seq(ScriptOk).contains(result)
|
||||
// }
|
||||
//
|
||||
property("Must generate a valid signature for a p2pk transaction") =
|
||||
Prop.forAll(TransactionGenerators.signedP2PKTransaction) {
|
||||
case (txSignatureComponent: TransactionSignatureComponent, _) =>
|
||||
//run it through the interpreter
|
||||
val program: PreExecutionScriptProgram = ScriptProgram(txSignatureComponent)
|
||||
val result = ScriptInterpreter.run(program)
|
||||
result == ScriptOk
|
||||
}
|
||||
|
||||
property("generate a valid signature for a p2pkh transaction") =
|
||||
Prop.forAll(TransactionGenerators.signedP2PKHTransaction) {
|
||||
case (txSignatureComponent: TransactionSignatureComponent, _) =>
|
||||
//run it through the interpreter
|
||||
val program = ScriptProgram(txSignatureComponent)
|
||||
val result = ScriptInterpreter.run(program)
|
||||
result == ScriptOk
|
||||
}
|
||||
|
||||
property("generate valid signatures for a multisignature transaction") =
|
||||
Prop.forAllNoShrink(TransactionGenerators.signedMultiSigTransaction) {
|
||||
case (txSignatureComponent: TransactionSignatureComponent, _) =>
|
||||
//run it through the interpreter
|
||||
val program = ScriptProgram(txSignatureComponent)
|
||||
|
||||
val result = ScriptInterpreter.run(program)
|
||||
|
||||
result == ScriptOk
|
||||
}
|
||||
|
||||
property("generate a valid signature for a p2sh transaction") =
|
||||
Prop.forAll(TransactionGenerators.signedP2SHTransaction) {
|
||||
case (txSignatureComponent: TransactionSignatureComponent, _) =>
|
||||
//run it through the interpreter
|
||||
val program = ScriptProgram(txSignatureComponent)
|
||||
val result = ScriptInterpreter.run(program)
|
||||
//can be ScriptErrorPushSize if the redeemScript is larger than 520 bytes
|
||||
Seq(ScriptOk, ScriptErrorPushSize).contains(result)
|
||||
}
|
||||
|
||||
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
|
||||
require(txSignatureComponent.transaction.lockTime.underlying >= scriptNumber.underlying, "TxLocktime must be satisifed so it should be greater than or equal to " +
|
||||
"the cltv value. Got TxLockTime : " + txSignatureComponent.transaction.lockTime.underlying + " , and cltv Value: " +
|
||||
scriptNumber.underlying)
|
||||
val program = ScriptProgram(txSignatureComponent)
|
||||
val result = ScriptInterpreter.run(program)
|
||||
val cltv = CLTVScriptPubKey(txSignatureComponent.scriptPubKey.hex)
|
||||
Seq(ScriptOk).contains(result)
|
||||
}
|
||||
|
||||
property("generate a valid signature for a validly constructed, but NOT spendable cltv transaction") =
|
||||
Prop.forAllNoShrink(TransactionGenerators.unspendableCLTVTransaction :| "cltv_unspendable") {
|
||||
case (txSignatureComponent: TransactionSignatureComponent, _, scriptNumber) =>
|
||||
|
@ -75,16 +75,25 @@ class TransactionSignatureCreatorSpec extends Properties("TransactionSignatureCr
|
|||
val program = ScriptProgram(txSignatureComponent)
|
||||
val result = ScriptInterpreter.run(program)
|
||||
val cltv = CLTVScriptPubKey(txSignatureComponent.scriptPubKey.hex)
|
||||
println("result: " + result)
|
||||
Seq(ScriptErrorUnsatisfiedLocktime, ScriptErrorPushSize).contains(result)
|
||||
}
|
||||
//
|
||||
// property("generate a valid signature for a valid and spendable csv transaction") =
|
||||
// Prop.forAllNoShrink(TransactionGenerators.spendableCSVTransaction :| "csv") {
|
||||
// case (txSignatureComponent: TransactionSignatureComponent, keys, scriptNumber, sequence) =>
|
||||
// //run it through the interpreter
|
||||
// val program = ScriptProgram(txSignatureComponent)
|
||||
// val result = ScriptInterpreter.run(program)
|
||||
// Seq(ScriptOk, ScriptErrorPushSize).contains(result)
|
||||
// }
|
||||
|
||||
property("generate a valid signature for a valid and spendable csv transaction") =
|
||||
Prop.forAllNoShrink(TransactionGenerators.spendableCSVTransaction :| "spendable csv") {
|
||||
case (txSignatureComponent: TransactionSignatureComponent, keys, scriptNumber, sequence) =>
|
||||
//run it through the interpreter
|
||||
val program = ScriptProgram(txSignatureComponent)
|
||||
val result = ScriptInterpreter.run(program)
|
||||
Seq(ScriptOk, ScriptErrorPushSize).contains(result)
|
||||
}
|
||||
|
||||
property("generate a valid signature for a validly constructed but unspendable csv transaction") =
|
||||
Prop.forAllNoShrink(TransactionGenerators.unspendableCSVTransaction :| "unspendable csv") {
|
||||
case (txSignatureComponent: TransactionSignatureComponent, keys, scriptNumber, sequence) =>
|
||||
//run it through the interpreter
|
||||
val program = ScriptProgram(txSignatureComponent)
|
||||
val result = ScriptInterpreter.run(program)
|
||||
Seq(ScriptErrorUnsatisfiedLocktime, ScriptErrorPushSize).contains(result)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,17 +15,4 @@ class CLTVScriptPubKeySpec extends Properties("CLTVScriptPubKeySpec") with Bitco
|
|||
Prop.forAll(ScriptGenerators.cltvScriptPubKey) { case (cltvScriptPubKey, _) =>
|
||||
CLTVScriptPubKey(cltvScriptPubKey.hex) == cltvScriptPubKey
|
||||
}
|
||||
property("a valid unspendable CLTV Transaction's locktime must be less than the script's CLTV value ") =
|
||||
Prop.forAll(TransactionGenerators.unspendableCLTVTransaction) { txSigComponent =>
|
||||
val locktime = txSigComponent._1.transaction.lockTime.underlying
|
||||
val cltvScriptValue = txSigComponent._3.underlying
|
||||
locktime < cltvScriptValue
|
||||
}
|
||||
|
||||
property("a valid spendable CLTV Transaction's locktime must be greater than the script's CLTV value ") =
|
||||
Prop.forAll(TransactionGenerators.spendableCLTVTransaction) { txSigComponent =>
|
||||
val locktime = txSigComponent._1.transaction.lockTime.underlying
|
||||
val cltvScriptValue = txSigComponent._3.underlying
|
||||
locktime > cltvScriptValue
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,6 +122,6 @@ class ScriptSignatureTest extends FlatSpec with MustMatchers {
|
|||
val cltvScriptPubKey = CLTVScriptPubKey("04e71bbe57b17576a914da88dc82530f0a4d1327dcfe75cc60c44277532c88ac")
|
||||
val pubKey = ECPublicKey("039ba48e162b1f47246f4ce9dc40f197fab7bde11da1b2fe9ac21113959e9f381b")
|
||||
val sig = ECDigitalSignature("3045022100d71cfe32fa4545c5a0fd665b3701eb458a1bacbba868a05fa703fd1fa4b4f5c502204ee706334f976d0bee9b0f0ff919c1dfe9ba027993bf3e39fc03416ba4255b2401")
|
||||
CLTVScriptSignature(cltvScriptPubKey, Seq(sig), Seq(pubKey), None).scriptSig.isInstanceOf[P2PKHScriptSignature]
|
||||
CLTVScriptSignature(cltvScriptPubKey, Seq(sig), Seq(pubKey)).scriptSig.isInstanceOf[P2PKHScriptSignature]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import scala.io.Source
|
|||
* Created by chris on 1/6/16.
|
||||
*/
|
||||
class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterpreter with BitcoinSLogger {
|
||||
/*
|
||||
|
||||
"ScriptInterpreter" must "evaluate all the scripts from the bitcoin core script_tests.json" in {
|
||||
|
||||
|
@ -61,19 +60,4 @@ class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterp
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
it must "fail CLTVScriptPubKey with nested P2SHScriptPubKey" in {
|
||||
val privKey = ECPrivateKey("8fe79310a9a5400daf4f9690187db1607c668fca9f63a530d67cc7472c9de589")
|
||||
val cltv = CLTVScriptPubKey("010ab175a914c280ffb6c00e2d8b333d84746dc38a807081590287")
|
||||
val p2shScriptSig = P2SHScriptSignature("483045022100d817fbc5a5d71f0859b811c01e251a20ab897c2b07b96149340336183e80d1" +
|
||||
"9e022065e20731db313b31c45b208919a8606f90d390620b65a71085d185618b6742bc0123210338a011f3d144d4af991b27d13bcac38ef312835e64a0971c7f5404e1252a332eac")
|
||||
val cltvScriptSignature = CLTVScriptSignature(p2shScriptSig)
|
||||
val redeemScript = p2shScriptSig.redeemScript
|
||||
val (creditingTx, outputIndex) = TransactionGenerators.buildCreditingTransaction(cltv)
|
||||
val (spendingTx, inputIndex) = TransactionGenerators.buildSpendingTransaction(UInt32.one, creditingTx, cltvScriptSignature, outputIndex, UInt32(5), UInt32.zero)
|
||||
val txSigComp = TransactionSignatureComponent(spendingTx, inputIndex, redeemScript, Policy.standardScriptVerifyFlags)
|
||||
ScriptInterpreter.run(ScriptProgram(txSigComp)) must be (ScriptErrorUnsatisfiedLocktime)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue