<p>Yes, this is possible in the Bitcoin Cash blockchain only. It would also be possible in OP_CODES, but much harder. </p>

<p>Here's how it works:</p>

<p>In the script signature, we check both OP_CHECKSIG and OP_CHECKDATASIG. First, OP_CHECKSIG goes "outside" and checks that the signature validates the transaction outputs. Thus, the <em>signature</em> variable has now been externally-verified to contain information from the transaction outputs.</p>

<p>In OP_CHECKDATASIG, we then verify that an input variable called "preimage" is the precursor to this exact "signature". Since digital signatures are unique, this pre-image must be the transaction itself. So, we now have a variable called <em>preimage</em>, that, transitively, is externally-verified to the transaction outputs. Coincidentally, this is also the raw transaction data containing the outputs.</p>

<p>Finally, we step through the preimage to determine the contents of the transaction before allowing spending. Very cool. (edited) </p>

CC BY-SA 4.0
2019-04-01T04:42:51.150Z
2019-04-01T04:42:51.150Z
nick carraway
<blockquote>
  <p>but in bitcoin usually the message is a hash of the previous transaction and the 'to' pubkey-hash and/or transaction? Unless i am missing something, the SIGHASH_SINGLE parameter specifically signs only the input and output of the new transaction. So, if you could create this input and output, and sign it inside an OP_CODE with a privatekey, you could verify that an output was going to a particular person inside a bitcoin script sig. Of course, the private key holding that UTXO would be unusable except for returning BTC to the user, or perhaps another pubkey could be used to spend the UTXO.</p>
</blockquote>

<p>This is incorrect. Transaction signing works by:</p>

<pre><code>for every input i in inputs:
    Start with a transaction skeleton that matches the transaction for non-input/output fields like tx version
    Add the input i
    Add other inputs and outputs based on the sighash flag
    Hash this update tx skeleton
    Sign the hash
</code></pre>

<p>The SIGHASH flags simplify specify which inputs and outputs are covered by the signature. For SIGHASH_ALL, the entire input and output set is signed. For SIGHASH_SINGLE, only the output corresponding to the index of the input is signed (for the first input in a tx, the first output will be signed). You also have additional options such as ANYONE_CAN_PAY which allow addition inputs to be added later, by only signing your input (for use with coinjoins).</p>

<p>By using <code>SIGHASH_ALL | SIGHASH_ANYONECANPAY</code> or <code>SIGHASH_SINGLE | SIGHASH_ANYONECANPAY</code> flags, if you already control an output, you can specify something such as:</p>

<pre><code>If this output is used as an input, at least X BTC must be sent to {these|this} new output(s).
</code></pre>

<p>However, this restriction only applies if the final transaction uses this specific signed input - nothing prevents you from creating another signed tx that spends that same output to a different destination and broadcasting it first.</p>

<p>Your example fails since within the signature, you have no information about the output. The data that is signed is that of an augmented tx skeleton as a whole - you cannot use Bitcoin Script to inspect a subset of that data and validate the signature.</p>

<p>To take the example another way, let us say we construct a bitcoin script equivalent to:</p>

