Hi ZmnSCPxj,
>
Just ask a bunch of fullnodes to add this 1Mb of extra ignored data in this tiny 1-input-1-output transaction so I pay only a small fee
I'm not suggesting that you wouldn't have to pay a fee for it. You'd pay a fee for it as normal, so there's no DOS vector. Doesn't adding extra witness data do what would be needed here? Eg simply adding extra data onto the witness script that will remain unconsumed after successful execution of the script?
> how do new jets get introduced?
In scenario A, new jets get introduced by being added to bitcoin software as basically relay rules.
> If a new jet requires coordinated deployment over the network, then you might as well just softfork and be done with it.
It would not need a coordinated deployment. However, the more nodes that supported that jet, the more efficient using it would be for the network.
> If a new jet can just be entered into some configuration file, how do you coordinate those between multiple users so that there *is* some benefit for relay?
When a new version of bitcoin comes out, people generally upgrade to it eventually. No coordination is needed. 100% of the network need not support a jet. Just some critical mass to get some benefit.
> Having a static lookup table is better since you can pattern-match on strings of specific, static length
Sorry, better than what exactly?
> How does the unupgraded-to-upgraded boundary work?
This is what I'm thinking. Imagine a simple script:
OP_DUP
OP_ADD
with witness
1
This would execute as 1+1 = 2 -> success. Let's say the script is jettified so we can instead write it as:
1b5f03cf # adler32 hash of the replaced script
with a witness:
OP_JET # Some number that represents OP_JET
1b5f03cf
0
1
A jet-aware node transmitting to another jet-aware node can transmit it as is (tho it would need to do a swap out to validate). For a jet-aware node to transmit this to a non-jet aware node, it would need to swap the OP_JET call with the script it represents. So the transaction sent to the non-jet aware node would have:
Script:
Witness:
And you can see that this would execute and succeed by adding 1+1 and ending up with the stack:
2
0
1b5f03cf
OP_JET
Which would succeed because of the non-zero top of stack.
When the non-jet aware node sends this to a jet-aware node, that node would see the extra items on the stack after script execution, and would interpret them as an OP_JET call specifying that OP_JET should replace the witness items starting at index 0 with `1b5f03cf OP_JET`. It does this and then sends that along to the next hop.
In order to support this without a soft fork, this extra otherwise unnecessary data would be needed, but for jets that represent long scripts, the extra witness data could be well worth it (for the network).
However, this extra data would be a disincentive to do transactions this way, even when its better for the network. So it might not be worth doing it this way without a soft fork. But with a soft fork to upgrade nodes to support an OP_JET opcode, the extra witness data can be removed (replaced with out-of-band script fragment transmission for nodes that don't support a particular jet).
One interesting additional thing that could be done with this mechanism is to add higher-order function ability to jets, which could allow nodes to add OP_FOLD or similar functions as a jet without requiring additional soft forks. Hypothetically, you could imagine a jet script that uses an OP_LOOP jet be written as follows:
5 # Loop 5 times
1 # Loop the next 1 operation
3c1g14ad
OP_JET
OP_ADD # The 1 operation to loop
The above would sum up 5 numbers from the stack. And while this summation jet can't be represented in bitcoin script on its own (since bitcoin script can't manipulate opcode calls), the jet *call* can still be represented as:
OP_ADD
OP_ADD
OP_ADD
OP_ADD
OP_ADD
which means all of the above replacement functionality would work just as well.
So my point here is that jets implemented in a way similar to this would give a much wider range of "code as compression" possibilities than implementing a single opcode like op_fold.
> To make jets more useful, we should redesign the language so that `OP_PUSH` is not in the opcode stream, but instead, we have a separate table of constants that is attached / concatenated to the actual SCRIPT.
This can already be done, right? You just have to redesign the script to consume and swap/rot around the data in the right way to separate them out from the main script body.