Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: Mike Hearn on May 18, 2011, 07:29:16 PM



Title: Designing distributed contracts
Post by: Mike Hearn on May 18, 2011, 07:29:16 PM
(edit) The article this thread discusses can now be found here:

   https://en.bitcoin.it/wiki/Contracts



Title: Re: Designing distributed contracts
Post by: unk on May 18, 2011, 09:02:08 PM
thanks for writing this up. i'm going to think about this more, but in the meantime i wanted to give you some initial feedback.

i think it works, technically, though i'm going only on your description and a very cursory review of the code. when multiple non-atomic transactions are necessary, there's always a concern about at least mischief that could be caused if one of them is delayed or obstructed, but the motivation for such attacks is unclear out of the context of particular forms of transactions, and nothing particularly dangerous jumps out to me in general.

i suspect, practically, that there may be a dearth of enthusiasm for scripting, at least initially. i'm inclined to think it's one of the more powerful and interesting features of bitcoin, but in many cases the extra distribution of trust that you get from the system is, i hate to admit, quite small practically compared to out-of-band protocols. for example, does the 'escrow' example achieve much more than sending the funds initially to the escrow agent?

still, simply committing to tie up funds without a trusted third party has compelling potential uses, as does CHECKMULTISIGVERIFY, which enables many kinds of 'contracts' on its own (though i would prefer the term 'commitments' or 'conditional payments', myself).


Title: Re: Designing distributed contracts
Post by: Mike Hearn on May 19, 2011, 07:06:47 AM
I call them contracts because that's what Satoshi called them. I guess it's a reasonable analogy though conditional payments might be more precise.

I haven't made up my mind about their value yet. Introducing new contract types means writing a patch for the Bitcoin software then waiting for miners to upgrade. It's probably not a big deal, but it's not free.

Still the minimization of trust strikes me as good practice. Bitcoin doesn't have chargebacks nor does it have any big, trusted names taking part so escrow is pretty essential. A trusted escrow service like ClearCoin might easily end up with really huge amounts of of money sitting in it, waiting for mediation. Whilst Gavin is a highly trustworthy fellow, what if the site gets hacked? There's tremendous incentive to break into servers which are acting as escrow agents.

If I send money to the merchant using a multi-pay contract, it's easier for us to do business. If the mediator, on receiving the funds, immediately ties them up in yet another multi-pay contract that sends the coins either to me or the merchant then I know even if the mediator/escrow service gets hacked my coins cannot be stolen. At worst the hacker might destroy the keys and get nothing. This chaining of multi-pay contracts can be done with a slightly different protocol/set of SIGHASH flags so at no point is the money ever "in the open".

Building up trust is difficult, slow and the fact that the Bitcoin economy is being bootstrapped from zero means that lack of trust is a drag on commerce. If contracts can help grease the wheels they seem like a useful feature to me.


Title: Re: Designing distributed contracts
Post by: kjj on May 19, 2011, 07:18:01 AM
Still the minimization of trust strikes me as good practice

Mental note to read the first post again when I'm not so tired.  My initial impression was that trust was being pushed around to (allegedly) trusted third parties, like bubbles under wallpaper, not being minimized.

By the way, I highly advise anyone interested in third party services to read about the history of ISK banking (AKA scams) in EVE Online.  The odds that a third party will remain trustworthy once the incentive to cheat becomes high enough has been holding steady at zero percent there for like 8 years now.


Title: Re: Designing distributed contracts
Post by: Mike Hearn on May 19, 2011, 09:01:12 AM
Not really. It's about limiting peoples options at each stage to remove the chances of bad things happening, or set up incentives to ensure good things happen.

Without a third party dispute mediator, buyer or seller has an incentive to screw the other person, so it's hard to do trade.

With a third party, you no longer need as much trust in the counterparty, but now you need to trust the third party instead. They also have an incentive to screw with you, although presumably there are far fewer escrow services than traders, and the escrow people have more to lose. The bigger risks are that the escrow service gets hacked and all the coins currently waiting for transactions to complete are stolen, or that trust becomes so centralized that escrow becomes very expensive.

With multi-pay contracts, we can minimize the chances of bad things happening:

  • If a trade goes well the third party is never involved at all. So there's no need for us to pay any fees.
  • If a trade goes south, as a buyer my only option is to get a pre-agreed mediator involved. I can't screw the merchant by taking back the coins (not a chargeback).
  • If the mediator gets hacked, the hacker can't steal any of the clients coins. They could only steal the companies own profits derived from mediation fees. That means I don't have to trust the security of their setup nearly as much, which in turn means it's easier for new mediation services to get started, leading to a more competitive and healthier market.

The cryptography of contracts lets us entirely remove various ways of things going wrong. The only trust you need is in the quality of the dispute resolution process. Other problems disappear entirely.


Title: Re: Designing distributed contracts
Post by: dacoinminster on May 19, 2011, 05:04:32 PM
This contract stuff could be incredibly important. What I don't see here is how to enforce the single most important kind of transaction bitcoin will be useful for: the bet.

Example: Person A wishes to bet Person B whether the price of bitcoins will rise or fall over the next 30 days.

