On November 15th, the Bitcoin Cash network compatible with ABC and BU will do a network wide upgrade. One of the new features is a new opcode (operations code), OP_CHECKDATASIG, also known as DSV or CDS.
The new opcode verifies a message, returns true or false if the message is signed by the pubkey stated. This enables us to write something commonly referred to as an “oracle”. An oracle is a third party service that can be used as an authority for facts, statistics and data.
In practice, this means that the user spending an output will need to first get the oracle message and signature from the internet and put it in the ScriptSig.

The on-chain bet example

Let's imagine Bitcoin.com has an oracle that every day publishes the BCH price from markets.bitcoin.com. The data message is formatted as <4 byte price> and <4 bytes timestamp>, concatenated into a little endian byte array. This 8 byte message is then signed by the oracle's private key. The oracle publishes the price every even hour with the unix timestamp rounded for predictability.
Bob and Alice makes a wager of the price of BCH on November 1st at Midnight UTC 2018. Bob speculates the BCH price will be 500.00 USD or more and Alice speculates that the BCH price will be 499.99 USD or lower. They know that the Bitcoin.com oracle will publish the price every hour, so they can know for certain that the oracle will produce a message that states the BCH price on the exact time of 1541030400 (November 1st at Midnight UTC).
Bob and Alice agrees to use the following script to make this wager happen. They know the oracle’s public key, so they construct a P2SH redeem script that first splits the message from the oracle using OP_SPLIT, then verifies the timestamp using OP_CHECKLOCKTIMEVERIFY. If everything checks out, depending on the price value published by the oracle on the exact time of 1541030400 is 50000 or higher, it can be spent by Bob and not Alice. This allows both Alice and Bob to sign the redeem script before hand, there is no risk of double spent since only one of them can be valid and that depends on the outcome of the oracle’s message.
The script looks like this: ScriptSig: [<Bob_signature> | <Alice_signature>] [<Bob_pubkey> | <Alice_pubkey>] <oracle_signature> <oracle_message> Script: OP_DUP OP_TOALTSTACK # Duplicate the message, # put it on the alt stack <oracle_pub> OP_CHECKDATASIGVERIFY # Check message is signed # with oracle pubkey # If not signed by oracle, # invalidate the tx OP_FROMALTSTACK # Get the message from # alt stack 4 OP_SPLIT # Split the message 4 bytes # to the right 1541030400 OP_DUP # Duplicate the timestamp OP_TOALTSTACK # Put the duplicated # timestamp to alt stack OP_EQUAL OP_VERIFY # Compare that the # timestamp is equal # to the oracle message's OP_FROMALTSTACK # Get the timestamp from # alt stack OP_CHECKLOCKTIMEVERIFY # Check that timestamp we # need has passed OP_DROP # Drop timestamp from stack OP_BIN2NUM # Convert value from # oracle to compact number 50000 OP_GREATERTHANOREQUAL # Check if the value from # oracle is => 50000 OP_IF # Bob can spend using his signature and pubkey # if the price is >=50000 OP_DUP OP_HASH160 <bob_pubkeyhash> OP_EQUALVERIFY OP_CHECKSIG OP_ELSE # Alice can spend using his signature and # pubkey if the price is <50000 OP_DUP OP_HASH160 <alice_pubkeyhash> OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF
This script uses a number of new opcodes not included in Bitcoin Core (and some not even in Bitcoin 0.1). First is OP_CHECKLOCKTIMEVERIFY introduced by the Core developers, secondly we have OP_SPLIT and OP_BIN2NUM that was introduced in May 2018. The final new opcode is OP_CHECKDATASIG that will be activated on mainnet on November 15th, 2018.
You may wonder what is the function of OP_BIN2NUM. The bitcoin scripting language handles all numbers as compact numbers, that means that any zeroes that are not needed must be removed. For example, if you try to do any kind of math with numbers (big endian in this example) 0x00000001 and 0x00000002, the script interpreter will execute to the end with true as the last stack element, but still end up with the infamous “non-mandatory-script-verify-flag (unknown error)”.
This poses a problem for oracles. Since the users of oracle data needs predictability, they need to know exactly how future oracle data will be formed so their spend scripts can parse it properly. Otherwise they risk building a script that turns out to be unspendable. In our case, the BCH price published will always be 4 bytes, so for some time, it will use less than 4 bytes. If today’s BCH price is 440 USD, we would represent it as 44000 for the two decimals (that’s 0xABE0 in hex big endian). The oracle would publish it as 0x0000ABE0, which means that when you feed that into the bitcoind script interpreter, you will get an unknown error. By using OP_BIN2NUM, 0x0000ABE0 will be shortened down to 0xABE0 and the script will pass. Another important note to keep in mind is that the variable is signed, so if you are using one byte, you can only use numbers up to 128, as each additional 128 requires another byte.

