Discreet Log Contracts: invisible smart contracts on the Bitcoin blockchain
On May 19, 2018, MIT’s Digital Currency Initiative and Fidelity Labs and organized the Layer 2 Summit in Boston. During this event, two people from the DCI, Tadge Dryja (Research Scientist) and Gert-Jaap Glasbergen (Software Developer), gave a presentation and demonstration on Discreet Log Contracts. The paper on Discreet Log Contracts is written by Tadge Dryja and published in 2017.
In this blog post, we’ll try to further explain what Discreet Log Contracts are, how they work, and what the next steps are if you’re interested in leveraging this technology.
What are Discreet Log Contracts?
By creating a Discreet Log Contract, Alice and Bob can form a monetary contract redistributing their funds to each other, based on preset conditions, without revealing any details of those conditions to the blockchain. Alice and Bob both commit funds to the contract, but its appearance on the blockchain will be no different than an ordinary multi signature output. Therefore the contract is discreet in the sense that no external observer can learn its existence or details from the public ledger.
This contract depends on an external entity or entities, known as an oracle, that publishes a signed message at some point in the future (before the expiration of the contract). The contents of this signed message determine the division of the funds committed to the contract.
Oracles are not aware of the contracts or people using its data, they independently publish their signed messages according to a preset schedule. These signatures are incorporated into the contract by Alice and Bob, without the oracle being aware of them using it.
Because the oracle is not aware of specific contracts using the data, it is not able to decide the outcome of a specific contract. This is an important difference from a situation where the oracle is the third party in a 2-of-3 multi signature setup.
Oracles provide the connection between the blockchain and the external world — and are therefore trusted to provide accurate data. There are ways to minimize the dependency on this trust, which we’ll discuss later.
Using Discreet Log Contracts, the signature published by the oracle gives each participant of the contract the possibility to claim the amount from the contract that is due him or her without the need for cooperation from the other party.
How can I use Discreet Log Contracts?
The most obvious use case for Discreet Log Contracts, which is also described in the paper, is a bitcoin-settled forward contract. Forward contracts are customized contracts between two parties to buy or sell an asset at a specified price on a particular date in the future. Forwards are a very common instrument to hedge against volatility. So using US Dollar forwards someone can hedge the volatility in the US Dollar to bitcoin exchange rate. Clearly, this can be used to hedge other currencies as well, such as Yen, Euros, or Rubles.
You could also engage in forwards on other assets like gold, wheat, coffee. As long as there is an oracle that publishes a price, you can build forward contracts on that using Discreet Log Contracts.
This opens up huge opportunities for a bitcoin economy. Since the main reason for businesses not to go with bitcoin as their base currency is that their purchases are all in fiat, and they can’t risk the volatility of bitcoin against that. A forward contract in essence can provide a solution to that problem. By engaging in a forward contract, you can preserve the fiat-value of (parts of) your bitcoin holdings.
Example: US Dollar forward contract
For instance: Alice can engage in a US Dollar forward contract with Bob. Alice agrees to buy 5000 US Dollar from Bob, at 12500 satoshi (=0.000125 BTC) per Dollar, which equals 8000$ per BTC, on the last Friday of the month at 5:00 PM. In this example, the US Dollar is the ‘asset’, and the price is denominated in bitcoin.
Alice engages in this contract because she has future obligations to deliver US Dollar (for instance: to pay bills), and wants to mitigate the volatility risk. This contract will entitle her to 5000 US Dollar at the time the contract expires, regardless of the US Dollar to bitcoin exchange rate at that time.
On the other hand, Bob expects the value of bitcoin to increase, hence he expects the market rate for 5000 US Dollar in bitcoin to be lower than what Alice agreed to pay. Bob engages in this contract to turn a profit at the time the contract expires.
Since the contract is bitcoin-settled this means that, like cash-settlements in normal asset forwards, instead of Bob actually delivering US Dollars to Alice, parties will pay each other the difference between the agreed price and the market price in bitcoin.
So if the US Dollar appreciates, Bob will have to pay Alice the difference. Similarly, if the US Dollar depreciates, Alice will have to pay Bob.
Alice and Bob commit the funds for paying each other upfront. This payment is locked in a 2-of-2 multi signature output that is controlled by Alice and Bob’s private keys. Before committing the funds, they exchange the transactions necessary for spending the funds based on the values the oracle will announce. This way, before committing the funds, they know the funds they are entitled to can be retrieved. This also means that the payment is limited to the amount both parties agree to lock up in the contract.
How does it work?
In our previous example:
Alice agrees to buy 5000 US Dollar from Bob, at 12500 satoshi (or 0.000125 BTC) per Dollar (which equals 8000$ per BTC), on the last Friday of the month at 5:00 PM
Step 1: Find an oracle. The first thing we need, is an oracle that will publish the value of the US Dollar, measured in satoshi, on the last Friday of the month at 5:00 PM. This oracle provides the public key with which it will sign this message.
Step 2: Create funding transaction. The parties will then construct a transaction funding the contract from the coins in their wallets. Both parties contribute the same amount of coin into the contract. The contract will be a 2-of-2 multi signature output, meaning both Alice and Bob will have to sign any transaction that spends from it. The contract is funded with [asset quantity * asset price] , so in this case 5,000 * 0.00125 = 0.625 BTC each.
Using the exchanged outpoint information, both parties can create one single transaction that funds the contract from both their wallets at once. Eventually they will have to sign their respective inputs to that transaction, but they don’t do that yet. Now that the transaction is created though, the transaction ID can be determined. Since the signatures are not part of the ID, signing it won’t change that ID.
Since we now know the ID of the funding transaction, we can already craft transactions that spend from the contract without it actually being on the blockchain, which is exactly what the next step is.
Step 3: Create all possible execution transactions. For each possible value the oracle can publish, a Contract Execution Transaction is created. A Contract Execution Transaction is a transaction that spends the funds locked in the contract (in the 2-of-2 multi signature output) to outputs that can be claimed by Alice or Bob. It divides the contract funds in the way the participants agreed to.
These transactions spend the contract funds to two outputs: One can be claimed by Alice and the other by Bob. How much is in each of them is determined by the price of the US Dollar. If either party would receive zero, the output is omitted.
An important part of this is that the transaction that Alice signs and Bob keeps, does not spend the amount Bob’s entitled to directly to Bob’s wallet (otherwise he could just sign it, broadcast it right after the contract is funded and capture the funds without waiting for any oracle signature). The transaction spends to a combination of Bob’s public key and the public key to the oracle’s signature. That way, Bob can only claim the funds due him using the oracle’s signature of the correct value, which he can’t falsify.
A second addition is that Bob’s due amount can also be spent by Alice, after a timeout. This is to mitigate the risk that if Bob publishes any Contract Execution Transaction other than the correct one, no one can claim the funds. If the published value by the oracle is 12500, and Bob publishes the transaction belonging to 12600 (of which no one has the oracle’s signature) — Alice can claim Bob’s funds after the timeout. So by publishing the wrong transaction, Bob essentially forfeits all the contract funds to Alice.
Since publishing the wrong transaction forfeits all the funds to the other side, either party should ensure they have the correct oracle signature prior to publishing a Contract Execution Transaction. Since these signatures are easily verifiable, no one should be able to get ‘tricked’ into publishing the wrong transaction.
So, when the value published by the oracle is 12500, parties receive back what they funded since the value is exactly the agreed price: no party has to pay the other the difference since there is none. The Contract Execution Transaction that Alice signs and gives to Bob for that looks like this:
However, if the price changed to 14000 satoshi ($7142,85 per BTC), Bob needs to pay Alice the difference of 5000 * 1500 satoshi, or 0.075 BTC. So the Contract Execution Transaction that Alice signs looks like this:
Alice and Bob can create all Contract Execution Transactions for all possible satoshi values.
Step 4: Exchange signatures to the Contract Execution Transactions. Once all these Contract Execution Transactions are crafted, both parties exchange the signatures to these transactions, but they don’t publish any of them yet. They verify their correctness, at which point they can safely exchange the signatures to the funding transaction, since they know they have a way to claim the contract funds.
Step 5: Exchange signatures to the funding transaction. Now that each party can claim funds from the contract, they are safe to exchange signatures to the transaction that funds the contract from their wallet.
Step 6: Publish the funding transaction to the blockchain. Now that the funding transaction is signed, either party can publish the signed funding transaction to the blockchain.
Step 7: Settle the contract. At the time the oracle publishes the value, either of the participants can publish the correct Contract Execution Transaction that spends from the contract. The party that publishes the transaction, should then claim the output that spends to the combined key back to their wallet — using the oracle signature combined with their private key to sign it. This prevents the other party from spending it after the time delay.
What are potential other use cases?
The forward contract is a pretty straightforward use case that fits this technology well. But essentially any value that an oracle can produce can be used in forming these kinds of contracts. For instance, you could create an insurance contract that automatically pays out a claim based on a value (weather data, flight delay data) that comes from an oracle. If an oracle would announce the country that won a world championship in any kind of sport, you could facilitate a simple betting contract based on it.
Basically any situation where funds need to be divided based on an external future value can be enforced using Discreet Log Contract technology.
What are the limitations / challenges?
We have currently identified a couple of issues that can be improved in the prototype we built:
- Contract collateral — Since the contract funds have to be committed in advance, there’s a limit to the price difference it can handle. In our example, if the price goes above 25000 satoshi per dollar (hence below 4,000$ per BTC), Alice will receive all the BTC in the contract, but it might no longer be worth 5000$. This can be prevented by both parties funding more money, but there’s a downside to that too since the funds are locked.
- Number of signatures— Especially in the Dollar forward use case, we’ve seen that dividing and signing transactions for each individual possible value can lead to enormous numbers of signatures that need to be exchanged. Since, if the oracle ends up giving us a value outside of the range we signed, there’s no way to claim the funds back (except for both parties signing a transaction again). The paper already describes a possible solution to this, but this has not been implemented yet. We could split up the value into an exponent and mantissa. In stead of signing 12500, the oracle will sign “.25” and 4 (1.25*10⁴). The decimal base and mantissa’s leading 1 are implied. We use both signatures’ public keys in the spending transaction. Now, in our example, we can make the transactions for values 100,000 and up just use the exponent signature and leave mantissa out. So with only 5 signatures extra, we can allow for values between 10⁵ and 10⁹ saving us a billion signatures.
- Risk of trusted oracle — When forming these contracts, you’re relying on the oracle to give you the correct value. Even more so, if the oracle decides to give you an R-point but never signs any message (and vanishes), you are stuck with a contract that can only be settled with your counter party cooperating. This risk can be somewhat mitigated by using multiple oracles. Using multiple oracles is possible by adding both oracle’s R-points together in the contract execution transactions.
- Novation — The current setup does not allow for swapping one of the parties for someone else. This might be useful in the situation where Bob wants to settle the contract early. If Alice disagrees with that, it might be an option to offer Alice a small fee to sign the Contract Execution Transactions again under the exact same conditions, except with Carol’s public keys in stead of Bob’s. This might be subject to further research.
- Matching — Right now the proof-of-concept does not include order matching. Bob and Alice already found each other and set up the contract after agreeing on the terms. It might make sense to allow for some form of marketplace to match people that want to engage in these kinds of contracts. Centralized marketplaces already exist, and could find a way to incorporate DLCs in their portfolio. A decentralized marketplace might be subject to further research.
Interesting, so how do I use it?
At this time, the software we produced is not ready for production usage. It is merely a proof-of-concept. We think this might be very interesting technology for a broad range of use-cases, and the detailing we did in this blog post might have interested you.
Creating an oracle
If you have an interesting data feed that might be useful for people to use in their contracts, consider making an oracle out of it. We created a library for that exact purpose. Check out one of the tutorials available. We created one for Go, NodeJS and .NET Core
Essentially, you pre-commit to publishing the data feed’s value at a particular time in the future by publishing the public key, and you publish the values and signatures once the publication is due.
Right now, the publication could just be on a plain website. We are still working on a standardized publication mechanism. If a standard is decided we will add this to the library.
Executing Discreet Log Contracts
You can execute Discreet Log Contracts using lit, the Lightning Network implementation that the DCI is working on.
You can find a tutorial on setting up an environment consisting of two lit nodes and a Bitcoin Regtest here.
Here is a tutorial on executing a Discreet Log Contract from lit’s console client (lit-af).
We also have a RPC Client for LIT in Go, NodeJS and .NET Core that you can use to execute Discreet Log Contracts from your own software. Samples on how to do that are also available in Go, NodeJS or .NET Core.
If you have any ideas, suggestions, questions, feel free to contact us through e-mail