This is the second article in A series Deep dives in individual alliance proposals that have reached a high school point by deserving a thorough break.
Checksigfromstack (CSFS), presented by Brandon Black and Jeremy Rubin with Bip 348, is not an alliance. As I said in the introductory article to this series, some of the proposals that I would have covered are not alliances, but synergized or stop in some way. CSFS is the first example of this.
CSFS is a very simple opcode, but before examining how we work we look at the foundations of how a bitcoin script actually works.
The script is a stack -based language. This means that the data are “stacked” together one above the other on the stack and managed by removing an element from the top of the stack to operate on the basis of what does an operating code does, returning the data or a result from it to the top of the stack.
There are two parts of a script when in the end it is performed and verified, the “witness” provided to unlock the script and script included in the spent output. The witness/unlock script is “added” to the left side of the locking script, then each element is added (or opera) the stack one by one from left to right. Look at this example (the “|“Scores the border between the witness and the script):
1 2 | Op_add 3 op_equal
This example adds the value “1” to the stack, then the “2” value above. Op_add takes the first two elements of the stack and adds them together, putting the result to the stack (so now everything on the stack is “3”). Another “3” is then added to the stack. The last element, Op_etual, takes the first two elements of the stack and returns a “1” to the stack (1 and 0 can represent true or false and numbers).
A script must end with the last element in the upper part of the stack is true, otherwise the script (and the transaction that performs it) fails and is considered unrealized consent.
This is a basic example of a pay-to-pubkey-Hash (P2PKH) script, that is, the Legacy addresses starting with a “1”:
First of all, the signature and the public key are added to the stack. So it’s called DUP, which takes the upper Stack object and duplicates it, returning it to the top of the stack. Hash160 takes the stack object at the top (the duplicate of the public key), the hash, then returns it to the top of the stack. The hash of the public key of the script is put at the top of the stack. Equalverify works the same as the same, grabs the two elements of the upper stack and returns a 1 or 0 according to the result. The only difference is the same, it also performs verification after the same, which fails the transaction if the upper stack element is not 1 and also removes the upper stack element. Finally, Checksig is performed, which grabs the first two elements of the stack, assuming that they are a signature and a pubkey and implicitly checks the signature against the hash of the verified transaction. If it is valid, put a 1 on top of the stack.
How CSF works
Checksig is one of the most used workers in Bitcoin. Each transaction, without any exception, uses this option at some point in one of its scripts. The signature of the signature is a basic component of the Bitcoin protocol. The problem is that there is almost no flexibility in terms of which message you are checking the signature. Checksig will check only a signature compared to the transaction that is verified. There is a certain flexibility, that is, you can decide with a certain degree of freedom to which parts of the transaction the signature is applied, but that’s enough.
CSFS aims to modify it allowing you to check a signature from any arbitrary message that is pushed directly to the stack, instead of being limited to verifying the signatures against the transaction itself. The opCode follows a very simple operating structure:
The signature and the message are released above the stack, then the public key above them, and finally CSFS grabs the first three elements of the stack, assuming that they are the public key, the message and the signature from top to bottom, checking the signature against the message. If the signature is valid, a 1 is positioned on the stack.
That’s all. A simple variant of Checksig that allows users to specify arbitrary messages instead of only the transaction of spending.
What is useful for CSF
So what exactly is it good for? What is the use of control of a signature against an arbitrary message on the stack instead of the transaction of spending?
Firstly, in combination with CTV it can provide a functionality equivalent to something that lightning developers have desired from the beginning, floating signatures that can connect to different transactions. This has been originally proposed as a new Sighash flag for the signatures (the field that determines to which parts of a transaction is applied a signature). This was necessary for a signature of the transactions to cover the transaction of the transaction that created the spent output. This means that a signature is valid only for a transactions expenditure Exactly production.
This is a desired behavior for lightning because it would allow us to eliminate the penalty of the canal. Each state of lightning needs a key of penalty and transactions in order to ensure that the counterparty of the channel never uses any of them to try to claim funds they do not have. If they try, you can claim all their money. A higher functionality would be something that allows you to “attach” the current state transaction simply to any precedent to stop the attempt to theft by distributing the funds correctly instead of confiscating them.
This can be made with a basic script that takes a CTV hash and a signature on it that is controlled using CSF. This would allow any transaction hash signed by that CSFS key to spending any output created with this script.
Another useful feature is the delegation of the control of an Utxo. In the same way that any CTV hash signed by a CSFS key can validly spend a UTXO with a script designed for that, other variables can be passed to the script to be controlled, as a new public key. A script may be built that allows a CSFS key to sign Anyone Public key, which could therefore be validated using CSF and used for a normal checksig validation. This would allow you to delegate the ability to spend a UTXO to anyone else without having to move it to the chain.
Finally, in combination with Cat, the CSF can be used to compose much more complex introspection features. As we will see later in the series, however, CSFS is not actually requested to emulate anyone of this more advanced behavior, since the only cat is able to do it.
Closing thoughts
CSFS is a very simple OPDODE which, in addition to offering simple useful features in your right, also composes very well with the simplest alliance codes to create very useful features. While the above example relating to floating signatures refers specifically to the lightning network, floating signatures are a primitive generally useful applicable to any Bitcoin based protocol that use pre-operated transactions.
In addition to floating signatures, the screenplay delegation is a very useful primitive that generalizes well beyond the delegation of control over an UTXO to a new public key. The same basic capacity as “Sideload” variables after the fact in a script validation flow can apply to anything, not only public keys. Timellock values, the premes of the hashlock, etc. Any script that hardcode a variable from which to verify can now have such values added dynamically after the fact.
In addition, CSF are a very mature proposal. It has an implementation that has been live on the liquid network and on the elements (the US liquid codebase since 2016. Also Bitcoin Cash has a version of it since 2018.
CSFS is a very mature proposal that dates back conceptually as long as I have been in this space, with more mature implementations and very clear use cases to which it can be applied.