Hi, this is an idea that has been on my mind for a while now, but my knowledge of Bitcoin Script (and especially Tapscript) is pretty limited.
From what I understand, Ordinals inscriptions work by embedding a "data envelope" inside the spending script. This envelope doesn't affect the script itself, (it's in an if branch that'll always evaluate to false).
So AFAICT the witness data looks something like this:
OP_PUSHBYTES_32 <signature> OP_CHECKSIG OP_FALSE #data envelope starts OP_IF #push data bytes here OP_ENDIF
But since the op_false script does nothing, it should in theory be possible to simply remove this from the witness data. What you would get after doing this would be a simple 1-in-1-out Taproot spend (with an extremely high feerate due to almost no actual data). Malleating the transaction in this way wouldn't change the txid either, so the signature would still be valid.
Have I gotten something wrong? Or is it in theory possible to simply render inscriptions worthless?
This is a great idea! I love the thought. Unfortunately it won't work, but its good thinking!
Here's the bit that you're missing: As you may know, taproot lets you construct an address that be can be spent from using either a key (called the keypath) or using one of potentially many scripts (called a script path)
When you construct a taproot "address", you take an internal key (the pubkey that's usable in a keyspend path), and you tweak it with the merkle root of the script tree. So you take all the tapscripts, make it into a merkle tree, and then add the merkle root of that tree to the internal pubkey, and the resulting pubkey is used as the address.
When you spend from a scriptpath, you provide the internal pubkey, the script that you're spending, and a little blob called the Control Block that includes a merkle proof that the script was included in the tweak. The script interpretter hashes the script that you provide, and then validates that the merkle proof in the control block is valid, and then combines the tweak with the pubkey and validates that it matches the address. In other words, it checks that the script that you're using to spend was actually committed to when you locked up the coins. This involves hashing the entire script. If that check passes, then it proceeds to actually interpreting the script (which as you point out it basically a checksig and then a no-op).
So, if you were to prune out the actual data blobs from the inscription envelope, then the hash of the script won't combine with the rest of the hashes in the control block up to the correct tweak, and the transaction will not be seen as valid, and won't be mined.
For the gory details on how this happens, check out BIP341: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#script-validation-rules
tl;dr: even though the data is not evaluated, it's still hashed, so has to be there for the tx to be valid.
reply
Thanks for the great answer. I wasn't aware that that the script is hashed for Taproot. But if Ordinals are doing the keypath spend anyways, shouldn't it be possible to omit the merkle root from the spend as well? Do regular Taproot wallet spends have to include that too?
reply
ordinal inscriptions do a scriptpath spend. The script happens to be: check a signature op_false op_if <data> op_endif
reply
Ahh, that makes sense. Thanks!
reply
great explanation indeed. @rijndael Could you care to elaborate what could be (if anything) to ignore them -- whether it's not mining them or nodes pruning them? I understand the witness part could be pruned but it's still useful for non-ordinals.
Is it a cat-and-mouse game where a conditional code is changed but the ordinal code simply pushes another small tweak which renders the ordinal-killing code useless?
Thanks!
reply
Doesn’t Segwit implement a wtxid that does take the witness data into account?
reply
Yes but the signature only commits to the TXID. A signature can't sign itself so you couldn't sign the WTXid even if you wanted to. AFAICT the WTXId is only used to build the merkle tree for witness data.
reply
I feel like we must be missing something or this is a huge problem for taproot. 😂
reply
If my understanding isn't wrong, the only reason this would work is because the ordinals data isn't actually needed to unlock the UTXO. It's just a bunch of meaningless fluff added after the signature has already been provided and checked
reply
Malleating the transaction in this way wouldn't change the txid either, so the signature would still be valid.
Could you explain this more?
reply
Segwit made it so that witness data doesn't affect the txid. This was to solve people changing the signature slightly and changing the txid (Google Transaction malleability) which was an issue for applications like LN.
Since ordinals are in the witness data, removing it won't affect the txid
reply
There would need to be a bit of discussion around this but it could cut out the fattest witness sections in the blocks. Since the logic is satisfied (return false, ie anything but 1, right?) with no bytes in the parameter (0 size varint, is all) still validates, and its fee is based on the data not the actual stuff it puts in the block (chuckle), and the TXID is the same, who's gonna know the difference? It makes the same address due to segwit anyhow, also.
At least that's how it sounds to me. And any miner doing this is lowering the cost of block space for the rest of the network :D Is there any meritorious party involved who doesn't win out of this?
reply
Well it doesn't actually work as the top level comment pointed out
reply