Please correct me if i'm wrong:

So, with segwit v0 we know that 20 bytes is equal to P2WPKH, and 32 bytes is equal to P2WSH, and thus we can identify the address type by decoding the 31 byte or 43 byte bech-32 encoded string.

so we get decoded 0 < hash of pubkey > or 0 < sha hash of redeem script >, and identify the sender address type

Now I read that there has been some testing done with newer bech versions (bech32m) for P2WSH (or P2TR?) addresses, and also comments that some testing resulted in funds being lost, which confused me. (https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-November/018268.html)

A) Considering funds got lost on mainnet using bech32m encoding (or was it p2tr v1+ using bech32?), am i correct in assuming that P2WPKH/S scripts can have a witness version of 1 (bech32m), else: how could this have been tested on mainnet (or can you generate valid p2tr addresses already, but just not spend from them? is that it?) -> I guess that would make sense considering a v1 taproot address would look identical to a v1 P2WSH address?

->> if so, how can we differentiate between script hashes of P2WSH 1 <32 byte hash of redeem script>, and taproot 1 <public key 32 bytes>


as address indication is done purely based on "script size", and why is this not done in above link? Would this be considered "unstandard" - if so, why was there such an emphasis on testing this? I don't understand how this was a surprise?

B) If this is not the case and it was indeed P2TR adddresses which did not decode correctly using bech32, why then was this the case exactly, considering the only thing that bech32m changes is the checksum? As in; the decoding process did not change as a result of this BIP.

A quote from the BIP:

This does not affect existing uses of witness version 0 BIP173 addresses due to their restriction to two specific lengths, but may affect future uses and/or other applications using the Bech32 encoding.

addresses using P2TR also have a restricted length, right?

1 Answer 1


You differentiate a Taproot scriptPubKey and a P2WSH scriptPubKey by their witness version. 1 for Taproot, 0 for P2WSH.

A "P2WSH with version 1" doesn't exist, it would just be treated as a Taproot scriptPubKey by upgraded nodes (after activation) and as an anyone-can-spend by legacy ones.

P2WSH: <0> <32-bytes push>
Taproot: <1> <32-bytes push>

As for the mentioned funds loss i haven't heard about it but it's possible (if you send coins to <0> <random 32 bytes> you are going to burn your funds). In any case it would not be related to the address encoding, which is just an user interface.

  • Okay, that was what I was wondering - native segwit cannot use version 1 and above and subsequently do not use bech32m encodings (which is just a different checksum), else they are seen as invalid, (or a taproot address which is actually unspendable). I still don't fully understand what happend that caused P2TR "scripts" (pubkey, whatever you want to call it) encoded using standard bech32 (so checksum of 1) to burn funds because they were decoded wrong by wallets, if anyone could clarify the technicalities of that, and why that would be changed by bech32m, aside from breaking forwar-compat Commented Jun 1, 2021 at 17:50
  • 1
    It's not whatever i want to call it, i try to use specific terms to not cause (additional) confusion (too many terms are already overloaded in Bitcoin-land). I don't know what you are talking about, could you provide a link to a discussion about this loss? Commented Jun 1, 2021 at 17:54
  • 1
    Taproot outputs (P2TR) are native segwit v1 with 32-byte programs. That's how these outputs are defined. They're not "P2WSH v1", because P2WSH is defined as "Native or P2SH segwit v0 outputs with 32-byte programs". Commented Jun 1, 2021 at 18:38
  • 2
    The burning of funds was due to some services incorrectly implementing BIP173 in a way that resulted in bech32 v1+ addresses being turned into native v0 witness outputs (regardless of the version in the address). Taking a P2TR output (which stores a tweaked xonly pubkey) and changing the version to zero causes it to be interpreted as a P2WSH (with as script "hash" that tweaked key), which is unspendable. Commented Jun 1, 2021 at 18:42
  • 2
    Sorry, in that case I should indeed specify that by "native-segwit" in the first comment I was referring to the two "spending scripts" (again, not sure if correct terminology) currently used with witness version 0. Taking ... is unspendable Okay fascinating, so they just sent to <0> <32-bytes push> instead of <1> <32-bytes push> because the version was hardcoded or similar on their end, and because that is actually just a valid P2WSH v0 encoding there was nothing that invalidated the payment? Think I got it. Commented Jun 1, 2021 at 18:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.