Desired features:
 - If person A and person B agree on who won the bet, no third parties are needed
 - If they don't agree, a third party mediator settles the dispute and decides who gets the money
 - Both persons commit their bitcoins, and they are locked (can't be spent) until the bet is over
 - The terms of the bet (i.e. how to decide who won) are encoded in the contract and permanently embedded in the block-chain. The terms can be viewed by either party, and can be viewed by the mediator if they must be brought in to settle a dispute. In this case the terms might be: "If MtGox average of highest and lowest price on July 1st 2011 is lower than $10, person A gets all bitcoins, otherwise person B gets them. Disputes will be settled by person C." (bitcoin addresses and email addresses would be included for all parties)
 - The mediator should be able to take a fee if their services are needed

If someone is able to describe how the above contract system could be used for a bet like this one, I would be VERY interested. Extra points if the bet can pay out partially to both parties, i.e. "Person A pays 5 BTC now to get $50 USD worth of bitcoins from person B on July 1st 2011"


Title: Re: Designing distributed contracts
Post by: arturh on May 19, 2011, 09:09:43 PM
What you are describing is a multipay as above. Just with a string embedded in it.


Title: Re: Designing distributed contracts
Post by: Stefan Thomas on May 19, 2011, 11:05:22 PM
Awesome, I can't wait to have "native" escrow support without a third party.

One question regarding the trust example:

Imagine you open an account on a website (eg, a forum or wiki) and wish to establish your trustworthyness with the operators, but you don't have any pre-existing reputation to leverage. One solution is to buy trust by paying the website some money. But if at some point you close your account you'd probably like that money back.

Hmm, but you would get your money back no matter what, so if you wanted you could thoroughly ruin an identity and just start over with a new one once your deposit expires and is returned, correct?

It's true that it would incur capital costs for scammers as their money is tied up in this kind of escrow, but the costs for a scammer would be the same as for a legitimate user, no?

How does this compare to the following system:

- Global trust rating based on total fees paid from an address, perhaps weighted by age as well.
- Trust rating can be raised by sending a high-fee zero output transaction - think of it as buying trust from miners.
- There would have to be some place to lodge complaints against an address. Could be a website or a custom blockchain (that shares work (https://en.bitcoin.it/wiki/Alternative_Chains) with Bitcoin of course).

The result should be that a legitimate user can spend say 10 BTC on his trust rating once and use it for decades (assuming he doesn't get negative reviews). Whereas a scammer can do the same, but negative reviews and complaints lodged against the address will quickly make his 10 BTC investment void, requiring him to get another identity and spend another 10 BTC.

(Sorry if this is off-topic, it's not an example for a Bitcoin contract strictly speaking.)


Title: Re: Designing distributed contracts
Post by: marcus_of_augustus on May 20, 2011, 04:28:28 AM
just listening.


Title: Re: Designing distributed contracts
Post by: Mike Hearn on May 20, 2011, 07:51:18 AM
Hmm, but you would get your money back no matter what, so if you wanted you could thoroughly ruin an identity and just start over with a new one once your deposit expires and is returned, correct?

Yes. The use case I was thinking of is places where CAPTCHAs are used today and are ineffective (ie, the use cases that keep me employed ;).

I missed out something that would have made this clearer - if your account is terminated for violating the ToS, you still have to wait the 6 months to get your money back. Assuming that accounts "go bad" and are terminated faster than that, the abusers lose. This is already the case with paying people to solve CAPTCHAs, the problem is that CAPTCHA solutions cost ~$1 per thousand, so it's cheap enough for spammers to just swallow as the cost of business.

Quote from: Stefan Thomas
The result should be that a legitimate user can spend say 10 BTC on his trust rating once and use it for decades (assuming he doesn't get negative reviews). Whereas a scammer can do the same, but negative reviews and complaints lodged against the address will quickly make his 10 BTC investment void, requiring him to get another identity and spend another 10 BTC.

(Sorry if this is off-topic, it's not an example for a Bitcoin contract strictly speaking.)

Yes, it could be done that way. The problem is authenticating the reviews and ensuring they're globally distributed/respected.

There's already something like this today, see StopForumSpam (http://www.stopforumspam.com/), but it doesn't have many reviews and many forums don't use it. If it did then we'd run into a different problem of the registry of bad people being abused itself.

Another example: big webmail providers rely on user feedbacks to train the spam filter and shut down abusive accounts. But I can tell you now that people press the "Report Spam" button on mail from their friends and relatives all the time, so it takes a lot of work to scrub the abuse report feeds and turn them into something useful.

The nice thing about putting up a deposit at each site you want to use is that the site can individually raise or lower the threshold as they see fit. A forum for discussing mega-yaughts might prefer to not have any moderators and just charge a hefty deposit, whereas a forum like this one may prefer to have more active moderators and manual spam fighting with a lower deposit.


Title: Re: Designing distributed contracts
Post by: Latregetic on May 20, 2011, 11:51:29 AM
This will be crucial to the future of the currency.  The current biggest downside to the currency is the fact that there is no possible remediation if you get scammed in a trade or purchase.  Every address can be a unique string, and there is no possible way to trace who owned that address.  Without some way to create a contract, there is no way to avoid this issue.

By being able to create a contract that is enforced by the network itself, allows for very complicated forms of behavior with a very minimal chance of being cheated.  Unless the buyer or seller are actively colluding with the mediator, there is no way to actively scam.  However, without some kind of mechanism to insure the mediators stay honest, there is no way to stop that from happening.  Unless the cost to become a mediator is greater than the profits derived from scamming, scammers will simply become a mediator on an alternate ID, and steal every transaction they take part in.

If both buyer and seller have to agree on the escrow agent, then there are less chances of either side being screwed in the event of shenanigans, but having to individually negotiate that for every purchase takes a lot of time and limits the ability of the seller to make automatic sales.  If the seller has a list of preferred mediators, then the onus for mediator selection is on the buyer, and that lessens the cost of the seller's side, but the buyer might end up running into an elaborate scam.  Many mediation firms have a very strong incentive to side with the company that paid/referred to them, in the interests of repeat business.

In order to assure fairness, or at least limit fly-by-night mediation sites with fancy web pages and no real there needs to be a mediator escrow fee, such that the total value of the outstanding contracts they are acting as a mediating agent on is less than some value they have in escrow in the network.  It could be a proportional model, like fractional banking, but there needs to be some strong financial incentive to not be a jerk.



Potential Attack Vectors (that I can think of now):
Respected Mediator is corrupt, buys tons of stuff from online guys using a 30 day contract with himself as the mediator.  Voids all the contracts after the goods arrive.  Seller is screwed.
Mediation site is hacked, and the private keys it used for mediation are stolen.  Now the hackers are able to buy tons of online merchandise from people that use that service, and void the contracts once the merchandise is delivered.
Seller only allows one mediation service, which will collude with them on some contracts.  Seller takes money, never sends package, and the mediator validates the contract without any input from the buyer.

You might want to include a mechanism for voiding a set of keys used in a transaction.  If the mediator notices the intrusion, there needs to be a way to tell the network 'These keys are invalid, never ever use them, ever.'  There should also be a way to freeze contracts that used those keys in such a way that is fair to both the buyer and seller.  I'm not sure how you'd do that with a compromised mediation agent, but it is possible to use any odd number of mediators such that the buyer or seller, plus the majority of the mediation agents concur in order to void or enforce the contract.

Now that I think about it, having multiple mediators, as long as the keys all don't end up in the hands of one of the two parties, would eliminate most of the mediator related attacks.


Title: Re: Designing distributed contracts
Post by: Mike Hearn on May 21, 2011, 01:51:52 PM
I think it's worth remembering that anonymity in Bitcoin is optional, not mandatory. Nothing stops a dispute mediator incorporating and being a real legal entity. Indeed, I wouldn't want to use one that wasn't!

The goal of the escrow transactions is really to grease the wheels by making it easier to become a mediator. You don't have to trust the mediator with your money, you just have to trust that they'll do a professional job of resolving the dispute. There will still be eBay style moderated markets in the Bitcoin world.

A possible other advantage is lower fees. If the trade executes successfully you don't need to get the mediator involved. Having thought about it more though, it seems that they could still charge fees even on successful transactions because otherwise they might refuse to mediate the dispute at all unless agreed up front. I guess it'd depend on what the most sensible business model is.

Yes, the protocol for setting up such trades would probably involve the merchant giving you a list of acceptable mediators and then you picking one. Alternatively a meet-in-the-middle protocol could work better where both merchants and buyers swap sorted lists of acceptable mediators and then the first item in the intersected list is used. It has the advantage that merchants can easily see if there is demand to use a new mediator they don't currently support. As long as the protocols are reasonably standardized adding support would be easy and low cost.

Implementing this system would require, as a first step, a decently written design doc. After that's done and agreed on somebody (maybe somebody different) could implement the design in the official software. There isn't much point in doing this until some dependencies are finished though. Like, the ability to invoke a bitcoin: URL from the browser.

The bets idea is an interesting one. I think it might be possible to encode the bet itself into the chain so you don't need a mediator, just an oracle.


Title: Re: Designing distributed contracts
Post by: Latregetic on May 21, 2011, 03:11:08 PM
Yeah, the anonymity of the mediator would run counter to the mediator's ability to prove he's trustworthy to the community.

I see the escrow transactions as a way to make transactions that are not self-reinforcing, basically any transaction that requires any kind of trust between the parties, work out for the parties involved.  When there is no way for any reasonable person to trust the other part, there needs to be a mechanism to stop cheating on both sides of the deal.

There will always be exchanges and markets that have their own internal methods of dealing with fraud and arbitrating disputes, but having a mechanism built into the block chain that allows a transaction to take place that does not involve only BTC transfers is a very powerful tool.

The meet in the middle protocol would work best, but some method of fairly assigning a mediator would be necessary.  If it just picks the first one on the list, then there is an incentive for mediators to spend huge quantities of time generating addresses with a very high number of leading zeros, such that they are always first in line to collect that 0.002 BTC fee. 

Is it possible to have multiple mediating parties involved in the transaction, such that a majority of the parties have to agree with one course of action in order for that action to be seen as valid by the network?  If you could choose 3 mediation agents from a list of agents with a positive reputation, practically any attack requires compromising too many agents for it to be viable.

How would you be able to invoke a fair oracle without the ability for one party or the other to influence or abuse the thing?  I guess there are a lot of services you could poll gribble style to see what MtGox closed at last night to officiate the bet.  Hell, having some kind of limited oracle support would be a very handy thing to allow for automatic and automated short sells of BTC on the market.

How hard would it be to develop a working design document that could be presented to one of the developers? 


Title: Re: Designing distributed contracts
Post by: Mike Hearn on May 21, 2011, 04:58:08 PM
Quote
Yeah, the anonymity of the mediator would run counter to the mediator's ability to prove he's trustworthy to the community.

Well, anonymity is a complex topic. Everyone has at least one identity they are given at birth which stays with them for their whole life. The internet and cryptography now allows people to create alternative identities and build their reputations independently, but it was of limited use because the only things you could do on the internet are speech and creative works, pretty much.

Bitcoin now allows you to trade under these pseudonyms too, but it's still tough to build up trust in an alternative identity because they are free to discard. As a result people tend to drop them whenever convenient. Real, legal identities can't be so easily discarded and there's serious accountability: you can be sued or sent to jail, so it's still much easier to Get Things Done and build trust under that ID.

The next stage of evolution in crypto-anarchism would be pseudonymous companies. The trust an individual can build is always limited just because there's a limited amount an individual can achieve. Big companies have much more to lose and have much bigger impact.

Lots of tricky problems to solve there and, frankly, not that many people interested in doing it. So I think dispute mediators along with most other Bitcoin-related service companies will be strongly identified for the foreseeable future.

Quote
The meet in the middle protocol would work best, but some method of fairly assigning a mediator would be necessary.

I think I didn't clearly explain the protocol. Both buyer and seller compile an ordered list of strongly identified mediators, eg, the list might be a list of domain names that have EV SSL certs. The list is intersected and the one that is highest on both lists is selected. Thus, both parties automatically find agreement on which mediator to use, but if buyers keep ranking some new guy higher than the merchants preferred mediator that can be noticed by the software and the merchant informed. It's an easy way to improve his business.

Quote
Is it possible to have multiple mediating parties involved in the transaction.

Yes, I think so. It involves an addition to the multi-pay protocol, which is already quite complex. I doubt it would be a very popular feature. This type of escrow is useful for the little guys who just want to buy some alpaca socks. Cases where the risk of corruption is so high you need 3 mediators are almost certainly high-value transactions between legally accountable organizations, so if it goes wrong you can just go to court.

Quote
How would you be able to invoke a fair oracle without the ability for one party or the other to influence or abuse the thing?

The oracle can be checked at any point to ensure its answers are correct. As long as there's some reasonable flow of transactions that rely on it, that should make cheating difficult or un-interesting.

I don't know all the details. I'm still pondering how to do it. I think the oracle would have to vend partially signed transactions on demand that match an output script checking the answer. It might be possible to settle bets that can be represented numerically this way.


Title: Re: Designing distributed contracts
Post by: Latregetic on May 21, 2011, 05:56:28 PM
Lots of tricky problems to solve there and, frankly, not that many people interested in doing it. So I think dispute mediators along with most other Bitcoin-related service companies will be strongly identified for the foreseeable future.
That's my guess as well.  An address associated with the company, and publicly shown on the website is all a mediation agency would really need to do.  Still technically anonymous from the perspective of someone trying to find a name and address, but to the community, they can build substantial reputation, so long as they use that address.

Quote
Is it possible to have multiple mediating parties involved in the transaction.

Yes, I think so. It involves an addition to the multi-pay protocol, which is already quite complex. I doubt it would be a very popular feature. This type of escrow is useful for the little guys who just want to buy some alpaca socks. Cases where the risk of corruption is so high you need 3 mediators are almost certainly high-value transactions between legally accountable organizations, so if it goes wrong you can just go to court.
My major concern is high value arbitrage and hedging between major parties.  Both parties would need to be legal entities in a position to sue each other with a reasonable chance of recovering losses.  A hedge fund in the cayman islands isn't going to give two shits about a suit someone sends them from China.  And many hedge and arbitrage transactions could be in the tens of thousands of dollars.  Being able to compromise the mediator for even one of these transactions could be worth the effort of breaking into his or her systems.  If the client is able to offer a high security 3 mediator transaction for these people, you'll probably see a lot more capital influx, because most of the attack vectors associated with a single mediator would fail misserably with 3.

Quote
How would you be able to invoke a fair oracle without the ability for one party or the other to influence or abuse the thing?

The oracle can be checked at any point to ensure its answers are correct. As long as there's some reasonable flow of transactions that rely on it, that should make cheating difficult or un-interesting.

I don't know all the details. I'm still pondering how to do it. I think the oracle would have to vend partially signed transactions on demand that match an output script checking the answer. It might be possible to settle bets that can be represented numerically this way.
Yeah, I could see a gribble style oracle script that would give you MtGox price quotes if you feed it the right bit of script.  As long as there is some 3rd party tool that allows for the bet/script to be made into plain English for the purposes of the bet, that kind of oracle could act as an impartial arbitrator of short sells. 


Title: Re: Designing distributed contracts
Post by: Mike Hearn on May 21, 2011, 08:09:13 PM
I was thinking actually that the bets would be programmatically enforced.

I just remembered that online betting is illegal in the USA. It's probably best to not have direct technical support for it in the block chain unless that situation changes. It wouldn't add very much beyond what can already be done with multi-pay transactions, anyway.


Title: Re: Designing distributed contracts
Post by: Latregetic on May 21, 2011, 10:10:56 PM
I was thinking actually that the bets would be programmatically enforced.

I just remembered that online betting is illegal in the USA. It's probably best to not have direct technical support for it in the block chain unless that situation changes. It wouldn't add very much beyond what can already be done with multi-pay transactions, anyway.

It's not just the bets, anything that you could use an impartial oracle to arbitrate are potentially up for contract.  Mostly short sells and price hedges.  These are technically gambling, but since it's a futures market, it's such a grey area that I don't think anyone would give a shit.  

Also, if the US government actually notices Bitcoin, we're probably going to get hit with a lot of laundering charges, not online gambling charges.


Also, I see this as the ability for the network to have an internal method of creating enforceable transactions for potentially large sums of money.  When the only thing you have is a Bitcoin address and possibly an IP, even with a 3rd party community they have a reputation with, there is an incentive to cheat.  Having a neutral 3rd party able to reverse the transaction after arbitration removes that ability to cheat, or at least makes it much harder to do.


Title: Re: Designing distributed contracts
Post by: mcqueenorama on June 14, 2011, 04:03:25 AM
Is anybody actually working on this?  Let's talk.  I want to get in on this too.


Title: In Reply To: Mike Hearn, Development & Technical:Designing distributed contracts
Post by: bji on June 17, 2011, 07:19:48 AM
Sorry, I would have posted this in the forum discussion directly, but as a newbie I am not allowed.

I think the Contracts section of the bitcoin wiki site is just awesome.  It kind of warps my brain to try to think about the fantastical ways that contracts can be drawn up using bitcoin scripts.

Anyway, I had one question about the 'Escrow and dispute mediation' section:

Wouldn't it make more sense in the last paragraph to define the transaction as spending the output to the mediator with an nLockTime of a month from now, instead of the same but spending the output to the merchant?  It seems to me that one would rather that, in the case of inactivity on the part of the spender, have the money go to the mediator than directly to the merchant.  This would protect the spender in case they were, e.g. incapacitated or something and could not for some reason verify that the goods were received, but the mediator might be able to investigate and hold the funds until the spender is dis-incapacitated and able to verify or challenge the transaction.

It would also deter the merchant from being the one to incapacitate the sender and wait for the transaction to default out to sending the coin to the merchant (assuming that the merchant knows who the sender is).

It's a minor correction but if it is agreed to then it verifies that my understanding of bitcoin contracts is valid, and if the wiki is then updated it may help someone who in future wants to create such a contract.


Title: Re: In Reply To: Mike Hearn, Development & Technical:Designing distributed contracts
Post by: Nefario on June 17, 2011, 07:51:10 AM
Where is the original thread you are refering to?


Title: Re: In Reply To: Mike Hearn, Development & Technical:Designing distributed contracts
Post by: bji on June 17, 2011, 08:38:34 AM
Where is the original thread you are refering to?

Sorry to have omitted the link, here it is:

http://forum.bitcoin.org/index.php?topic=8821.0 (http://forum.bitcoin.org/index.php?topic=8821.0)

The discussion in the forum is relevant, but more relevant is the contents of the bitcoin wiki under the Contracts section:

https://en.bitcoin.it/wiki/Contracts (https://en.bitcoin.it/wiki/Contracts)

which looked to be the results of that discussion and is what I would like to see changed if my comments make sense.


Title: Re: Designing distributed contracts
Post by: ByteCoin on June 21, 2011, 05:23:49 PM
Mike, thanks for the explanation. I appreciate the effort you spent to write it up. Could you please add a section to the Wiki explaining "lock time", "sequence number" and "transaction replacement" since these seem to be prerequisites for understanding the Contracts (https://en.bitcoin.it/wiki/Contracts) article you wrote.

In particular, could you clarify exactly what is compared with the LockTime value to prevent it being replaced and a little word on how LockTime interacts with block chain reorgs in a way that makes it superior to OP_BLOCKNUMBER (http://forum.bitcoin.org/index.php?topic=1786.0).

You imply in your post that it could either be a time or a blocknumber. How is this distinction managed?

What is the significance of the sequence number applying to each input instead of the transaction as a whole?

"HashType" such as SIGHASH_NONE, SIGHASH_SINGLE and SIGHASH_ALL could do with being explained.

How does CODESEPARATOR work?


Example 1: Providing a deposit
We can solve this problem with a contract:
  • The user and website send each other a newly generated public key.
  • The user creates transaction Tx1 (the payment) putting 10 BTC into an output which requires both user and website to sign, but does not broadcast it. They use the key from the previous step for the site.
  • User sends the hash of Tx1 to the website.

Doesn't the user also have to send the index of the relevant TxOut if Tx1 produced change?

  • The sequence numbers on the inputs are set to zero instead of the default which is UINT_MAX.
...
  • Because the sequence numbers are zero the contract can be amended in future if both parties agree.

"Inputs" and "sequence numbers". I thought there was only one input, Tx1.

ByteCoin


Title: Re: Designing distributed contracts
Post by: joan on June 21, 2011, 07:43:14 PM
You imply in your post that it could either be a time or a blocknumber. How is this distinction managed?
I might be wrong but this should be clear from the value. When read as a time, the current blocknumber get only as far as january 2nd 1970.
If we agree that every value before 1231006505 (genesis time) is a blocknumber, and considering blocks being added at 10 minutes interval, it would give us about 23404 years before the trouble starts  ;D


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 22, 2011, 11:50:13 AM
From the code:

Code:

    bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
    {
        // Time based nLockTime implemented in 0.1.6
        if (nLockTime == 0)
            return true;
        if (nBlockHeight == 0)
            nBlockHeight = nBestHeight;
        if (nBlockTime == 0)
            nBlockTime = GetAdjustedTime();
        if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime))
            return true;
        BOOST_FOREACH(const CTxIn& txin, vin)
            if (!txin.IsFinal())
                return false;
        return true;
    }


So the boundary value is 500,000,000 blocks. Not a problem.

Hash types are explained in the OP_CHECKSIG article. But I will try and add some of the explanations to the contracts article as well.

Somebody has implemented escrow transactions:

   https://github.com/bitcoin/bitcoin/pull/319

Sequence numbers apply to inputs rather than transactions to allow for multi-party signing by passing around partially signed transactions. Changing the sequence number on your input allows for a new version to appear without invalidating other parties signatures (see IsNewerThan and SignatureHash).

I would take things written in the Contracts article with a pinch of salt. This stuff is very complex and I haven't tried implementing it. It's based purely on my reading of the code, thinking about it and a few discussions with Satoshi. Some of the details are certainly wrong. For instance I got an email querying my usage of CODESEPARATOR. I think I agree the article is wrong on this point and I'll try to fix it.


Title: Re: Designing distributed contracts
Post by: killerstorm on June 23, 2011, 04:18:26 PM
I have an alternative idea for escrows which has some overlap with this.

Basic idea is to have time-sensitive transaction scripts.

A very small protocol extension is needed -- new script opcode, say, OP_CUR_BLOCK_NUMBER which pushes current block's serial number (height, or however you call it) on stack. (By current block I mean one which tries to spend an output, of course.)
Or OP_CUR_TIME which pushes current time.

This can be used in a number of situations:

1. Just as in "Providing a deposit", a web site wants you to put some coins aside for a few month. You can broadcast txn with script like this:

Code:
if (cur_block_number > 123456) {
   checksig(your_key);
} else fail;

This way you will be able to get your money back, but only after some time passes.

To prove it is really your txn you can either use unique amount provided by site (e.g. 1.013890123) OR embed a proving number into a txn in some other way.

2. Use 3rd party for escrow and mediation:

Code:
if (cur_block_number < 123000) {
   checkmultisig(counterparty's pubkey, escrow service's pubkey);
} else if (cur_block_number > 123100) {
   checsig(your pubkey);
} else fail;

What this means:

Your counter-party needs both his signature and mediator signature to unlock funds.
Thus if mediator service finds that contract requirements are met he will either provide his signature or his private key.

But if mediator service dies, or counter-party dies and they are unable to spend locked money then you will be able to get it back.

This way if something goes awry money doesn't hang there indefinitely.

3. Particularly, case number 2 might be useful for betting service. For example, A and B decide to make a bet: if event E happens some time in future A pays B 10 BTC, otherwise B pays A 10 BTC. They use a betting service S to ensure that this agreement is fulfilled.

So A sends B 10 BTC with script as above and B sends A 10 BTC.

Then, in the future, if event E happens S provides his signature to B and B is able to unlock his prize. But it does not provide signature to A, so B's money eventually return to B.

Again, if betting service dies money returns to users. And betting service cannot steal money (unless it conspires with one of users).


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 23, 2011, 05:49:35 PM
What you suggest is what nLockTime does. OP_BLOCKNUMBER has been discussed before, but it can't be implemented because if it's evaluated "in context" it can be used to make a transaction valid for some time, then invalid (causing attacker controlled chain splits). If it's converted into a constant before being placed in a block the signatures over the transactions can break.


Title: Re: Designing distributed contracts
Post by: ByteCoin on June 23, 2011, 06:14:42 PM
Mike's concern is valid. The solution suggested in the OP_BLOCKNUMBER threads is to reduce the risk to the same level as the invalidation of coinbase transactions. Coinbase transactions take a long time to mature because reorgs that invalidate transactions spending coinbases must be thrown away after the reorg. OP_BLOCKNUMBER transactions could take a very long time to mature, proportional to their value.

nLockTime, sequence numbers and scripting are powerful. There seems to be no way however using scripting, nLockTime etc to send bitcoins to an address and to have them revert back to you if they are unspent for a very long time which seems to be a keenly desirable feature. I will take this back and discard OP_BLOCKNUMBER if someone demonstrates that equivalent functionality can be gained without it.

If there were an OP_DIFFICULTY as well then the futures and bonds suggested by cunicula (http://forum.bitcoin.org/index.php?topic=19130.0) might be possible.

ByteCoin


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 23, 2011, 06:22:25 PM
You can already do that (well, if the features were re-enabled).

Send coins to a recipient as usual. The recipient creates a tx with a nLockTime in the future that sends them back to you, but doesn't broadcast it, instead they just give it to you out of band (eg via email).

Now wait. If after the time period is nearly up the coins weren't spent, broadcast your reclamation tx. Once nLockTime passes the coins are yours once again.

Broadcasting the reclamation tx prevents the owner spending the coins (it'd be a double spend so will be rejected). But the reclamation was created by the owner of the coins, not you. If you broadcast it before the time is up, the real owner can create a new version of the tx with a higher sequence number and broadcast it to claim the coins for good, overriding your reclamation tx.

In this way there's no point trying to reclaim the coins unless the recipient has really gone away for good and won't block your reclaim attempt.


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 23, 2011, 08:20:55 PM
ByteCoin and a few others asked for more detail on the SIGHASH flags.

I added a brief description of what they are for to the top. Also, because it's quite hard to understand all the parts without illustration, I added a third example that describes how to implement assurance contracts via script.

Note that beyond lacking a GUI and RPCs for the general protocol, the lock time feature is disabled today and there's no way to mark coins as temporarily unspendable. Without the latter feature it'd be possible to accidentally spend pledged coins without meaning to, invalidating your pledge.


Title: Re: Designing distributed contracts
Post by: killerstorm on June 23, 2011, 08:37:50 PM
Hmm, latest message I can find on OP_BLOCKNUMBER is of May 03 http://forum.bitcoin.org/index.php?topic=6900.20
and Mike says "I don't know.". Is there a new information, like, a concrete attack scenario?

If all nodes are required to validate scripts then yes, it is problematic because blocknumber might be different.

But if only miners check these complex scripts at time they are included into a block then I see no problem -- OP_BLOCKNUMBER is fixed in context of block being made. The only problem is reorg, but this can fixed too through maturation time, as ByteCoin says.

Solutions which use OP_BLOCKNUMBER seem to be orders of magnitude simpler than ones which use nLockTime, so why dismiss it just because there _might_ be problems, i.e. in absence of concrete attack scenarios? I would guess that if nLockTime looks more complex then it can have well-hidden security problems.

Quote
If there were an OP_DIFFICULTY as well then the futures and bonds suggested by cunicula might be possible.

Yep, and with OP_BLOCKTIMESTAMP you can also check for hashrate growth before difficulty updates. (I.e. if hashrate went up blocks will be generated faster and so timestamp will be lower than you would expect otherwise.)


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 23, 2011, 08:49:52 PM
I thought about it more since I wrote that post.

Something like OP_BLOCKNUMBER is probably 'possible', but would require serious surgery on the codebase. Having explored the system in more depth, I understand why Satoshi chose to implement this as a property of the transaction rather than in script.

Currently, script evaluation is independent of context. If OP_BLOCKNUMBER is defined to be the block the transaction appears in, it has no meaning outside the block chain (eg in the memory pool), so is a script containing it valid or invalid? If it's defined to be the current best height, it's possible to fork the chain when it's included (so this isn't an acceptable definition).

It's important to note that nLockTime is a property of the whole transaction, not an input. You could potentially write a transaction in which different inputs used the current block number in different ways, resulting in a lot of weird edge cases and bugs.

The design of Bitcoin is quite subtle and changing it in big ways isn't to be taken lightly. So far nLockTime seems to offer enough power to achieve many different things, most proposed uses for OP_BLOCKNUMBER can be rephrased to use the existing facilities.


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 23, 2011, 10:25:11 PM
OK, I'm going to be busy for a few days so I added a final fourth example of how to lock coins to arbitrary external state using an oracle. Minor adaptations should make things like network-enforced futures contracts possible, for those who are interested in that.



Title: Re: Designing distributed contracts
Post by: kjj on June 23, 2011, 10:33:53 PM
You can already do that (well, if the features were re-enabled).

Send coins to a recipient as usual. The recipient creates a tx with a nLockTime in the future that sends them back to you, but doesn't broadcast it, instead they just give it to you out of band (eg via email).

Now wait. If after the time period is nearly up the coins weren't spent, broadcast your reclamation tx. Once nLockTime passes the coins are yours once again.

Broadcasting the reclamation tx prevents the owner spending the coins (it'd be a double spend so will be rejected). But the reclamation was created by the owner of the coins, not you. If you broadcast it before the time is up, the real owner can create a new version of the tx with a higher sequence number and broadcast it to claim the coins for good, overriding your reclamation tx.

In this way there's no point trying to reclaim the coins unless the recipient has really gone away for good and won't block your reclaim attempt.

The transaction of your coins for their promise to return your coins is not atomic.

And thank you for the other part.  I had been wondering about nLockTime and sequences for a while now, but hadn't dug into them.  But now I know.  Another nifty gem hidden in the bitcoin design.


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 23, 2011, 10:46:28 PM
If you want the operation to be atomic you can create the initial send, hash it, send the hash to the recipient and then wait for them to reply with the reclamation tx. Once you have the reclamation tx, broadcast the send.


Title: Re: Designing distributed contracts
Post by: kjj on June 23, 2011, 10:57:32 PM
If you want the operation to be atomic you can create the initial send, hash it, send the hash to the recipient and then wait for them to reply with the reclamation tx. Once you have the reclamation tx, broadcast the send.

I think I'm missing an implied step in there.  How is the hash useful as security to them?  Couldn't you just fail to broadcast the send after you get the reclaim?

But we could just skip that step entirely and end up in the same place.  They give you the reclamation transaction first, and then invalidate it (as described earlier) if you fail to send.


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 24, 2011, 07:02:19 AM
You can't construct the reclamation tx without the hash of the transaction it's reclaiming.


Title: Re: Designing distributed contracts
Post by: killerstorm on June 24, 2011, 11:33:46 AM
Currently, script evaluation is independent of context. If OP_BLOCKNUMBER is defined to be the block the transaction appears in, it has no meaning outside the block chain (eg in the memory pool), so is a script containing it valid or invalid? If it's defined to be the current best height, it's possible to fork the chain when it's included (so this isn't an acceptable definition).

Here is how I would define OP_BLOCKNUMBER:

1. If transaction input is verified in context of AcceptToMemoryPool it is defined as current best height + 1. (I.e. next block's index.)
2. If transaction input is verified in context of ConnectBlock it is defined as this block's index, i.e. height of block chain at time block was created + 1.
3. If transaction input is verified in context of CreateNewBlock it is defined as current best height + 1 (i.e. index of block which is in process of being mined).

These contexts already do exist as different flags to ConnectInputs(), but they are not passed to VerifySignature() and VerifyScript(). But it is trivial either to pass an additional parameter or record this info in state of transaction. I don't think this qualifies as a serious surgery, if you're concerned about code complexity I can try to make a patch which implements it and we'll see...

Now if it is defined this way I don't see how bad things you talk about can happen.

Once txn is in block its input is well-defined and so all nodes will agree on its validity. So this cannot be used to cause block chain splits. If blocks are reorganized then new transaction might have problems getting into next block, but it is also the case with double-spend scenarios, so it's nothing new. Impact can be minimized by requiring transactions with inputs which use OP_BLOCKNUMBER to mature for some time.

For transactions which are in pool validity might change over time, so different nodes with different chain heights might disagree, but this is not a problem because transactions are re-checked once they appear in blocks. It will only have effect on transaction relaying, and if transaction is not relayed then it hurts only one who made it.


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 24, 2011, 12:06:42 PM
But what's the justification for such a complicated opcode and set of changes? And yes, an opcode whose result changes depending on the context in which it's verified counts as 'complex' to me, relative to most of the other opcodes.

I haven't seen any use case for such a thing yet, given that it'd require a forced global upgrade.


Title: Re: Designing distributed contracts
Post by: garyrowe on June 24, 2011, 12:36:55 PM
I'm very interested in the bitcoin contract creation.
Is it possible for the standard client to do this, or is it only available through an API?
Are there any code examples of it in use?


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 24, 2011, 01:38:15 PM
Contracts are only of interest to people willing to modify the core Bitcoin code, currently (or significantly extend another implementation like BitCoinJ). There's no API for generic crafting of contracts and it doesn't make much sense to create one, imo.


Title: Re: Designing distributed contracts
Post by: garyrowe on June 24, 2011, 01:42:56 PM
Thanks, Mike. Looks like I'll be wading into BitcoinJ if you're happy to see it extended in this manner.


Title: Re: Designing distributed contracts
Post by: killerstorm on June 26, 2011, 12:58:35 PM
I don't quite get how "oracle" example is secure. This part:

Quote
The signature uses the SIGHASH_NONE flag, thus the recipient can be anyone (the oracle does not care). If the man dies, the son can claim the funds by taking this transaction, adding an output to one of his own addresses, and then broadcasting it.

What prevents malicious party from crafting similar transaction with his output?

E.g. it monitors broadcast transactions and when he sees son's transaction involving oracle sig it will copy it and replace output with his own and broadcast it too. Then it is a race condition. As you said, SIGHASH_NONE means that output is not signed so this copycat transaction is possible, right?

Or oracle itself can construct this transaction itself and just wait for son's input to be broadcast.

BTW I have an idea of how to implement escrow/oracle with somewhat different properties: to make a contract transaction you need to obtain a token (hash) from escrow/oracle service, but service does not need to work with each individual transaction. It is based on hashes, security is derived from complexity of first preimage attack.

Idea is simple: oracle generate an unique random number R associated with event E and announces its hash: hash256(R). Interested parties incorporate hash256(R) in scripts of their transaction. Then if event E happens oracle announces original random number R and it will unlock spending scripts.

In a simplest case:

Code:
scriptPubKey: HASH256 <hash256(R)> EQUALVERIFY DUP HASH160 <pubKeyHash> EQUALVERIFY CHECKSIG
scriptSig: <sig> <pubKey> <R>

Use case can be similar to a legacy case, but oracle is required to associate an unique number R with event of death of "John Smith" before transaction is made.

It can also be used for making bets on public events, trading binary options etc.

For example, person A agrees to pay 100 BTC to person B in case exchange rate on a certain exchange is higher than 17.5 on a certain date.

An exchange itself or a third-party service will create a an unique random number RL_x_y for each event EL_x_y which means that exchange rate will be lower than x on date y, and numbers RH_x_y for each event EH_x_y which means that exchange rate is higher than x on date y.

Now A should obtain hash256(RH_x_y) and hash256(RL_x_y) from service and create a transaction for 100 BTC with scriptPubKey like this:

Code:
IF HASH256 <hash256(RH_x_y)> EQUALVERIFY DUP HASH 160 <pubKeyBHash> EQUALVERIFY CHECKSIG
ELSE HASH256 <hash256(RL_x_y)> EQUALVERIFY DUP HASH 160 <pubKeyAHash> EQUALVERIFY CHECKSIG
ENDIF

Now if exchange rate is higher service will publish RH_x_y and then B will create txn with scriptSig:

Code:
<sig> <pubKeyB> <RH_x_y> 1

otherwise A will create similar txn which unlocks money to him.

An advantage comparing to signature-based escrows is that service only needs to publish a hash and a random number, but it does not need to process each transaction individually. Also, hash and number are rather small so it is easy to just copy them into GUI form field, so there is no need for software integration between contract-making GUI and service: this service can be a simple static web page.


Title: Re: Designing distributed contracts
Post by: Mike Hearn on June 26, 2011, 09:10:13 PM
The oracle transaction can be combined with another signature so only the grandson can spend the coins in combination with the oracle. But transactions propagate pretty fast. I don't think it's worth worrying about a race condition much.

For the random number idea, I think to be secure the random number would have to be very large (eg, the size of a hash). Otherwise you can calculate a rainbow table for a huge range of numbers. I thought about hashing the output of the oracle when writing the article, but doing it in a way that isn't susceptible to trivial brute forcing seemed hard.



Title: Re: Designing distributed contracts
Post by: cunicula on June 27, 2011, 05:13:22 AM
Can claims on distributed contracts be sold to third parties?

Suppose there is a ClearCoin-style Escrow contract. Seller sets an escrow expiration date (if he really doesn't trust the buyer, he sets a date very far off in the future). Buyer puts coins in escrowed account. Buyer has limited control over escrowed coins. He can a) release coins to the seller immediately, or b) order the coins returned to another account after the escrow expiration date expires.

If the buyer picks b), can he trade his escrowed coins to a third party? Ideally, could escrowed coins be traded more than once?

Trades would be helpful because:
a) they would make escrow transactions attractive to a wider variety of buyers (many people can risk a partial loss of coins, but can't risk having large sums tied up for a long time.)
b) if the escrow expiration dates were standardized (e.g. Jan 1st and June 1st), failed escrow transactions would create a useful commodity. Escrowed coins would sell at a discount over regular coins. Accordingly, anyone who has promised to pay someone bitcoins in the future would rather back their promises with escrowed coins than with regular bitcoins.

I would love it if escrowed coin balances could be integrated into special versions of the bitcoin client. Standardization of escrow termination dates would limit the new types of balances to a few additional kinds of coins (e.g. Jan 1st this year, June 1st this year, Jan 1st next year, Jun 1st next year). Contract standardization is pretty much essential for bitcoin contracts to be tradeable.


Title: Re: Designing distributed contracts
Post by: killerstorm on June 28, 2011, 10:28:07 AM
The oracle transaction can be combined with another signature so only the grandson can spend the coins in combination with the oracle.

Two CHECKSIGs and two sigs in scriptSig?

Quote
But transactions propagate pretty fast. I don't think it's worth worrying about a race condition much.

This sounds like security-through-obscurity approach. If we're talking about a serious sum (which quite fits in case with inheritance) it quite makes sense to find nodes close to what "grandson" uses and infiltrate the network to stop propagation of his txn and distribute your txn faster.

As I understand normally client connects to a limited number of random nodes. Attacker might instead choose to connect to nodes of prominent miners directly, so he will be able to deliver his txn to miners faster and have higher chances of his txn being included into a block.

It would also make sense to flood network with transactions to slow propagation.


Quote
For the random number idea, I think to be secure the random number would have to be very large (eg, the size of a hash).

Yes, that was the plan.


Quote
Otherwise you can calculate a rainbow table for a huge range of numbers. I thought about hashing the output of the oracle when writing the article, but doing it in a way that isn't susceptible to trivial brute forcing seemed hard.

ECDSA, as used by bitcoin protocol, also relies both on high-quality crypto RNGs and hashing, so it, in theory, suffers from same preimage and RNG-related attacks. So I don't see how hash-based approach is less secure. If anything, it is more secure because it does not rely on ECDSA's number-theoretic mumbo-jumbo.


Title: Re: Designing distributed contracts
Post by: Andrew Vorobyov on September 29, 2011, 10:59:07 PM
bzzz... any results??


Title: Re: Designing distributed contracts
Post by: Mike Hearn on September 30, 2011, 01:14:57 AM
AFAIK the only contract being implemented currently is multi-signing.


Title: Re: Designing distributed contracts
Post by: maaku on September 30, 2011, 05:55:55 AM
Multi-sig is being discussed here (https://bitcointalk.org/index.php?topic=38928.0). Multi-sig is a primitive operation that would enable quite a few of the contracts described here and on the wiki.


Title: Re: Designing distributed contracts
Post by: Andrew Vorobyov on October 14, 2011, 08:21:54 PM
https://bitcointalk.org/index.php?topic=48215.0