3

Is there a way to use Bitcoin script to force payment for the receiver?

I do not mind if it's a non-standard transaction, just curious if Bitcoin script itself allows expression of something like that.

For example, is it possible to write a locking script such that:

  1. Alice sends 1 BTC to Bob
  2. But Bob can ONLY spend if Bob sends 0.5 BTC to Carol in the next transaction

3 Answers 3

4

No, that is not possible, and doing so can be problematic.

Such scripts would need the ability to inspect the spending transaction and this is currently not allowed or possible; the script interpreter does not have access to other parts of the transaction.

Furthermore, if implemented naively, this could allow for widespread censorship and centralized control of Bitcoin. In essence, such scripts could be written to require that transactions do not send money to some blacklisted addresses, and at the same time require that all receivers in that transaction also have this same requirement. This could lead to services blacklisting some addresses, and then forcing their users to also blacklist those addresses when they withdraw from the exchange. And the recursive nature of that means that all subsequent transactions also have the same blacklist.

1
  • Sounds a bit like copyleft or share-alike licenses.
    – ComFreek
    Commented Nov 26, 2020 at 8:40
4

While Bitcoin does not currently have any covenants, BIP119: Checktemplateverify proposes a new op-code that would allow you to do exactly that.

The proposal is currently in "draft" status.

3

TL;DR: Can be done with

                                                      ____  pk_B
       ____                                          |    |------->
Alice |    |2-of-{pk_A, pk_B}      2-of-{pk_A, pk_B} |    |  0.5
----->|tx_1|------------------>    ----------------->|tx_2|
  1   |____|         1                               |    | pk_C
                                                     |____|------->
                                                             0.5

There is currently no such script. You can do it though with a little protocol and two transactions:

  1. Alice knows Bob's and Carol's keys (pk_B, pk_C). Bob knows Alice's and Carol's keys. Alice and Bob have already agreed to do this kind of payment out-of-band.
  2. Alice creates tx_1 that spends her 1 BTC and has a single (1, 2-of-{pk_A, pk_B}) output [where the output is (coins, script) and n-of-{m public keys} is an n-of-m-multisig]. She does not broadcast tx_1 yet.
  3. Alice creates tx_2 with a 2-of-{pk_A, pk_B} input that spends tx_1 and two outputs: (0.5, pk_B), (0.5, pk_C). She signs tx_2 with her sk_A and sends the signature, sig_A, to Bob.
  4. Bob recreates tx_2, verifies sig_A with pk_A and replies "OK" to Alice.
  5. Alice broadcasts tx_1.
  6. Bob signs tx_2 with his sk_B, adds the two signatures to tx_2 and broadcasts it.

The only way for Bob to get any coins is if he uses Alice's signature, which is valid only for tx_2, which splits Alice's coin equally among Bob and Carol. So Bob is incentivized to play along.

The drawbacks compared to a single script are that

  1. Alice and Bob must establish a communication channel,
  2. Bob must save Alice's signature and use it later,
  3. If Bob doesn't publish tx_2, the money is stuck,
  4. Two transactions are needed instead of one.

You can avoid the first two issues by having Alice put sig_A in an additional OP_RETURN in tx_1. OP_RETURN is big enough to fit sig_A and tx_1 will still be standard. Making sig_A public is secure because only Bob can create the other signature needed to spend tx_1. The third issue can be avoided by adding a timelock to the output of tx_1, after which Alice can spend the coin as she pleases. I don't see any way to avoid the last issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.