I am not sure if I confuse the address format prefix bc1 with the witness version.
You are confusing them. "bc1" is the prefix. The witness version is part of the bech32/bech32m payload; specifically, the next character after the "1" encodes the witness version.
P2WPKH, P2WSH have witness version 0 indicated by the yellow part shown below. If witness version is 0, a SegWit node looks at the size of the byte-key-hash to determine if it is a P2WPKH (20B) or P2WSH(32B).
This is correct.
P2WPKH wrapped in P2SH and P2WSH wrapped in P2SH does not have a witness version byte in the scriptPubKey. Why is that?
In P2SH-wrapped P2WPKH/P2WSH the scriptPubKey encodes only a hash of the witness program (the OP_(version) + data push). The actual witness program (including the witness version) is only revealed at spending time.
According to BIP350, bech32 has witness version 0 and bech32m has witness version.
Almost. You cannot tell bech32 from bech32m strings by just looking at them. However, in the context of native segwit addresses, bech32 has to be used for witness 0, and bech32m has to be used for witness 1 and higher.
So in general the strategy is to try decoding every address as both bech32 and bech32m, see if either is valid, then check if the payload encodes a valid segwit address, find its version, and finally check that the version matches the address encoding (bech32 for 0, bech32m for other versions).
This is mostly unrelated to your question though. The encoding is structured as follows (for both bech32 and bech32m; the only difference between the two is the checksum):
- First there is the human readable part.
- For mainnet native segwit addresses (v0 or later), the human readable part is "bc".
- Then there is the separator. The separator is always exactly "1".
- Then there is the payload, consisting of a variable number of base32 characters.
- For native segwit addresses (v0 or later), the payload consists of one character that encodes the witness version (v0 = "p", v1 = "q", v2 = "z", ...), followed by 4 to 64 characters that encode the 2 to 40 byte push in the witness program (the data pushed after the OP_(version)).
- Lastly there are 6 base32 characters that form a checksum over the whole thing.
P2TR introduces new opcodes and therefore, it should introduce a new witness version, is that correct?
Indeed, P2TR uses witness programs that consist of OP_1 + a 32-byte push, and are thus witness version 1. In BIP350 addresses, that translates to a "p" after the separator (as opposed to version 0 P2WPKH/P2WSH, which have a "q" after the sepatator).