We invent a technique, called opportunistic contract, to faithfully execute any smart contract in a regular payment (P2PKH) transaction. It drastically improves the privacy and efficiency of arbitrary multiparty smart contract, when all parties cooperate.
We illustrate how opportunistic contract works between two parties. It can be extended to multiple parties trivially. In a typical contract with two parties, the workflow is as follows:
Alice and Bob each deposits into the contract. After the contract execution, it splits the output to Alice and Bob according to the logic of the contract¹. The execution can be triggered by the release of, for example, a hash preimage, a signature, or a result of a sports game signed by an oracle.
We modify the workflow as below:
Instead of depositing directly into the contract, we first deposit into a joint address, which can only be unlocked if both parties sign. After that, the joint fund is locked into the contract.
At first glance, this extra step seems redundant and only add complexity. The key idea is that the contract transaction (tx2) is not broadcasted and held off-chain by Alice and Bob. The contract is executed off chain. If Alice and Bob agree on the outcome, they can both sign a new transaction tx2' and spend tx1.
This has the same effect as broadcasting tx2 and tx3, in terms of how many bitcoins Alice and Bob receive, but with two benefits.
- privacy: all transactions (tx1 and tx2') look the same as a regular payment (P2PKH) transaction. An outside party is not even aware there is a hidden underlying contract.
- efficiency: regardless of how complex and large the contract is, only two payment transactions end up on the blockchain, saving enormous miner fees.
When either party is uncooperative and refuses to sign tx2', the other party can always broadcast pre-signed tx2 and terminate the contract in tx3. The recourse option incentivizes all parties to cooperate.
In tx1, we use a 2-of -2 threshold signature scheme (TSS):
- A joint public key is generated
- To unlock it, Alice and Bob both have to sign separately. A joint signature combining both signatures is valid for the joint public key.
From the outside, the joint public key and signature look the same as a regular public key and signature. Amazingly, the private key corresponding to the joint public key does not have to exist when signing, avoiding single point of failure.
A detailed explanation of how TSS works on ECDSA² is outside the scope of this article. Interested readers can read this whitepaper from nChain and this. TSS has been demonstrated here and been extensively used in production wallets such as HandCash and Volt.
Nakamoto Signing Protocol
A naive way to follow the workflow in Figure 2 is for Alice and Bob to sign and broadcast tx0/tx0', tx1 and tx2, sequentially. However, there are several issues. After Bob gets Alice’s partially signed tx1, he can
- redirect the fund to another contract
- or sign and broadcast tx1, but refuses to sign later. Alice’s fund gets stuck.
To overcome these issues, we setup the contract in 2 steps as inspired by Satoshi Nakamoto, which we call the Nakamoto Signing Protocol.
- Alice and Bob exchange the txid of tx0 and tx0', which suffices to create and sign tx1 and tx2. But they do not share raw transaction tx0 and tx0' with each other yet and keep them off-chain.
- Alice checks tx1 and tx2 are both signed and their output contains the expected joint address and contract. If yes, she broadcasts tx0. If not, she aborts. Bob does the same thing.
The contract only proceeds when neither party aborts, since tx1 needs both tx0 and tx0' to be valid.
Compared to Cooperative Contracts
Opportunistic contract is similar to cooperative contract we have introduced, where a shortcut is taken when all parties reach an agreement on the final output. It is more private and efficient than the latter:
- In the latter, the whole smart contract is always exposed on chain, while it is not exposed in the former if all parties cooperate.
- In the latter, when all parties cooperate and sign, all signatures are needed in the unlocking transaction, while only one signature is needed in the former.
 Both the deposit and split amount can be zero, meaning only one party deposits and redeems.
 Contrary to what many people think, Schnorr signature is not needed to aggregate multiple signatures into one.