The reason that we want to specify the number of inputs but not the exact inputs is because if we were to specify the exact inputs it creates a hash cycle. This then prevents the opcode from actually being used.
OP_CAT
Am I missing something, or is OP_CAT not really a thing anymore? The info here says its disabled.
https://en.bitcoin.it/wiki/Script#SpliceNope, you're not wrong here. My point was that if those sorts of covenants are desirable to express, we can add great support for that functionality with another often requested opcode (OP_CAT or a similar solution). There are a few variants to OP_CAT to consider, but I don't think there would be much objection if someone went through the effort of re-specifying it as a Tapscript upgrade (OP_SUCCESSX makes it easier to introduce opcodes which manipulate the stack).
Personally, I like that there's a "roadmap" for more powerful covenants enabled by OP_CTV, while we can introduce the fundamentals today.
the reason that separately committing the number of inputs from the sequences makes it possible to write a script that allows the spender to pass in *any* sequences they like, while still be restricted to a specific number of inputs
Hmm, well that makes it sound like its not actually strictly redundant then. Why would you want to restrict a transaction to a specific number of inputs (other than 1) tho?
Well it's strictly redundant insofar as the sequences commits to the length which transitively commits to the number of inputs.
I think it's less so that you want a restriction to a specific number of inputs and more that committing the field lets you programmatically select a number of inputs.
You might want to restrict this number in future applications where a script (with a new OP, something like CHECKINPUTVERIFY) checks a property of all the inputs. If you could add or remove an input, then you might break such a script.
the half spend problem crops up if I created 2 CTV outputs with the same script (with no # inputs restriction) they could be spent in the same transaction, creating half the outputs as if spent separately
Is this the same problem Greg brought up in his first post, about "preventing an attacker from .. sending most of [the] value to fee?" Are you saying that if 2 CTV UTXOs that have the same script commit to specific outputs, both UTXOs will be spent for no reason (because the outputs are set in stone)?
This is a class of vulnerability which I believe I originally came up with when writing the BIP. You can review
https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki for "half-spend".
Specifically, this is not an issue with OP_CTV because we designed OP_CTV with this in mind. CTV commits to the input index being spent at, which precludes this sort of issue in the context of key reuse for basic CTV scripts. (We meaning myself and other Bitcoin developers I discussed this issue with).
So I think that your vault use case is too general. If you refine it a little, you'll see that CTV works pretty well.
What do you mean by "too general". What downside are you implying with that generality? The issue with op_ctv as it is is that it basically requires that outputs be spent one at a time, rather than allowing the wallet owner arbitrary ability to construct a transaction with as many inputs and to as many outputs as they want. This would make the use of a wallet that uses this construct a lot more expensive to use, and a lot less convenient.
It seems like there are a couple primary things you might want to do with an op like this:
1. Require that an output be spent with a specific transaction (ie you can commit to a hash of the whole transaction).
2. Require that an output be to a specific address (perhaps less some fee), or more generally, require that the transaction that spends the input must spend at least X coin to a specified address (or multiple specified addresses), where X is less than or equal to the input value and is specified in the covenant.
3. Require a particular locktime.
I must admit I'm not practiced in bitcoin scripting, but it seems like the types of things we might want a covenant to commit to is somewhat more limited than op_ctv is (less fields able to independently commit to) and at the same time provides more general abilities. I'm curious about your thoughts on what the above three mechanisms would be unable to do well that op_ctv can do better.
Well so you've said stuff that translates to me as "I want to be able to arbitrarily spend the coins in whatever manner I want". Tongue in cheek, but bitcoin already has this... it's called P2[w]PKH! When you're using a covenant you're generally trying to encumber the coins with new restrictions. I think CTV strikes an elegant balance between encumbrance and flexibility, but you're right that it's far from being able to run an arbitrary piece of code outside of the transaction checking arbitrary properties.
That said, it is possible to do *some* of these things.
1. There's a kinda clunky way to do this when the other input is non-segwit. However, I think this behavior is best left to a separate op_code so that the "checkinput" functionality can be used standalone from op_ctv.
2. So this is the fundamental thing CTV does. But without OP_CAT (or similar), you can't restrict it to just requiring *some* output be specified
3. This exists presently as locktime is comitted.
Generally, I think the right way to design a contract with CTV is to come up with the end states and preconditions for the end states that you want to encode, and then figure out a transaction structure that meets your goal. I've found this to be successful for OP_CTV. If you instead, design an arbitrary system with whichever features you want, map it onto transactions, and then try to convert that into OP_CTV it may not be possible.
With respect to efficiency, you can always create as many outputs as you want, so I'll interpret your comment to be about how many inputs you are co-spending. You can definitely write safe contracts with CTV that spend many inputs together to create the contract, because the first step is not bound by anything.
But I think if you *generally* analyze the program size it will be more transactions (as nodes in your program graph) but the overall size is not too great. Remember, if I have O(N) inputs in O(1) transactions, it's within constant factors of O(1) inputs in O(N) transactions. But without a specific example (e.g., I have these UTXOS, I want to end up with these other UTXOS if preconditions X are met) it's hard for me to tell you how much less efficient or more efficient the CTV version will be. CTV scripts are also *small* and *cheap* to verify, so each node isn't that expensive to verify anyways.
Here are some pics of a vault contract that I implemented a (power user) GUI for
https://imgur.com/a/rhxW4F0cold vaults which by default leave the coins at rest
I'm very curious to hear what you mean by "by default leave the coins at rest".
Recommend you watch my BPASE 17 talk
https://www.youtube.com/watch?v=r7xN7K0OqaA https://cyber.stanford.edu/sites/g/files/sbiybj9936/f/jeremyrubin.pdfI go over a lot of different covenant mechanisms and designs. Specifically this is the "optically isolated" idea -- it's a security trade-off but sometimes it can be a good design.