bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.68k stars 2.1k forks source link

internalPubkey seems to be a misnomer when committing to null merkle root of script tree #2029

Closed ildarmgt closed 9 months ago

ildarmgt commented 9 months ago

afaik it's a point of great confusion that when you have to manually tweak the internal key to commit to no script, you still have to submit it under internal key in p2tr api. This is even more the case when people have both script path and key path, I see confusion on which pubkey to put under payments.p2tr({ internalPubkey, network})

it's all just q = P + H(P||m)*G as far as I know where q is often referred to as taproot output key or external key.

BIP recommended way is to just remove m to commit to no script if want only keypath so just q = P + H(P)*G

Right now we can have scriptTree set as array of 2 items or object for a tapleaf, which seems to tweak internal key correctly by calculating m. However, when you avoid scriptTree, it just suddenly stops doing the calculation for external key and we have to do it manually. If there was a way to specify scriptTree: null or scriptTree: {none: true} or { noScriptTree: true } or even just give value of m, the tweak could be done internally and not have user being unsure which key to use regardless of use of scriptTree.

Let me know if I got anything wrong, thank you!

junderw commented 9 months ago

I don't really understand what is confusing.

I am highly doubtful that creating a difference between the treatment of undefined and null in this case will decrease confusion... I think it will increase it greatly. Especially because you would need to tweak the private key in order to sign anyways, so moving the tweaking to the key makes more sense to me.

To be fair, taproot is confusing in general, so 100 people might have 100 opinions on what a "good API" is. I think @motorina0 did a good job with the current API.

I'd be interested to hear @motorina0 's opinion.

motorina0 commented 9 months ago

I don't really understand what is confusing.

  • idem

The internalPubkey is (usually) the the bip32 derived key at path m/86'/.... So this is what Signing Devices can derive and provide as input.

For the output key the pubkey field is used. This makes it consistent with the other payment functions (p2pkh, p2wpkh).

If the user provides the internalPubkey then the pubkey (output key) will be computed automatically.