mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-25 07:17:32 +01:00
Fixing issue where we have the wrong version of ScriptSignature in our tree
This commit is contained in:
parent
40929aa5bf
commit
81f2cf3ba2
1 changed files with 180 additions and 200 deletions
|
@ -6,6 +6,7 @@ import org.bitcoins.core.serializers.script.{RawScriptPubKeyParser, RawScriptSig
|
|||
import org.bitcoins.core.script.constant._
|
||||
import org.bitcoins.core.script.crypto.{HashType, HashTypeFactory, OP_CHECKMULTISIG, SIGHASH_ALL}
|
||||
import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil, BitcoinScriptUtil, Factory}
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
import scala.util.{Failure, Success, Try}
|
||||
|
||||
|
@ -15,50 +16,44 @@ import scala.util.{Failure, Success, Try}
|
|||
*/
|
||||
sealed trait ScriptSignature extends NetworkElement with BitcoinSLogger {
|
||||
|
||||
/**
|
||||
* Representation of a scriptSignature in a parsed assembly format
|
||||
* this data structure can be run through the script interpreter to
|
||||
* see if a script evaluates to true
|
||||
* @return
|
||||
*/
|
||||
def asm : Seq[ScriptToken]
|
||||
|
||||
/**
|
||||
* The digital signatures contained inside of the script signature
|
||||
* p2pkh script signatures only have one sig
|
||||
* p2pk script signatures only have one sigs
|
||||
* p2sh script signatures can have m sigs
|
||||
* multisignature scripts can have m sigs
|
||||
* @return
|
||||
*/
|
||||
* Representation of a scriptSignature in a parsed assembly format
|
||||
* this data structure can be run through the script interpreter to
|
||||
* see if a script evaluates to true
|
||||
* @return
|
||||
*/
|
||||
lazy val asm : Seq[ScriptToken] = ScriptParser.fromHex(hex)
|
||||
|
||||
|
||||
/**
|
||||
* The digital signatures contained inside of the script signature
|
||||
* p2pkh script signatures only have one sig
|
||||
* p2pk script signatures only have one sigs
|
||||
* p2sh script signatures can have m sigs
|
||||
* multisignature scripts can have m sigs
|
||||
* @return
|
||||
*/
|
||||
def signatures : Seq[ECDigitalSignature]
|
||||
|
||||
|
||||
/**
|
||||
* Derives the hash type for a given digitalSignature
|
||||
*
|
||||
* Derives the hash type for a given digitalSignature
|
||||
* @param digitalSignature
|
||||
* @return
|
||||
*/
|
||||
* @return
|
||||
*/
|
||||
def hashType(digitalSignature: ECDigitalSignature) = {
|
||||
digitalSignature match {
|
||||
case EmptyDigitalSignature => SIGHASH_ALL()
|
||||
case sig : ECDigitalSignature => HashTypeFactory.fromByte(digitalSignature.bytes.last)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait NonStandardScriptSignature extends ScriptSignature {
|
||||
def signatures : Seq[ECDigitalSignature] = ???
|
||||
def signatures : Seq[ECDigitalSignature] = Seq()
|
||||
}
|
||||
|
||||
object NonStandardScriptSignatureImpl {
|
||||
def apply(hex : String) : NonStandardScriptSignatureImpl = NonStandardScriptSignatureImpl(hex, RawScriptSignatureParser.read(hex).asm)
|
||||
}
|
||||
case class NonStandardScriptSignatureImpl(hex : String, asm : Seq[ScriptToken]) extends NonStandardScriptSignature
|
||||
|
||||
|
||||
/**
|
||||
|
@ -71,24 +66,22 @@ trait P2PKHScriptSignature extends ScriptSignature {
|
|||
|
||||
|
||||
/**
|
||||
* P2PKH scriptSigs only have one signature
|
||||
*
|
||||
* P2PKH scriptSigs only have one signature
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def signature : ECDigitalSignature = signatures.head
|
||||
|
||||
|
||||
/**
|
||||
* Gives us the public key inside of a p2pkh script signature
|
||||
*
|
||||
* Gives us the public key inside of a p2pkh script signature
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def publicKey : ECPublicKey = ECFactory.publicKey(asm.last.bytes)
|
||||
|
||||
/**
|
||||
* Returns the hash type for the p2pkh script signature
|
||||
*
|
||||
* Returns the hash type for the p2pkh script signature
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def hashType : HashType = HashTypeFactory.fromByte(signature.bytes.last)
|
||||
|
||||
override def signatures : Seq[ECDigitalSignature] = {
|
||||
|
@ -104,37 +97,36 @@ trait P2PKHScriptSignature extends ScriptSignature {
|
|||
* <sig> [sig] [sig...] <redeemScript>
|
||||
*/
|
||||
trait P2SHScriptSignature extends ScriptSignature {
|
||||
|
||||
/**
|
||||
* The redeemScript represents the conditions that must be satisfied to spend the output
|
||||
*
|
||||
* The redeemScript represents the conditions that must be satisfied to spend the output
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def redeemScript : ScriptPubKey = ScriptPubKey(asm.last.bytes)
|
||||
|
||||
|
||||
/**
|
||||
* Returns the script signature of this p2shScriptSig with no serialized redeemScript
|
||||
*
|
||||
* Returns the script signature of this p2shScriptSig with no serialized redeemScript
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def scriptSignatureNoRedeemScript = ScriptSignature.fromAsm(splitAtRedeemScript(asm)._1)
|
||||
|
||||
|
||||
/**
|
||||
* Returns the public keys for the p2sh scriptSignature
|
||||
*
|
||||
* Returns the public keys for the p2sh scriptSignature
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def publicKeys : Seq[ECPublicKey] = {
|
||||
val pubKeys : Seq[ScriptToken] = redeemScript.asm.filter(_.isInstanceOf[ScriptConstant])
|
||||
.filterNot(_.isInstanceOf[ScriptNumberOperation])
|
||||
pubKeys.map(k => ECFactory.publicKey(k.hex))
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The digital signatures inside of the scriptSig
|
||||
*
|
||||
* The digital signatures inside of the scriptSig
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def signatures : Seq[ECDigitalSignature] = {
|
||||
val nonRedeemScript = splitAtRedeemScript(asm)._1
|
||||
val sigs = nonRedeemScript.filter(_.isInstanceOf[ScriptConstant]).filterNot(_.isInstanceOf[ScriptNumberOperation])
|
||||
|
@ -143,13 +135,12 @@ trait P2SHScriptSignature extends ScriptSignature {
|
|||
|
||||
|
||||
/**
|
||||
* Splits the given asm into two parts
|
||||
* the first part is the digital signatures
|
||||
* the second part is the redeem script
|
||||
*
|
||||
* Splits the given asm into two parts
|
||||
* the first part is the digital signatures
|
||||
* the second part is the redeem script
|
||||
* @param asm
|
||||
* @return
|
||||
*/
|
||||
* @return
|
||||
*/
|
||||
def splitAtRedeemScript(asm : Seq[ScriptToken]) : (Seq[ScriptToken],Seq[ScriptToken]) = {
|
||||
//call .tail twice to remove the serialized redeemScript & it's bytesToPushOntoStack constant
|
||||
(asm.reverse.tail.tail.reverse, Seq(asm.last))
|
||||
|
@ -181,191 +172,180 @@ trait MultiSignatureScriptSignature extends ScriptSignature {
|
|||
* Signature script: <sig>
|
||||
*/
|
||||
trait P2PKScriptSignature extends ScriptSignature {
|
||||
|
||||
/**
|
||||
* Returns the hash type for the signature inside of the p2pk script signature
|
||||
*
|
||||
* Returns the hash type for the signature inside of the p2pk script signature
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def hashType = HashTypeFactory.fromByte(signature.bytes.last)
|
||||
|
||||
/**
|
||||
* PubKey scriptSignatures only have one signature
|
||||
*
|
||||
* PubKey scriptSignatures only have one signature
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def signature : ECDigitalSignature = signatures.head
|
||||
|
||||
/**
|
||||
* The digital signatures inside of the scriptSig
|
||||
*
|
||||
* The digital signatures inside of the scriptSig
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
def signatures : Seq[ECDigitalSignature] = {
|
||||
Seq(ECFactory.digitalSignature(BitcoinScriptUtil.filterPushOps(asm).head.hex))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Represents the empty script signature
|
||||
*/
|
||||
case object EmptyScriptSignature extends ScriptSignature {
|
||||
def asm = List()
|
||||
def signatures = List()
|
||||
def hex = ""
|
||||
}
|
||||
|
||||
object ScriptSignature extends Factory[ScriptSignature] with BitcoinSLogger {
|
||||
|
||||
private object P2PKHScriptSignatureImpl {
|
||||
def apply(hex : String) : P2PKHScriptSignatureImpl = P2PKHScriptSignatureImpl(hex, RawScriptSignatureParser.read(hex).asm)
|
||||
}
|
||||
private case class P2PKHScriptSignatureImpl(hex : String, asm : Seq[ScriptToken]) extends P2PKHScriptSignature
|
||||
private case class NonStandardScriptSignatureImpl(hex : String) extends NonStandardScriptSignature
|
||||
|
||||
private object P2SHScriptSignatureImpl {
|
||||
def apply(hex : String) : P2SHScriptSignatureImpl = P2SHScriptSignatureImpl(hex, RawScriptSignatureParser.read(hex).asm)
|
||||
}
|
||||
private case class P2SHScriptSignatureImpl(hex : String, asm : Seq[ScriptToken]) extends P2SHScriptSignature
|
||||
private case class P2PKScriptSignatureImpl(hex : String) extends P2PKScriptSignature
|
||||
|
||||
private object MultiSignatureScriptSignatureImpl {
|
||||
def apply(hex : String) : MultiSignatureScriptSignatureImpl = MultiSignatureScriptSignatureImpl(hex, RawScriptSignatureParser.read(hex).asm)
|
||||
}
|
||||
private case class MultiSignatureScriptSignatureImpl(hex : String, asm : Seq[ScriptToken]) extends MultiSignatureScriptSignature
|
||||
private case class MultiSignatureScriptSignatureImpl(hex : String) extends MultiSignatureScriptSignature
|
||||
|
||||
private object P2PKScriptSignatureImpl {
|
||||
def apply(hex : String) : P2PKScriptSignatureImpl = P2PKScriptSignatureImpl(hex, RawScriptSignatureParser.read(hex).asm)
|
||||
}
|
||||
private case class P2PKScriptSignatureImpl(hex : String, asm : Seq[ScriptToken]) extends P2PKScriptSignature
|
||||
private case class P2SHScriptSignatureImpl(hex : String) extends P2SHScriptSignature
|
||||
|
||||
private case class P2PKHScriptSignatureImpl(hex : String) extends P2PKHScriptSignature
|
||||
|
||||
/**
|
||||
* Builds a script signature from a digital signature and a public key
|
||||
* this is a pay to public key hash script sig
|
||||
*
|
||||
* @param signature
|
||||
* @param pubKey
|
||||
* @return
|
||||
*/
|
||||
def factory(signature : ECDigitalSignature, pubKey : ECPublicKey) : ScriptSignature = {
|
||||
val signatureBytesToPushOntoStack = BytesToPushOntoStack(signature.bytes.size)
|
||||
val pubKeyBytesToPushOntoStack = BytesToPushOntoStack(pubKey.bytes.size)
|
||||
val asm : Seq[ScriptToken] = Seq(signatureBytesToPushOntoStack, ScriptConstant(signature.hex),
|
||||
pubKeyBytesToPushOntoStack, ScriptConstant(pubKey.hex))
|
||||
fromAsm(asm)
|
||||
* Builds a script signature from a digital signature and a public key
|
||||
* this is a pay to public key hash script sig
|
||||
*
|
||||
* @param signature
|
||||
* @param pubKey
|
||||
* @return
|
||||
*/
|
||||
def factory(signature : ECDigitalSignature, pubKey : ECPublicKey) : ScriptSignature = {
|
||||
val signatureBytesToPushOntoStack = BytesToPushOntoStack(signature.bytes.size)
|
||||
val pubKeyBytesToPushOntoStack = BytesToPushOntoStack(pubKey.bytes.size)
|
||||
val asm : Seq[ScriptToken] = Seq(signatureBytesToPushOntoStack, ScriptConstant(signature.hex),
|
||||
pubKeyBytesToPushOntoStack, ScriptConstant(pubKey.hex))
|
||||
fromAsm(asm)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty script signature
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def empty : ScriptSignature = EmptyScriptSignature
|
||||
|
||||
def fromBytes(bytes : Seq[Byte]) : ScriptSignature = RawScriptSignatureParser.read(bytes)
|
||||
|
||||
/**
|
||||
* Creates a scriptSignature from the list of script tokens
|
||||
*
|
||||
* @param tokens
|
||||
* @return
|
||||
*/
|
||||
def fromAsm(tokens : Seq[ScriptToken]) : ScriptSignature = {
|
||||
val scriptSigHex = tokens.map(_.hex).mkString
|
||||
tokens match {
|
||||
case Nil => EmptyScriptSignature
|
||||
case _ if (tokens.size > 1 && isRedeemScript(tokens.last)) =>
|
||||
P2SHScriptSignatureImpl(scriptSigHex)
|
||||
case _ if (isMultiSignatureScriptSignature(tokens)) =>
|
||||
//the head of the asm does not neccessarily have to be an OP_0 if the NULLDUMMY script
|
||||
//flag is not set. It can be any script number operation
|
||||
MultiSignatureScriptSignatureImpl(scriptSigHex)
|
||||
case List(w : BytesToPushOntoStack, x : ScriptConstant, y : BytesToPushOntoStack,
|
||||
z : ScriptConstant) => P2PKHScriptSignatureImpl(scriptSigHex)
|
||||
case List(w : BytesToPushOntoStack, x : ScriptConstant) => P2PKScriptSignatureImpl(scriptSigHex)
|
||||
case _ => NonStandardScriptSignatureImpl(scriptSigHex)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty script signature
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def empty : ScriptSignature = EmptyScriptSignature
|
||||
|
||||
def fromBytes(bytes : Seq[Byte]) : ScriptSignature = {
|
||||
RawScriptSignatureParser.read(bytes)
|
||||
/**
|
||||
* Creates a script signature from the given tokens and scriptPubKey
|
||||
*
|
||||
* @param tokens the script signature's tokens
|
||||
* @param scriptPubKey the scriptPubKey which the script signature is trying to spend
|
||||
* @return
|
||||
*/
|
||||
def fromScriptPubKey(tokens : Seq[ScriptToken], scriptPubKey : ScriptPubKey) : ScriptSignature = {
|
||||
val scriptSigHex = tokens.map(_.hex).mkString
|
||||
scriptPubKey match {
|
||||
case s : P2SHScriptPubKey => P2SHScriptSignatureImpl(scriptSigHex)
|
||||
case s : P2PKHScriptPubKey => P2PKHScriptSignatureImpl(scriptSigHex)
|
||||
case s : P2PKScriptPubKey => P2PKScriptSignatureImpl(scriptSigHex)
|
||||
case s : MultiSignatureScriptPubKey => MultiSignatureScriptSignatureImpl(scriptSigHex)
|
||||
case s : NonStandardScriptPubKey => NonStandardScriptSignatureImpl(scriptSigHex)
|
||||
case EmptyScriptPubKey if (tokens.size == 0) => EmptyScriptSignature
|
||||
case EmptyScriptPubKey => NonStandardScriptSignatureImpl(scriptSigHex)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a scriptSignature from the list of script tokens
|
||||
*
|
||||
* @param tokens
|
||||
* @return
|
||||
*/
|
||||
def fromAsm(tokens : Seq[ScriptToken]) : ScriptSignature = {
|
||||
val scriptSigHex = tokens.map(_.hex).mkString
|
||||
tokens match {
|
||||
case Nil => EmptyScriptSignature
|
||||
case _ if (tokens.size > 1 && isRedeemScript(tokens.last)) =>
|
||||
P2SHScriptSignatureImpl(scriptSigHex,tokens)
|
||||
case _ if (isMultiSignatureScriptSignature(tokens)) =>
|
||||
//the head of the asm does not neccessarily have to be an OP_0 if the NULLDUMMY script
|
||||
//flag is not set. It can be any script number operation
|
||||
MultiSignatureScriptSignatureImpl(scriptSigHex,tokens)
|
||||
case List(w : BytesToPushOntoStack, x : ScriptConstant, y : BytesToPushOntoStack,
|
||||
z : ScriptConstant) => P2PKHScriptSignatureImpl(scriptSigHex,tokens)
|
||||
case List(w : BytesToPushOntoStack, x : ScriptConstant) => P2PKScriptSignatureImpl(scriptSigHex,tokens)
|
||||
case _ => NonStandardScriptSignatureImpl(scriptSigHex,tokens)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects if the given script token is a redeem script
|
||||
*
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
private def isRedeemScript(token : ScriptToken) : Boolean = {
|
||||
logger.debug("Checking if last token is redeem script")
|
||||
val redeemScriptTry : Try[ScriptPubKey] = parseRedeemScript(token)
|
||||
redeemScriptTry match {
|
||||
case Success(redeemScript) =>
|
||||
logger.debug("Possible redeemScript: " + redeemScript)
|
||||
redeemScript match {
|
||||
case x : P2PKHScriptPubKey => true
|
||||
case x : MultiSignatureScriptPubKey => true
|
||||
case x : P2SHScriptPubKey => true
|
||||
case x : P2PKScriptPubKey => true
|
||||
case x : NonStandardScriptPubKey => false
|
||||
case EmptyScriptPubKey => false
|
||||
}
|
||||
case Failure(_) => false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a redeem script from the given script token
|
||||
*
|
||||
* @param scriptToken
|
||||
* @return
|
||||
*/
|
||||
def parseRedeemScript(scriptToken : ScriptToken) : Try[ScriptPubKey] = {
|
||||
val redeemScript : Try[ScriptPubKey] = Try(ScriptPubKey(scriptToken.bytes))
|
||||
redeemScript
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a script signature from the given tokens and scriptPubKey
|
||||
*
|
||||
* @param tokens the script signature's tokens
|
||||
* @param scriptPubKey the scriptPubKey which the script signature is trying to spend
|
||||
* @return
|
||||
*/
|
||||
def fromScriptPubKey(tokens : Seq[ScriptToken], scriptPubKey : ScriptPubKey) : ScriptSignature = {
|
||||
val scriptSigHex = tokens.map(_.hex).mkString
|
||||
scriptPubKey match {
|
||||
case s : P2SHScriptPubKey => P2SHScriptSignatureImpl(scriptSigHex,tokens)
|
||||
case s : P2PKHScriptPubKey => P2PKHScriptSignatureImpl(scriptSigHex,tokens)
|
||||
case s : P2PKScriptPubKey => P2PKScriptSignatureImpl(scriptSigHex,tokens)
|
||||
case s : MultiSignatureScriptPubKey => MultiSignatureScriptSignatureImpl(scriptSigHex,tokens)
|
||||
case s : NonStandardScriptPubKey => NonStandardScriptSignatureImpl(scriptSigHex, tokens)
|
||||
case EmptyScriptPubKey if (tokens.size == 0) => EmptyScriptSignature
|
||||
case EmptyScriptPubKey => NonStandardScriptSignatureImpl(scriptSigHex,tokens)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Detects if the given script token is a redeem script
|
||||
*
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
private def isRedeemScript(token : ScriptToken) : Boolean = {
|
||||
logger.debug("Checking if last token is redeem script")
|
||||
val redeemScriptTry : Try[ScriptPubKey] = parseRedeemScript(token)
|
||||
redeemScriptTry match {
|
||||
case Success(redeemScript) =>
|
||||
logger.debug("Possible redeemScript: " + redeemScript)
|
||||
redeemScript match {
|
||||
case x : P2PKHScriptPubKey => true
|
||||
case x : MultiSignatureScriptPubKey => true
|
||||
case x : P2SHScriptPubKey => true
|
||||
case x : P2PKScriptPubKey => true
|
||||
case x : NonStandardScriptPubKey => false
|
||||
case EmptyScriptPubKey => false
|
||||
}
|
||||
case Failure(_) => false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a redeem script from the given script token
|
||||
*
|
||||
* @param scriptToken
|
||||
* @return
|
||||
*/
|
||||
def parseRedeemScript(scriptToken : ScriptToken) : Try[ScriptPubKey] = {
|
||||
val redeemScript : Try[ScriptPubKey] = Try(ScriptPubKey(scriptToken.bytes))
|
||||
redeemScript
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given script tokens are a multisignature script sig
|
||||
* format: OP_0 <A sig> [B sig] [C sig...]
|
||||
*
|
||||
* @param asm the asm to check if it falls in the multisignature script sig format
|
||||
* @return boolean indicating if the scriptsignature is a multisignature script signature
|
||||
*/
|
||||
def isMultiSignatureScriptSignature(asm : Seq[ScriptToken]) : Boolean = {
|
||||
asm.isEmpty match {
|
||||
case true => false
|
||||
case false if (asm.size == 1) => false
|
||||
case false =>
|
||||
val firstTokenIsScriptNumberOperation = asm.head.isInstanceOf[ScriptNumberOperation]
|
||||
val restOfScriptIsPushOpsOrScriptConstants = asm.tail.map(
|
||||
token => token.isInstanceOf[ScriptConstant] || StackPushOperationFactory.isPushOperation(token)
|
||||
).exists(_ == false)
|
||||
logger.debug("First number is script op: " + firstTokenIsScriptNumberOperation)
|
||||
logger.debug("tail is true: " +restOfScriptIsPushOpsOrScriptConstants )
|
||||
firstTokenIsScriptNumberOperation && !restOfScriptIsPushOpsOrScriptConstants
|
||||
}
|
||||
/**
|
||||
* Checks if the given script tokens are a multisignature script sig
|
||||
* format: OP_0 <A sig> [B sig] [C sig...]
|
||||
*
|
||||
* @param asm the asm to check if it falls in the multisignature script sig format
|
||||
* @return boolean indicating if the scriptsignature is a multisignature script signature
|
||||
*/
|
||||
def isMultiSignatureScriptSignature(asm : Seq[ScriptToken]) : Boolean = {
|
||||
asm.isEmpty match {
|
||||
case true => false
|
||||
case false if (asm.size == 1) => false
|
||||
case false =>
|
||||
val firstTokenIsScriptNumberOperation = asm.head.isInstanceOf[ScriptNumberOperation]
|
||||
val restOfScriptIsPushOpsOrScriptConstants = asm.tail.map(
|
||||
token => token.isInstanceOf[ScriptConstant] || StackPushOperationFactory.isPushOperation(token)
|
||||
).exists(_ == false)
|
||||
logger.debug("First number is script op: " + firstTokenIsScriptNumberOperation)
|
||||
logger.debug("tail is true: " +restOfScriptIsPushOpsOrScriptConstants )
|
||||
firstTokenIsScriptNumberOperation && !restOfScriptIsPushOpsOrScriptConstants
|
||||
}
|
||||
}
|
||||
|
||||
def apply(bytes: Seq[Byte]) : ScriptSignature = fromBytes(bytes)
|
||||
def apply(hex : String) : ScriptSignature = fromHex(hex)
|
||||
|
|
Loading…
Add table
Reference in a new issue