1

Given a raw tx, how to determine whether an input is of type witness_v0_keyhash or witness_v1_taproot? Thanks.

For example:

0100000000010180896ef46031af4aa6633bfc93ba2051605df3b81c2dd2beee626adca1e9a2370000000000ffffffff022bae3a010000000022512057b565e1ee4231a53f1f62ef7250c2640cc110f845086b902fe389f36c87dbe0cdd90000000000001600147978341fb68e3956812c494a56d9d3efaef0ee3a0141a8f4b208bb6e28cab7935e8b677f9480a192de7749b55ed6e1e3a31e1b5f6853017ff5cdd1f37d5e3ad91623cdbf377a9105f42df7dcc675e9c008014d16fc440100000000

2 Answers 2

1

While there are common patterns that can be used to determine the output type from the input that spends it, the only surefire way to know the output type is to inspect the output itself. Since that information is not provided by the spending transaction, it is not possible to make this determination definitively.

However, as I mentioned, there are some common patterns. Inputs that spend Segwit v0 keyhash outputs can only look a certain way. Such inputs will have no scriptSig and will have a witness stack containing two items. The last stack item will be a public key, identifiable by its length of either 33 bytes or 64 bytes, and have a leading byte of one of 0x02, 0x03, or 0x04. The second item in that stack will be a signature that follows DER strictly.

For Segwit v1 Taproot outputs, the witness stacks can vary depending on the spending method. If it is a keypath spend, then there will be only one item and it will be a signature that is 64 or 65 bytes long. There are no encoding rules that place fixed bytes, so that is all you will have.

Taproot script path spends are much more complicated. They will have at least 2 witness stack elements. The last element is the control block and will be 33 + 32m bytes long, where m is an integer between 0 and 128 inclusive. The control block's first byte is the leaf version, which is currently only 0xc0. The following 32 bytes are the Taproot internal pubkey, followed by 32 byte hashes for the branches Taproot merkle tree, followed by the 32 byte merkle root. The second to last element in the stack will be the tapscript. The TapLeaf hash of this script can be combined with the branches given in the control block in order to calculate the merkle root. All of the remaining stack items depend on the script.

While inputs that spend v0 keyhash and v1 taproot outputs will look like this, they are not necessarily exclusive. It is theoretically possible to have v0 scripthash spends that look identical to these patterns. It is possible that future segwit versions will have input stacks that look identical. It's also possible that someone can spend a currently undefined segwit version and provide input stacks that look identical to these. Determining the output type based on the input data is not guaranteed to be correct.

1

So your question asks about inputs. The types witness_v0_keyhash and witness_v1_taproot are generally associated with outputs. However, inputs can also (sort of) be categorized by what is in the input script and/or the segregated witness.

First of all, witness_v0_keyhash outputs are of the form:

OP_0
<20-byte hash>

Whereas, witness_v1_taproot outputs are of the form:

OP_1
<32-byte hash>

But the inputs that redeem these outputs don't necessarily have to all be of the same format.

If we look at a recent witness_v0_keyhash output, for example aa64f3a8e692e585a50d441d82f6ddc5cbc1ae33176fd645066a1de4734262e4 (output 0), we see an example of this output type. It is two fields: OP_0, followed by the 20-byte hash.

Now if we look at the input that redeemed this output, which is a27f50775ce85e02815fd9e30f9bcc242deabc1789797d24177ad757b67036f5 (input 0), we see that it is very simple. As a segregated witness transaction, it has an empty input script and nothing but a signature and a public key in the segregated witness. Almost all inputs that redeem witness_v0_keyhash outputs are of that same format. Some things to note are that it is the old-style elliptic curve signature and has a sighash byte appended to the end of it, making it a variable length signature. The public key is a 33-byte compressed public key.

Let's compare that to a recent witness_v1_taproot output, for example 7aeb0447d99fb9755ad21846cef74a1b24bb6a75c56c85a39379c5097d230021 (output 0). It is also two fields: OP_1, followed by the 32-byte hash.

The input that redeems this output, which is 1eac74f5d124b9f5f2b606ca8f9a37dca3dddd890b66e19b6a761ec693f2467a (input 1), is even more simple. It too contains an empty input script, but the segregated witness is nothing but a 64-byte, uniform-length, signature.

But redeeming Taproot outputs can get more complicated if you start getting into script path spending. In the old days, there was P2PKH and P2SH, key vs. script methods for redeeming outputs. The data was moved to a different part of the transaction when those output types became P2WPKH and P2WSH. But with Taproot, there is one output type that accommodates both key path and script path spending. So there are many different types of inputs that are possible. These are explained in BIP 340, BIP 341 and BIP 342.

1
  • Nit: the 32-byte witness program that follows the OP_1 in a P2TR output is not a hash, but a tweaked x-only public key (in a very abstract sense that can be considered a hash too, but that's more confusing than enlightening I think). Dec 15, 2022 at 15:26

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.