<pre><code>Accept a signature and a public key
Verify that the signature is over the data (input,hash160(public_key)
Verify the signature is performed by the same key that unlocks the input being spent
</code></pre>

<p>This would seem to imply that we can sign the destination public key using the same private key that owns the input, and then have a script that validates both the tx signature, and the signature over the public key we claim to send to.</p>

<p>However, in this case, nothing prevents you from feeding a valid signature and destination public key to the script, but specifying a completely different output in the actual tx - This is because there is simply no way for the Bitcoin Script program to read and check where the tx output(s) are actually going.</p>

CC BY-SA 4.0
2019-03-30T04:17:22.537Z
Wait, really? I can sign a group of inputs, and a group of outputs. Where the inputs provides only 0.1 BTC from my accounts. And the outputs provide 10.0 BTC as output. (invalid tx) And If i sign it with "SIGHASH_ALL | SIGHASH_ANYONE_CAN_PAY", then the transaction will go through if someone adds inputs totaling 9.9 BTC? (And I understand that it would only apply to this signed input; I could rebroadcast if i wanted)
nick carraway
CC BY-SA 4.0
2019-03-30T04:18:37.830Z
Or can you still only sign valid TX like this?
nick carraway
CC BY-SA 4.0
2019-03-30T04:19:12.877Z
Yes, that's correct. You can construct a partial tx, with insufficient inputs or outputs and wait for other people to complete it. I wrote a blog post on this some time ago with more detail/examples, if you are interested: http://raghavsood.com/blog/2018/06/10/bitcoin-signature-types-sighash
Raghav Sood
CC BY-SA 4.0
2019-03-30T05:00:40.193Z
Thanks. I have been studying your blog post. It seems if I want people to be able to add outputs, the SIGHASH_SINGLE is the only way to do it. But this limits to a single output.  I wish that I could sign multiple outputs and still have someone else add outputs.
nick carraway
CC BY-SA 4.0
2019-03-30T05:49:44.570Z
You can, in a round about way. If you own n utxos, you can create a tx with n inputs, each signed with SIGHASH_SINGLE for their corresponding output (1 through n). Then, anyone else can add more outputs after the fifth one
Raghav Sood
CC BY-SA 4.0
2019-03-30T12:47:51.627Z
But wouldn't someone be able to degroup these transactions? I need to ensure that if one utxo is broadcasted, so is the other
nick carraway
CC BY-SA 4.0
2019-03-30T17:47:09.400Z
Please see: https://bitcoin.stackexchange.com/questions/85732/is-there-anyway-to-sign-a-pair-of-inputs-and-outputs-and-still-add-to-the-output
nick carraway
CC BY-SA 4.0
2019-03-30T22:11:46.807Z
This is exact stack exchange post is implemented in bitcoin cash https://honest.cash/pein_sama/spending-constraints-with-op_checkdatasig-172
nick carraway
CC BY-SA 4.0
2019-03-30T23:23:45.747Z
But I think your explanation still holds
nick carraway
CC BY-SA 4.0
2019-03-31T03:14:49.103Z
@nickcarraway OP_CHECKDATASIG is not available in Bitcoin, from what I recall. You might be able to use it on one of the forks, though.
Raghav Sood
CC BY-SA 4.0
2019-03-31T16:49:54.970Z
I think it's coming to lightning. Also, doesn't your explanation still hold? It's still just an unlocking script that takes information from the input stack and unlocks the coin. Just want to be sure
nick carraway
CC BY-SA 4.0
2019-03-31T16:55:35.650Z
Someone could still provide a fake signature that says the coins are going one place, where in the actual transaction they are going to the wrong place right?
nick carraway
CC BY-SA 4.0
2019-04-01T04:02:16.067Z
????????????????
nick carraway
CC BY-SA 4.0
2019-04-01T04:22:28.500Z
are you alive sir
nick carraway
CC BY-SA 4.0
2019-03-30T03:49:39.180Z
2019-03-30T03:49:39.180Z
Raghav Sood
<p>Edit; after writing this post i have found that <code>OP_CHECKDATASIG</code> is basically this in a nutshell. It is implemented on Bitcoin Cash and may soon be on Bitcoin Core as well.</p>

<p>Someone has even written this post into a Bitcoin Cash smart contract: <a href="https://honest.cash/pein_sama/spending-constraints-with-op_checkdatasig-172" rel="nofollow noreferrer">https://honest.cash/pein_sama/spending-constraints-with-op_checkdatasig-172</a></p>

<script><bitcoin-core-development><input-script>
Verifying a digital signature that a transaction is going to an output with value X inside a script
nick carraway
# Verifying a digital signature that a transaction is going to an output with value X inside a script

(Asked by: username_0 on 2019-03-30)

Edit; after writing this post i have found that `OP_CHECKDATASIG` is basically this in a nutshell. It is implemented on Bitcoin Cash and may soon be on Bitcoin Core as well.

Someone has even written this post into a Bitcoin Cash smart contract: <https://honest.cash/pein_sama/spending-constraints-with-op_checkdatasig-172>

**Tags:** script, bitcoin-core-development, input-script


---

## 2 answers

### Answer by username_0 on 2019-04-01. Score: 0 | Accepted answer

Yes, this is possible in the Bitcoin Cash blockchain only. It would also be possible in OP\_CODES, but much harder.

Here's how it works:

In the script signature, we check both OP\_CHECKSIG and OP\_CHECKDATASIG. First, OP\_CHECKSIG goes "outside" and checks that the signature validates the transaction outputs. Thus, the *signature* variable has now been externally-verified to contain information from the transaction outputs.

In OP\_CHECKDATASIG, we then verify that an input variable called "preimage" is the precursor to this exact "signature". Since digital signatures are unique, this pre-image must be the transaction itself. So, we now have a variable called *preimage*, that, transitively, is externally-verified to the transaction outputs. Coincidentally, this is also the raw transaction data containing the outputs.

Finally, we step through the preimage to determine the contents of the transaction before allowing spending. Very cool. (edited)


---

### Answer by username_1 on 2019-03-30. Score: 1

> but in bitcoin usually the message is a hash of the previous transaction and the 'to' pubkey-hash and/or transaction? Unless i am missing something, the SIGHASH\_SINGLE parameter specifically signs only the input and output of the new transaction. So, if you could create this input and output, and sign it inside an OP\_CODE with a privatekey, you could verify that an output was going to a particular person inside a bitcoin script sig. Of course, the private key holding that UTXO would be unusable except for returning BTC to the user, or perhaps another pubkey could be used to spend the UTXO.

This is incorrect. Transaction signing works by:

```
for every input i in inputs:
    Start with a transaction skeleton that matches the transaction for non-input/output fields like tx version
    Add the input i
    Add other inputs and outputs based on the sighash flag
    Hash this update tx skeleton
    Sign the hash

```

The SIGHASH flags simplify specify which inputs and outputs are covered by the signature. For SIGHASH\_ALL, the entire input and output set is signed. For SIGHASH\_SINGLE, only the output corresponding to the index of the input is signed (for the first input in a tx, the first output will be signed). You also have additional options such as ANYONE\_CAN\_PAY which allow addition inputs to be added later, by only signing your input (for use with coinjoins).

By using `SIGHASH_ALL | SIGHASH_ANYONECANPAY` or `SIGHASH_SINGLE | SIGHASH_ANYONECANPAY` flags, if you already control an output, you can specify something such as:

```
If this output is used as an input, at least X BTC must be sent to {these|this} new output(s).

```

However, this restriction only applies if the final transaction uses this specific signed input - nothing prevents you from creating another signed tx that spends that same output to a different destination and broadcasting it first.

Your example fails since within the signature, you have no information about the output. The data that is signed is that of an augmented tx skeleton as a whole - you cannot use Bitcoin Script to inspect a subset of that data and validate the signature.

To take the example another way, let us say we construct a bitcoin script equivalent to:

```
Accept a signature and a public key
Verify that the signature is over the data (input,hash160(public_key)
Verify the signature is performed by the same key that unlocks the input being spent

```

This would seem to imply that we can sign the destination public key using the same private key that owns the input, and then have a script that validates both the tx signature, and the signature over the public key we claim to send to.

However, in this case, nothing prevents you from feeding a valid signature and destination public key to the script, but specifying a completely different output in the actual tx - This is because there is simply no way for the Bitcoin Script program to read and check where the tx output(s) are actually going.

> **Comments:**
> **username_0**: Wait, really? I can sign a group of inputs, and a group of outputs. Where the inputs provides only 0.1 BTC from my accounts. And the outputs provide 10.0 BTC as output. (invalid tx) And If i sign it with "SIGHASH_ALL | SIGHASH_ANYONE_CAN_PAY", then the transaction will go through if someone adds inputs totaling 9.9 BTC? (And I understand that it would only apply to this signed input; I could rebroadcast if i wanted)  
> **username_0**: Or can you still only sign valid TX like this?  
> **username_1**: Yes, that's correct. You can construct a partial tx, with insufficient inputs or outputs and wait for other people to complete it. I wrote a blog post on this some time ago with more detail/examples, if you are interested: http://username_1.com/blog/2018/06/10/bitcoin-signature-types-sighash  
> **username_0**: Thanks. I have been studying your blog post. It seems if I want people to be able to add outputs, the SIGHASH_SINGLE is the only way to do it. But this limits to a single output.  I wish that I could sign multiple outputs and still have someone else add outputs.  
> **username_1**: You can, in a round about way. If you own n utxos, you can create a tx with n inputs, each signed with SIGHASH_SINGLE for their corresponding output (1 through n). Then, anyone else can add more outputs after the fifth one  
> **username_0**: But wouldn't someone be able to degroup these transactions? I need to ensure that if one utxo is broadcasted, so is the other  
> **username_0**: Please see: https://bitcoin.stackexchange.com/questions/85732/is-there-anyway-to-sign-a-pair-of-inputs-and-outputs-and-still-add-to-the-output  
> **username_0**: This is exact stack exchange post is implemented in bitcoin cash https://honest.cash/pein_sama/spending-constraints-with-op_checkdatasig-172  
> **username_0**: But I think your explanation still holds  
> **username_1**: @username_0 OP_CHECKDATASIG is not available in Bitcoin, from what I recall. You might be able to use it on one of the forks, though.  
> **username_0**: I think it's coming to lightning. Also, doesn't your explanation still hold? It's still just an unlocking script that takes information from the input stack and unlocks the coin. Just want to be sure  
> **username_0**: Someone could still provide a fake signature that says the coins are going one place, where in the actual transaction they are going to the wrong place right?  
> **username_0**: ????????????????  
> **username_0**: are you alive sir  

---