The escrow example

Let’s try another more complicated script. The message being verified is in the case <0 or 1> <contract_id>. It’s a byte array where the first byte is the verdict, affirmed or denied. The rest is 4 bytes with the contract id.
The scenario is that an escrow creates a P2SH address, the buyer sends BCH to this address, and the seller will send the physical item to the buyer. In this case, there are two escrows the buyer and the escrow service. In most cases, the buyer will release the payment and confirm delivery by signing a message. If the buyer does not do this, the escrow service can step in and sign the message after reaching arbitration. OP_CHECKDATASIG returns true for correct signatures, and false if the signature is zero. This means that even if the escrow goes offline, we can spend this script by inserting 0 as the signature. In this example, the buyer signs it, and the escrow doesn’t need to do anything.
ScriptSig: <seller_tx_signature> <seller_pubkey> [empty array] <contract_message> <buyer_contract_signature> <contract_message> Script: OP_DUP # Duplicate the message OP_TOALTSTACK # Push it to the alt stack <buyerKey> OP_CHECKDATASIG # Check sig with message OP_IF # If the message is signed # by the pubkey OP_FROMALTSTACK # Get the message from altstack OP_1 OP_SPLIT # Split the last 4 bytes OP_BIN2NUM # Convert to compact number <contractIdBytes> OP_EQUAL # Check contract id OP_IF OP_BIN2NUM # Convert to compact number OP_1 OP_GREATERTHANOREQUAL # If the number is > 1 OP_IF OP_1 OP_TOALTSTACK # Push number 1 to altstack OP_ENDIF OP_ENDIF OP_ELSE # Else, push zero to the altstack OP_FROMALTSTACK # (we can’t push OP_0) OP_1 OP_1SUB OP_TOALTSTACK OP_ENDIF OP_DUP # Copy next contract message OP_TOALTSTACK # Push it to the alt stack <escrowKey> OP_CHECKDATASIG # Check the signature OP_IF OP_FROMALTSTACK # Get the message from alt stack OP_4 OP_SPLIT # Split out contract id and verdict OP_BIN2NUM # Make it a compact number <contractIdBytes> OP_EQUAL # Check contract id OP_IF OP_BIN2NUM # Make it a compact number OP_1 OP_GREATERTHANOREQUAL OP_IF # If the verdict is 1, get # current variable from altstack OP_FROMALTSTACK OP_1 OP_ADD # Add 1 OP_TOALTSTACK # Push it back to # the alt stack OP_ENDIF OP_ENDIF OP_ELSE # If the signature is wrong OP_FROMALTSTACK # Remove the message from altstack OP_DROP # and drop it. OP_ENDIF OP_FROMALTSTACK # Get the verdicts from the altstack OP_1 OP_GREATERTHANOREQUAL # Check if it’s >= 1 OP_IF # Then the seller can spend this OP_DUP OP_HASH160 <sellerAddress> OP_EQUALVERIFY OP_CHECKSIG OP_ELSE # Otherwise, the buyer can spend this after the time has run out <timeLock> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <buyerAddress> OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF
This is a quite large script compared to most scripts on the bitcoin network. We could make it even longer by adding more escrows (just copy paste the operations from the second escrow). The larger we make our scripts, the more errors and bugs we risk introducing. We are fortunate that OP_CHECKDATASIG can be carried out with one op-code. It’s still unclear if it’s even possible to do the exact same thing with just opcodes alone, but even if it is, we are talking about an extremely large script.
Please note that the scriptSig have an empty array pushed, which if using bitcoinj’s ScriptBuilder would be .data(new byte[0]). It’s worth mentioning that the altstack is used as extra memory. A CPU does have register and access to RAM, but when doing bitcoin scripting, we only have the ordinary stack and altstack. In this case, for each escrow we add 1 to the variable on the altstack. At the end of the script, we can check if the value stored on the alt stack is greater or equal to zero. If we add more escrows, we could require a higher value.

