LearnBitcoin

Bitcoin Dev Archive 2020

reviving op_difficulty

13 messages, 16 Aug to 2 Sep 2020. Started by Thomas Hartman.

Thomas Hartman (6), Tier Nolan (2), ZmnSCPxj (2), Anthony Towns, David A. Harding, Jeremy Rubin

Permalink Original thread on gnusha.org

Thomas Hartman permalink original

First, I would like to pay respects to tamas blummer, RIP.

https://bitcoinmagazine.com/articles/remembering-tamas-blummer-pioneering-bitcoin-developer

Tamas proposed an additional opcode for enabling bitcoin difficulty futures, on this list at

https://www.mail-archive.com/bitcoin-dev@lists.linuxfoundation.org/msg07991.html

I really like this idea.

1) Trusted third parties are security holes

https://nakamotoinstitute.org/trusted-third-parties/

and oracles (eg discreet log contracts) are really just trusted third parties in a blockchain's clothing. So truly ttp-free oracle-free on chain contracts are good.

2) Difficulty is a proxy for energy, which is a proxy for usd, which is what everyone currently cares about, which is bad. Energy is real. Bitcoin traders should care about future difficulty, not future usd price.

So in sum I think this is a very good idea, and I would like to continue this work. Ideally I would like to see to completion the BIP that Tamas was unable to produce.

Some initial thoughts on the technical merits.

My understanding is that adding a single op_difficulty operation as proposed would enable not true difficulty futures but binary options on difficulty.

https://en.wikipedia.org/wiki/Binary_option

As the wikipedia article notes, "While binary options may be used in theoretical asset pricing, they are prone to fraud in their applications and hence banned by regulators in many jurisdictions as a form of gambling." The trouble is that because of the all or nothing nature binary options are more of a gamble than a hedge. They are popular with scammers, and even licensed binary options exchanges such as nadex are under constant scrutiny by regulators.

Because any form of trusted third party-free / oracle free speculation would encourage economic use of blockchain space and support the transaction fee market, perhaps an economic case can be made for naive op_difficulty as above even it has more of a flavor of gambling than hedging. I think at a psychological level it would be good for a ttp-free difficulty speculation tool to capture mindshare.

That being said, true difficulty futures -- real hedging and not just gambling -- would be far healthier for bitcoin than binary options. I am trying to wrangle what additional opcodes and protocol changes would be required beyond just op_difficulty, to get true difficulty futures on chain.

I envision something like this. To give some context: Current difficulty is 16.9 Trillion. We're a week in to the current difficulty regime so there's aboout 1000 blocks to retarget, and predicted next difficuly is 18.5 Trillion. So let's pretend we sell a difficulty future that pays out in sats, of the next difficulty divided by a trillion. A reasonable price for this would be, say, 17.4 sats.

So in our op_difficulty utxo, one address (the futures buyer) would get current difficulty / trillion, and the other address (the seller) would get however much value is locked in the utxo, minus that amount and miner fee. The payout would be limited by however much value is locked in the utxo. Since difficulty adjusts very slowly I don't think overflowing the locked up value would be much of a problem in practice. We also want a mechanism to enable on-chain purchase of such a contract, say for 17.4 sats.

One additional opcode that apparently would be required is division. Some version of rshift could also do.

I am not clear if there is a way to solve the accounting for the payouts, but perhaps there is a way to do this with covenants.

I'm somewhat new to protocol and script. I would appreciate if anyone has any further advice on this.

Cheers, Thomas.

Tier Nolan in reply to Thomas Hartman permalink original

On Sun, Aug 16, 2020 at 4:50 PM Thomas Hartman via bitcoin-dev < bitcoin-dev@lists•linuxfoundation•org> wrote:

Quoted text (5 lines)
> My understanding is that adding a single op_difficulty operation as
> proposed would enable not true difficulty futures but binary options
> on difficulty.
>
> https://en.wikipedia.org/wiki/Binary_option

