diff --git a/core-test/src/test/scala/org/bitcoins/core/protocol/Bech32Spec.scala b/core-test/src/test/scala/org/bitcoins/core/protocol/Bech32Spec.scala index a40dace717..38228b2290 100644 --- a/core-test/src/test/scala/org/bitcoins/core/protocol/Bech32Spec.scala +++ b/core-test/src/test/scala/org/bitcoins/core/protocol/Bech32Spec.scala @@ -28,7 +28,7 @@ class Bech32Spec extends Properties("Bech32Spec") { } property("serialization symmetry") = { - Prop.forAll(ScriptGenerators.witnessScriptPubKey, + Prop.forAll(ScriptGenerators.witnessScriptPubKeyV0, ChainParamsGenerator.networkParams) { case ((witSPK, _), network) => val addr = Bech32Address(witSPK, network) diff --git a/core-test/src/test/scala/org/bitcoins/core/protocol/Bech32Test.scala b/core-test/src/test/scala/org/bitcoins/core/protocol/Bech32Test.scala index 9e3ee1a34b..5b8468bf9b 100644 --- a/core-test/src/test/scala/org/bitcoins/core/protocol/Bech32Test.scala +++ b/core-test/src/test/scala/org/bitcoins/core/protocol/Bech32Test.scala @@ -240,4 +240,18 @@ class Bech32Test extends BitcoinSUnitTest { .checkDataValidity("bcrt1qq6w6pu6zq90az9krn53zlkvgyzkyeglzukyepf") .isFailure) } + + it must "fail to read a segwitV1 bech32 address" in { + assert( + Bech32Address + .fromStringT( + "tb1prp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7") + .isFailure) + + assert( + Bech32Address + .fromStringT( + "bc1prp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7") + .isFailure) + } } diff --git a/core/src/main/scala/org/bitcoins/core/protocol/Address.scala b/core/src/main/scala/org/bitcoins/core/protocol/Address.scala index e8130ebbbf..f77e01ae65 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/Address.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/Address.scala @@ -88,7 +88,7 @@ sealed abstract class Bech32Address extends BitcoinAddress { def checksum: Vector[UInt5] = Bech32Address.createChecksum(hrp, data) - override def scriptPubKey: WitnessScriptPubKey = { + override def scriptPubKey: WitnessScriptPubKeyV0 = { Bech32Address.fromStringToWitSPK(value).get } @@ -99,9 +99,6 @@ sealed abstract class Bech32Address extends BitcoinAddress { Sha256Hash160Digest(byteVector) case _: P2WSHWitnessSPKV0 => Sha256Digest(byteVector) - case _: UnassignedWitnessScriptPubKey => - throw new IllegalArgumentException( - s"Cannot parse the hash of an unassigned witness scriptpubkey for bech32 address") } } @@ -149,7 +146,7 @@ object Bech32Address extends AddressFactory[Bech32Address] { /** Tries to convert the given string a to a * [[org.bitcoins.core.protocol.script.WitnessScriptPubKey WitnessScriptPubKey]] */ - def fromStringToWitSPK(string: String): Try[WitnessScriptPubKey] = { + def fromStringToWitSPK(string: String): Try[WitnessScriptPubKeyV0] = { val decoded = fromStringT(string) decoded.flatMap { bech32Addr => val bytes = bech32Addr.data @@ -161,7 +158,7 @@ object Bech32Address extends AddressFactory[Bech32Address] { witVersion match { case Some(v) => val witSPK = Try( - WitnessScriptPubKey( + WitnessScriptPubKeyV0( List(v.version) ++ pushOp ++ List(ScriptConstant(progBytes)))) witSPK match { case Success(spk) => Success(spk) diff --git a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptPubKey.scala b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptPubKey.scala index a9d6ad61ba..cdf440deea 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptPubKey.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptPubKey.scala @@ -1212,7 +1212,7 @@ sealed abstract class WitnessScriptPubKeyV0 extends WitnessScriptPubKey { override def witnessProgram: Seq[ScriptToken] = asm.tail.tail } -object WitnessScriptPubKeyV0 { +object WitnessScriptPubKeyV0 extends ScriptFactory[WitnessScriptPubKeyV0] { /** * Mimics the function to determine if a @@ -1227,6 +1227,19 @@ object WitnessScriptPubKeyV0 { WitnessScriptPubKey.isWitnessScriptPubKey(asm) && asm.headOption.contains( OP_0) } + + def apply(asm: Seq[ScriptToken]): WitnessScriptPubKeyV0 = fromAsm(asm) + + override def fromAsm(asm: Seq[ScriptToken]): WitnessScriptPubKeyV0 = + asm match { + case _ if P2WPKHWitnessSPKV0.isValid(asm) => + P2WPKHWitnessSPKV0.fromAsm(asm) + case _ if P2WSHWitnessSPKV0.isValid(asm) => + P2WSHWitnessSPKV0.fromAsm(asm) + case _ => + sys.error( + s"The given asm was not a valid WitnessScriptPubKeyV0, got asm=$asm") + } } /** diff --git a/testkit/src/main/scala/org/bitcoins/testkit/core/gen/AddressGenerator.scala b/testkit/src/main/scala/org/bitcoins/testkit/core/gen/AddressGenerator.scala index 2661392bbd..9f130beadb 100644 --- a/testkit/src/main/scala/org/bitcoins/testkit/core/gen/AddressGenerator.scala +++ b/testkit/src/main/scala/org/bitcoins/testkit/core/gen/AddressGenerator.scala @@ -24,9 +24,9 @@ sealed trait AddressGenerator { def bech32Address: Gen[Bech32Address] = for { - (witSPK, _) <- ScriptGenerators.assignedWitnessScriptPubKey + (witSPKV0, _) <- ScriptGenerators.witnessScriptPubKeyV0 network <- ChainParamsGenerator.networkParams - addr = Bech32Address(witSPK, network) + addr = Bech32Address(witSPKV0, network) } yield addr def bitcoinAddress: Gen[BitcoinAddress] =