Difference between OP_CHECKDATASIG and OP_CHECKSIG

These two opcodes are actually very similar and nearly perform the same function. OP_CHECKDATASIG don’t use any scripthash and is just a plain EC key signature. While OP_CHECKSIG uses data from the transaction itself as the message, OP_CHECKDATASIG needs to get the message. This means that after signing a transaction that is supposed to be validated by OP_CHECKSIG, you can’t change the transaction without making it invalid. With OP_CHECKDATASIG, the transaction can be modified however you like without invalidating it. These two opcodes, despite being so similar, gives us two very different use cases that needs to be used appropriately. When making your script, you will need to combine both OP_CHECKSIG and OP_CHECKDATASIG to make sure that transactions can’t be modified on the fly. In our second example, the script ends with either making the seller or the buyer able to spend it after running the OP_CHECKDATASIG operations to validate the escrow data. The benefit is that the seller can spend without anyone stopping them. The seller doesn’t need to disclose where they send the transaction next to the escrow before signing. The escrow simply just signs the contract with a verdict and nothing else.

This is just scratching the surface

These are just two examples, there are many other uses cases of OP_CHECKDATASIG. There is Pay To Identity [2], Zero Conf Forfeit [3] already. We are sure this opcode will inspire a lot of innovation for permissionless payments and smarter contracts on-chain.

More reading:

[0] Andrew Stone's original proposal [1] Spec [2] Pay To Identity [3] Zero Conf Forfeit Transactions Donation address: bitcoincash:pp44u8f970zmsqxs96yhdxa83erlvxzqr5c0ukyl43 https://i.imgur.com/XgXmZLj.png
 

$11.25
$2.50

Reviews
3 of 3 reviewers say it's worth paying for

0 of 3 reviewers say it's not worth paying for
Comments
  earned 0.0¢
Wow!
0.0¢
   7mo ago
  earned $1.00
Seems completely worth a hash war and not focusing on building P2P cash for the world.....
$1.00
   7mo ago
25.0¢ 25.0¢ 25.0¢ 25.0¢
  earned 75.0¢
I look forward to seeing this get the attention it deserves.
75.0¢
   7mo ago
25.0¢ 25.0¢ 25.0¢
  earned 25.0¢
The betting example can easily be done using hash based signing.
What problem does the escrow example solve that can't be solved using just one or more 2-of-3 multisig addresses?
25.0¢
   7mo ago
25.0¢
  earned 0.0¢
@craigswright - HOW people use this is what may be of interest to the SEC. Just like CASH is not the subject of the investigation, but the tool to find those that break the "glorious" law. Even better if the company/merchant/etc ask for permission the government will be glad to "permit" them to use these features. They will not stop the innovation itself, but get their piece of the pie.
0.0¢
   7mo ago
  earned 0.0¢
@thomasbakketun its solves the "noob dev," "lack of dev," and "cost of dev" problem - what you introduce as "EASY" can add months to development process holding up the scarce resources of developers so that we can NOT quickly onboard the world. Developers then expect too much money for a simple project also scaring merchants/apps etc from introducing crypto into their project do to the extra costs. Finally a project that should take weeks will be extended to months, again keeping BCH from being the money of the world as the queue to BE A PART of grows bigger and bigger.
0.0¢
   7mo ago
  earned 0.0¢