Any kind of opcode is a binary option. Either the output can be spent or it can't.

You could get a pseudo-continuous future by having lots of outputs with different thresholds.

Alice and Bob create a transaction with 100 outputs and each having 1% of the future's value.

Output 0: Pay Alice if diff < 1.00 trillion else Bob Output 1: Pay Alice if diff < 1.01 trillion else Bob .... Output 98: Pay Alice if diff < 1.98 trillion else Bob Output 99: Pay Alice if diff < 1.99 trillion else Bob

If the difficulty is 1.25 trillion, then Alice gets outputs 0-24 and Bob gets outputs 25-99. The future has a tick size of 1%. It isn't very efficient though

It would be good to have the option to specify a block height for the future too. If it triggered on block time, then miners have an incentive to give false block times.

I am not clear if there is a way to solve the accounting for the

Quoted text (2 lines)
> payouts, but perhaps there is a way to do this with covenants.
>

I agree you would need covenants or something similar.

There needs to be a way to check the outputs (value and script) of the spending transaction. You also need a way for Alice and Bob to create their spending transaction in sequence.

Output 0: Pay Alice if [output value 0] <= Diff / 1 trillion AND [output value 1] >= (2 trillion - diff) / (1 trillion) AND [output 1 pays to Bob]

To spend her output, Alice has to create a transaction which pays Bob and assigns the coins in the right ratio. [output value x] means the output value of the spending transaction for output x.

To get it to work Alice creates a transaction with these restrictions

Output 0: Script: Anything (Alice gets it to pay herself) Value: <= Diff / 1 trillion

Output 1: Script: Must pay to Bob Value: >= (2 trillion - Diff) / 1 trillion

You also need to handle overflows with the calculations.

Bob can then spend output 1 and get his money.

There is a hold-up risk if Alice doesn't spend her money. You can make the output script so either of them can spend their coins to avoid that.

Output 0:
    Pay Alice if [output value 0] <= Diff / 1 trillion AND [output value 1]
Quoted text (1 line)
>= (2 trillion - diff)  / (1 trillion) AND [output 1 pays to Bob]
      OR
    Pay Bob if [output value 0] <= (2 trillion - Diff) / 1 trillion AND
[output value 1] >= Diff / (1 trillion) AND [output 1 pays to Alice]

You would need a covenant-like instruction to check the output values and scripts and the diff opcode to get the difficulty.

Anthony Towns in reply to Thomas Hartman permalink original

On Sun, Aug 16, 2020 at 11:41:30AM -0400, Thomas Hartman via bitcoin-dev wrote:

Quoted text (3 lines)
> My understanding is that adding a single op_difficulty operation as
> proposed would enable not true difficulty futures but binary options
> on difficulty.

An alternative approach for this might be to use taproot's annex concept.

https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-5

The idea would be to add an annex restriction that's only valid if the difficulty is a given value (or within a given range). Protocol design could be:

  Alice, Bob, Carol, Dave want to make bets on difficulty futures
  They each deposit a,b,c,d into a UTXO of value a+b+c+d payable to
    a 4-4 of multisig of their keys (eg MuSig(A,B,c,D))
  They construct signed payouts spending that UTXO, all timelocked
    for the future date; one spending to Alice with the annex locking
    in the difficulty to Alice's predicted range, one spending to Bob
    with the annex locking in the difficulty to Bob's predicted range,
    etc