@Robert Melluish
That is not true at all. Here, you can see how easy a binary oracle bet can be coded in Spedn language. OP_CHECKDATASIG is not needed for doing this in a simple way. https://twitter.com/dagur/status/1055407665415897089/photo/1?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1055407665415897089&ref_url=https%3A%2F%2Fs9e.github.io%2Fiframe%2Ftwitter.min.html%231055407665415897089 This whole article is a Rube-Goldberg machine to give a fake reason for OP_CHECKDATASIG in the upcoming hash war.
The escrow example is even more ridiculus. It provides nothing new and is much better done with an oldschool 2 of 3 signature.
Pay To Identity is just a trusted third party connecting a registered short name to an Xpub key.
Zero Conf Forfeit is also solving a problem that doesn't exist. While bitcoin ATM's have existed around the world for many years and payment processors look for doublespends with simple methods by using multiple nodes, devs gotta dev and come up with a UX getting close to the Lightning Network experience where you have to lock up money to spend money.
I'm surprised Emil is pumping this propaganda.
0.0¢
   7mo ago
  earned 25.0¢
@robertmelluish - "noob dev," "lack of dev," and "cost of dev" problem is bullshit. Unleashing the power of script is not an easy task. It requires higher level tools to be developed. Why haven't this been done yet? Because the risk is extremely high. Most useful scripts will hit the script size limit. Not because the scripts will be huge and many megabytes, but because the script size limit is currently very small, only a few hundred bytes.
"Build and they will increase the limit" is very risky. It might work, but it's also possible that sentiment that "big scripts are stupid" will prevail. The work on building the tools has then been wasted.
In order to get "devs" start working on building stuff on top of Bitcoin we need to ensure them they platform is ready. If limits are hit "everyone" will consider it important to fix the bottleneck ASAP. We are not there. The stress test showed that the network couldn't cope with more than about 20 MB blocks, significantly less then supposed 32 MB capacity. Instead of working on the actual bottlenecks, the stress test result are just ignored as irrelevant, because it was just a test. There is no real demand for such big blocks yet. How do the hell do they know that? Maybe someone that took the imitative to stress test did so because they have something ready for launch that would generate significant transaction volume.
25.0¢
   7mo ago
25.0¢
  earned 0.0¢
Robert Melluish you are the biggest wanker in history. The SEC dont care how its done, they care about the real world. if i program a bomb to go off, i would get charged for creating the bomb. The code leads to its destructive intent you dumb shit. OP_CHECKDATASIG will not happen, if you like it or not, the law DOESNT CARE.
0.0¢
   7mo ago
  earned 0.0¢
@steinhåvardludvigsen it is great that you are able to understand script so easily. I can say in a recent app I was working on it took me 3 weeks to produce the results I required and still have pretty much no clue what I did, as much of what I did was piggy backing off of "examples" on the internet. On day, I would love to truly "understand" the script language, but until then. Making things work for BCH apps is gonna take a lot of guess work.
0.0¢
   7mo ago
  earned 0.0¢
@thomasbakketun part 2: What? I am developing on BCH and even with 10 thousand additions to the BCH protocol BCH is ready for DEVS to be building on it. While I'm not great at it, I'm learning and working everyday to create great things on BCH. Bitcoin programming is far from easy and if the "good devs" that are actually creating additional innovations on Bitcoin to make it easier for me to do my job then I appreciate it. I dread reverting back to days before bip39/timelocks and even all the features that SN had added before his departure in feb 2013. If hitting a script limit is even fathomable by most devs - they are light years ahead of the "noob dev." We need things to be simple/fast and time saving. If a 3rd party solution provides the answer, that too is great, but if you neglect and stifle an option that is ALREADY READY and helpful then you are slowing up the entire Bitcoin experiment. Most of us broke away from BTC because they stifled innovation. We have returned to that same space - with promises of once we return to v 0.1(LN) people can build on top. I'm tired of waiting for it to be created - quit fucking up what has already been created and as long as NEW FEATURES do not affect the old then I could give a SHIT. The CASH feature of Bitcoin has worked since 2009 and ADDING new shit doesn't change that it just makes it easier to use.
0.0¢
   7mo ago
  earned 0.0¢
@Robert Melluish Did you look at the tweet from @dagur I linked to? Here is a direct link to the image of the Spedn script: https://i.imgur.com/gDkrVjn.jpg
0.0¢
   7mo ago
  earned 0.0¢