When the future date arrives, whoever was right can immediately broadcast their payout transaction. (If they don't, then someone else might be able to when the difficulty next retargets)

(Specifying an exact value for the difficulty rather than a range might be better; it's smaller/simpler on the blockchain, and doesn't reveal the ranges of your predictions giving traders slightly better privacy. The cost to doing that is if Alice predicts difficulty could be any of 100 different values, she needs 100 different signatures for her pre-signed payout, one for each possible difficulty value that would be encoded in the annex)

Cheers, aj

ZmnSCPxj in reply to Tier Nolan permalink original

Good morning Tier, Thomas, and aj,

Quoted text (21 lines)
> On Sun, Aug 16, 2020 at 4:50 PM Thomas Hartman via bitcoin-dev <bitcoin-dev@lists•linuxfoundation•org> wrote:
>
> > My understanding is that adding a single op_difficulty operation as
> > proposed would enable not true difficulty futures but binary options
> > on difficulty.
> >
> > https://en.wikipedia.org/wiki/Binary_option
>
> Any kind of opcode is a binary option.  Either the output can be spent or it can't.
>
> You could get a pseudo-continuous future by having lots of outputs with different thresholds.
>
> Alice and Bob create a transaction with 100 outputs and each having 1% of the future's value.
>
> Output 0:  Pay Alice if diff < 1.00 trillion else Bob
> Output 1:  Pay Alice if diff < 1.01 trillion else Bob
> ....
> Output 98:  Pay Alice if diff < 1.98 trillion else Bob
> Output 99:  Pay Alice if diff < 1.99 trillion else Bob
>
> If the difficulty is 1.25 trillion, then Alice gets outputs 0-24 and Bob gets outputs 25-99.  The future has a tick size of 1%.  It isn't very efficient though

Taproot MAST to the rescue.

* Alice and Bob agree on the number of ticks N and payout schedule.
* Alice and Bob generate N fresh keypairs and share them.
* Alice and Bob generate tapleaf scripts of the form:
  * script[i] = Alice[i] && Bob[i] && diff < 1.00 trillion + i * tick_size && CLTV(deadline)
* Alice and Bob generate the taproot MAST for the above scripts.
* Alice and Bob generate, but do ***NOT*** sign, a funding transaction paying out to the generated taproot MAST.
* Bob generates partial signatures for N payout transactions, with lower-difficulty-targets paying out less to Alice and more to Bob, and higher-difficulty-targets paying out more to Alice and less to Bob.
  * This requires spending the [i]th tapleaf script with the appropriate difficulty target.
* Alice saves all the Bob signatures.
* At deadline, Alice rationally selects the highest-paying version that is still acceptable, based on the actual difficulty target at the time.

This requires publishing only O(log N) data (the merkle path to the selected tapleaf). This translates to the 100-tick example requiring only one TXO, 1 scripthash, and 7 or so Merkle-tree-path hashes, compared to the above example which requires 100 TXOs and 100 script hashes.

The same scheme can be used with `OP_CTV` and without keypairs being involved, but basically anything `OP_CTV` can do, signing keypairs with pre-generated signatures from all participants can do just as well, with higher storage and setup costs.

Regards, ZmnSCPxj

Thomas Hartman in reply to ZmnSCPxj permalink original

Tier, AJ, ZmnSCPxj, thanks!

Quoted text (3 lines)
> On Aug 17, 2020, at 1:04 AM, ZmnSCPxj via bitcoin-dev <bitcoin-dev@lists•linuxfoundation•org> wrote:
>
> Taproot MAST to the rescue.

OK. So, using the tick scheme described by Tier a difficulty futures instrument is possible with current script + op_diff; and with taproot + op_diff (ZmnSCPxj) it may even be economical. (I will set aside covenants for now.)

To do it all on-chain, we need a mechanism for selling such an instrument in a trustless way.

That is to say (using ZmnSCPxj's construction), we have now a future where Bob pays Alice a pico-difficulty at next adjustment.

But how does Alice pay Bob his 17.4 sat?

I am trying to figure out a way to do this naively using the base layer. (I really want this with lightning, and eventually hft, but first things first.)

My thinking so far is, Alice and Bob collaborate to create partial versions of

** the difficulty future funded by Bob, spendable by Alice in 1000 blocks ** and a 17.4 sat payment from Alice to Bob, spendable by Bob immediately

When Bob completes and broadcasts the payment from Alice, it should enable Alice to complete and broadcast the difficulty future funded by Bob.

I am thinking a hash lock on the payment, with a preimage secret generated by Bob, could be used to accomplish this. When Bob unlocks and broadcasts the payment, this reveals the preimage, and with the preimage Alice can unlock and broadcast the difficulty future funded by Bob.

Am I correct in thinking something like this could work?

Tier Nolan in reply to ZmnSCPxj permalink original

On Mon, Aug 17, 2020 at 6:04 AM ZmnSCPxj <ZmnSCPxj@protonmail•com> wrote:

Quoted text (2 lines)
> Taproot MAST to the rescue.
>

Another option would be a binary payout

You pay 64 + 32 + 16 + 8 + 4 + 2 + 1 as outputs. The outputs are enabled/disabled based on the diff value. This would require division and also binary operators.

D = (int) ((100 * diff) / (1 trillion))

Output 0: 1.28: If (D & 128) then pay Alice otherwise Bob Output 0: 0.64: If (D & 64) then pay Alice otherwise Bob Output 0: 0.32: If (D & 32) then pay Alice otherwise Bob Output 0: 0.16: If (D & 16) then pay Alice otherwise Bob Output 0: 0.8: If (D & 8) then pay Alice otherwise Bob Output 0: 0.4: If (D & 4) then pay Alice otherwise Bob Output 0: 0.4: If (D & 4) then pay Alice otherwise Bob Output 0: 0.4: If (D & 4) then pay Alice otherwise Bob

This has log performance in terms of the number of ticks like the MAST solution.

ZmnSCPxj in reply to Thomas Hartman permalink original

Good morning Thomas,

Quoted text (26 lines)
> Tier, AJ, ZmnSCPxj, thanks!
>
> > On Aug 17, 2020, at 1:04 AM, ZmnSCPxj via bitcoin-dev <bitcoin-dev@lists•linuxfoundation•org> wrote:
> >
> > Taproot MAST to the rescue.
>
> OK. So, using the tick scheme described by Tier a difficulty futures instrument is possible with current script + op_diff; and with taproot + op_diff (ZmnSCPxj) it may even be economical. (I will set aside covenants for now.)
>
> To do it all on-chain, we need a mechanism for selling such an instrument in a trustless way.
>
> That is to say (using ZmnSCPxj's construction), we have now a future where Bob pays Alice a pico-difficulty at next adjustment.
>
> But how does Alice pay Bob his 17.4 sat?
>
> I am trying to figure out a way to do this naively using the base layer. (I really want this with lightning, and eventually hft, but first things first.)
>
> My thinking so far is, Alice and Bob collaborate to create partial versions of
>
> ** the difficulty future funded by Bob, spendable by Alice in 1000 blocks
> ** and a 17.4 sat payment from Alice to Bob, spendable by Bob immediately
>
> When Bob completes and broadcasts the payment from Alice, it should enable Alice to complete and broadcast the difficulty future funded by Bob.
>
> I am thinking a hash lock on the payment, with a preimage secret generated by Bob, could be used to accomplish this. When Bob unlocks and broadcasts the payment, this reveals the preimage, and with the preimage Alice can unlock and broadcast the difficulty future funded by Bob.
>
> Am I correct in thinking something like this could work?

Bitcoin transactions on the blockchain layer are atomic, so it would be far simpler to make the purchase output and the options output in the same transaction, in a sort of PayJoin-like cooperatively-signed transaction.

That said, the construction you are imagining is indeed going to work. The only requirement is that the hash-branch needs two signatures in order to ensure that it pays out to a transaction with a very specific contract. Xref. how Lightning *really* creates its HTLCs.

Regards, ZmnSCPxj

Thomas Hartman in reply to Tier Nolan permalink original
Quoted text (3 lines)
> On Aug 16, 2020, at 2:59 PM, Tier Nolan via bitcoin-dev <bitcoin-dev@lists•linuxfoundation•org> wrote:
>
> Output 0:  Pay Alice if diff < 1.00 trillion else Bob

What is included in blocks is a packed representation of the difficulty target, not the difficulty per se as typically reported on blockchain explorer.

https://en.bitcoin.it/wiki/Difficulty <https://en.bitcoin.it/wiki/Difficulty>

Perhaps what is best for speculation contracts is not the difficulty per se, but the ratio between some unknown future difficulty and the current difficulty. That is easily obtained from the packed representations already included in blocks. IE

Current difficulty / last difficulty = 1 / ( current target / last target )

To give a worked example, current difficulty is 16.94T, and last difficulty was 16.84T. Current packed target is 0x17109bac, last packed target is 0x1710b4f8 16.94 / 16.84 is same as 1 / ( 0x109ba / 0x10b4f8 ) (the 17 is an exponent in both cases so leaving it out for clarity).

So perhaps the way op_diff should work is take 2 packed targets, 1 known and 1 unknown at time of contract, and return the ratio.

The contract could then work as previously described, except using the ratio for ticks instead of the difficulty.

Thomas Hartman in reply to Thomas Hartman permalink original
Quoted text (2 lines)
>
> So perhaps the way op_diff should work is take 2 packed targets, 1 known and 1 unknown at time of contract, and return the ratio.

On second thought, I don’t think this is a good idea. The 32-bit packed difficulty target is equivalent to difficulty, and this is probably what should get pushed onto the stack. No division is needed, just the arithmetic less than operator, which is already live in script, using the tick strategy described by Tier. So it seems to me these contracts could truly be done with the addition of the single op_diff opcode. It’s probably less human readable to be using difficulty target instead of difficulty, but no one reads script anyway.

It was also bothering me that difficulty was a floating point number (I have floating point phobia), so it is great not to have to think about floats anymore!

David A. Harding in reply to Thomas Hartman permalink original

On Sun, Aug 16, 2020 at 11:41:30AM -0400, Thomas Hartman via bitcoin-dev wrote:

Quoted text (3 lines)
> First, I would like to pay respects to tamas blummer, RIP.
>
> https://bitcoinmagazine.com/articles/remembering-tamas-blummer-pioneering-bitcoin-developer

RIP, Tamas.

Quoted text (4 lines)
> Tamas proposed an additional opcode for enabling bitcoin difficulty
> futures, on this list at
>
> https://www.mail-archive.com/bitcoin-dev@lists.linuxfoundation.org/msg07991.html

Subsequent to Blummer's post, I heard from Jeremy Rubin about a scheme[1] that allows difficulty futures without requiring any changes to Bitcoin. In short, it takes advantage of the fact that changes in difficulty also cause a difference in maturation time between timelocks and height-locks. As an simple example:

1. Alice and Bob create an unsigned transaction that deposits their
   money into a 2-of-2 multisig.
2. They cooperate to create and sign two conflicting spends from the multisig:
    a. Pays Alice with an nLockTime(height) of CURRENT_HEIGHT + 2016 blocks
    b. Pays Bob with an nLockTime(time) of CURRENT_TIME + 2016 * 10 * 60 seconds
3. After both conflicting spends are signed, Alice and Bob sign and
   broadcast the deposit transaction from #1.
4. If hashrate increases during the subsequent period, the spend that
   pays Alice will mature first, so she broadcasts it and receives that
   money.  If hashrate decreases, the spend to Bob matures first, so he
   receives the money.

Of course, this basic formula can be tweaked to create other contracts, e.g. a contract that only pays if hashrate goes down more than 25%.

As far as I can tell, this method should be compatible with offchain commitments (e.g. payments within channels) and could be embedded in a taproot commitment using OP_CLTV or OP_CSV instead of nLockTime.

-Dave

[1] https://powswap.com/
Thomas Hartman in reply to ZmnSCPxj permalink original

This is in reply to David harding’s message at

https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-August/018129.html <https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-August/018129.html>

(For some reason didn’t arrive in my inbox, so I was late noticing it, and I am replying in this way. Sorry if it screws up threading.)

Powswap sounds great! And it doesn’t require any protocol changes! Very cool.

One potential problem I see with powswap is iiuc you need something like watchtowers, or the loser of the bet can sweep the funds if the winner is napping. Related, I’d also like to have trades happening in lightning channels, and I’m not sure how this race affects the security assumptions there.

Further question about powswap.

It’s currently block 64632 with retarget in 808 blocks. I’d like to bet that

* the first 6 blocks after the retarget are found in under an hour
* AND the new difficulty exceeds some threshold. Is such a bet currently possible with powswap?

I see how pow swap lets you bet on hashrate (ie block times) from current time till some future time. But I would like to also bet on hashrate of slices of time in the future. Possible?

Thomas Hartman in reply to Thomas Hartman permalink original

Replying to myself:

IIUC, Powswap seems to only create contracts from current time to future time.

But, you can create synthetic hashrate binaries for time span in the future time A to time B, using powswap, by subtracting

(current time to B) - (current time to A)

IE, buy first, sell second.

On Tue, Sep 1, 2020 at 4:07 PM Thomas Hartman <thomashartman1@gmail•com> wrote:

Quoted text (21 lines)
>
> This is in reply to David harding’s message at
>
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-August/018129.html
>
> (For some reason didn’t arrive in my inbox, so I was late noticing it, and I am replying in this way. Sorry if it screws up threading.)
>
> Powswap sounds great! And it doesn’t require any protocol changes! Very cool.
>
> One potential problem I see with powswap is iiuc you need something like watchtowers, or the loser of the bet can sweep the funds if the winner is napping. Related, I’d also like to have trades happening in lightning channels, and I’m not sure how this race affects the security assumptions there.
>
> Further question about powswap.
>
> It’s currently block 64632 with retarget in 808 blocks. I’d like to bet that
>
> * the first 6 blocks after the retarget are found in under an hour
> * AND the new difficulty exceeds some threshold. Is such a bet currently possible with powswap?
>
> I see how pow swap lets you bet on hashrate (ie block times) from current time till some future time. But I would like to also bet on hashrate of slices of time in the future. Possible?
>
>
Jeremy Rubin in reply to David A. Harding permalink original

Yep this is a good example construction. I'd also point out that modulo a privacy improvement, you can also script it as something like:

IF IF <T> CLTV B DROP CHECKSIG ELSE <T2> CLTV DROP A CHECKSIG ENDIF ELSE 2 A B 2 CHECKMULTI ENDIF

This way you equivalently have cooperative closing / early closing positions, but you make the redeem script non-interactive to setup which enable someone to pay into one of these contracts without doing pre-signeds. This is unfortunate for privacy as the script is then visible, but in a taproot world it's fine.

Of course the non interactivity goes away if you want non-binary outcomes (e.g., Alice gets 1.5 Coin and Bob gets .5 Coin in case A, Bob gets 1.5 Coin Alice gets .5 coin in Case B).

And it's also possible to mix relative and absolute time locks for some added fun behavior (e.g., you win if > Time and > Blocks)

A while back I put together some python code which handles these embedded in basic channels between two parties (no routing). This enables you to high-frequency update and model a hashrate perpetual swap, assuming your counterparty is online.

The general issue with this construction family is that the contracts are metastable. E.g., if you're targeting a 100 block deficit , that means you have 100 blocks of time to claim the funds before either party can win. So there's some minimum times and hashrate moves to play with, and the less "clearly correct" you were, the less clearly correct the execution will be. This makes the channel version of the contract compelling as you can update and revoke frequently on further out contracts.