@steinhåvardludvigsen Looking at the pic and the code - It is very cool that someone put together a cool little Spedn library to make contractual bets- I would personally never use DSV for this particular example, and If I did need it I would hunt down this library(?) to make it easy on myself. I see many other uses for DSV than an illegal gambling bet, but in order for me to do that I would need to learn how to use things like op_dup op_if and much more internal scripts that I just don't have the time to include into my learning. Now if this individual were to create a million libraries that do all the possible DSV uses in the history of all future generations, then cool, cancel DSV - we don't need it.
0.0¢
   7mo ago
  earned 0.0¢
@Robert Melluish You are not making any sense to me now. What do you think DSV is?
0.0¢
   7mo ago
  earned 25.0¢
@robertmelluish - Anything is easy when you understand it. I find Bitcoin Script easy to understand, but that's probably because I have prior experience with stack based languages (RPL on HP48 calculator). If you want to learn more about stack based programming, I would suggest looking at Factor.
To say that Script is easy to understand is not the same as to say it's easy to use. The lack of functions and loops makes anything but trivial program difficult to program directly in Script. I consider Script a low level language, not intended for writing programs directly in. Instead you want to use high level tools.
With the help of such higher level tools, any noob dev can easily make a Script that hits the current limit of just a few hundred bytes. The limit is going to hurt noob devs the most. Some programs that hits the limit can be optimised in order to fit, but that no easy task. Optimisation requires a lot of knowledge. Early version of high level tools is likely to generate unnecessary big scripts. Over time the developers will figure out ways to optimise the generated programs. Better learning material will be written for new comers on how to best write programs in order to avoid big scripts.
Trying to build the high level tools into Script by regularly adding new high level constructs is not a good idea. This is analogous to keep adding new instructions to CPUs, instead of using high level programming languages and libraries. It's problematic for several reasons. Changing the CPU/Bitcoin base layer is expensive. Only the features that's considered most use will be included. This means that niche use cases has a huge disadvantage. Keep in mind that most things as a niche only considered useful by a small group.
Let me explain this by a real world example. I'm currently involved in developing a Bitcoin wallet using Java Card. It's the platform used by MasterCard and Visa cards, as well as many other smart cards. The main use case for this platform is security related applications. In order work as planned, the cards had to be powerful enough to do security related functions such as hashing, signing and encryption. The developers could have solved this in several ways.
  1. A generic processor powerful enough to execute software implementing the security algorithms.
  2. A fairly weak generic processor, but special support for the security algorithms considered important.
  3. A generic processor optimised for security related algorithms (i.e. modular arithmetic on big numbers).

They choose option 2. The consequences of this is that implementing a Bitcoin Wallet on the platform becomes challenging. The platform does support the signing algorithm used by Bitcoin, but it doesn't support deriving the public key from a private key. Based on good help from prior work by others, we have figured out how to this using a combination generic Java code and some high level constructs available. The way to do this is very far from trivial. It involves doing a Diffie-Hellman key exchange and a RSA encryption. That's just because those operation happens to do the mathematical operations we need to do to calculate the public key.
If they instead had choose option 1 or 3, the Java Card platform would have been a much more usable platform. It's most likely that there would have existed a library or code that we could reuse. Even if we would have to write the code our self, it would have been easier, because we wouldn't had to figure out tricks like using RSA encryption for a calculation that has nothing to do with RSA encryption at all.

Summary

  • Bitcoin Script is low level.
  • We need higher level tools for generating scripts.
  • High level tools is not easy to make.
  • It's easier to make a good high level for a platform with generic basic operations than one with many high level constructs.
  • Building on a constantly changing platform is costly.
  • Making the platform itself high level is costly.
  • A high level platform disfavours niche use cases.
  • Most uses cases starts as niche use cases.
  • Instead of adding a new opcode that might be useful, look for more generic improvements, that makes Script powerful enough to do the feature.
  • Bitcoin needs to be stable for people to invest in building tools for it.
  • Bitcoin needs to be stable for people to invest in building apps on top of it.
  • We need better tools and documentation for building apps on top of Bitcoin.
25.0¢
   7mo ago
25.0¢