Add scriptPubKey enforced sendescrow and redeemescrow API calls
11 messages, 16 to 22 Jun 2011. Started by bgroff.
bgroff (5), Mike Hearn (4), Gavin Andresen (2)
I have a pull request here:
https://github.com/bitcoin/bitcoin/pull/319
From the README:
Bitcoin "escrow" are coins that are under the control of multiple parties. The initial implementation allows n parties to vote, with k good signatures needed (k <= n).
This eliminates single points of failure and reduces the trust required in many transaction use cases.
Use cases include Escrow (without trusting the escrow agent with the coins), immediate payment and funds locked with multi-party signatures.
This was inspired by https://forum.bitcoin.org/index.php?topic=8821.0 and https://forum.bitcoin.org/index.php?topic=4723.msg68804 .
Feedback on the pull is very much appreciated.
Thanks for writing this. It's great to see somebody run with the contracts protocol.
Your proposed protocol is simpler than the one I suggested, so I updated the Contracts wiki page to use it. However your implementation, as pointed out by Gavin, is too complicated. See my proposal on the wiki here:
https://en.bitcoin.it/wiki/Contracts
I think you can just use an output script of
2 <K1> <K2> <K3> 3 CHECKMULTISIGVERIFY
On Thu, Jun 16, 2011 at 6:53 AM, <bgroff@lavabit•com> wrote:
Quoted text (35 lines)
> I have a pull request here: > > https://github.com/bitcoin/bitcoin/pull/319 > > >From the README: > > Bitcoin "escrow" are coins that are under the control of multiple > parties. The initial implementation allows n parties to vote, with > k good signatures needed (k <= n). > > This eliminates single points of failure and reduces the trust required > in many transaction use cases. > > Use cases include Escrow (without trusting the escrow agent with the > coins), immediate payment and funds locked with multi-party signatures. > > This was inspired by https://forum.bitcoin.org/index.php?topic=8821.0 and > https://forum.bitcoin.org/index.php?topic=4723.msg68804 . > > Feedback on the pull is very much appreciated. > > > > > > ------------------------------------------------------------------------------ > EditLive Enterprise is the world's most technically advanced content > authoring tool. Experience the power of Track Changes, Inline Image > Editing and ensure content is compliant with Accessibility Checking. > http://p.sf.net/sfu/ephox-dev2dev > _______________________________________________ > Bitcoin-development mailing list > Bitcoin-development@lists•sourceforge•net > https://lists.sourceforge.net/lists/listinfo/bitcoin-development >
Oh, one other thing - as you point out yourself, escrow is only one use case for multsig transactions. So I suggest you don't use the word in the patch. Maybe instead call them multisign or multipay transactions.
On Wed, Jun 22, 2011 at 9:24 AM, Mike Hearn <mike@plan99•net> wrote:
Quoted text (2 lines)
> I think you can just use an output script of > 2 <K1> <K2> <K3> 3 CHECKMULTISIGVERIFY
I think it is time to start experimenting with MULTISIG transactions on testnet.
Mike: Did Satoshi ever tell you what he was thinking for the best way to implement MULTISIG transactions? I'm wondering if hard-coding new standard script templates in script.cpp Solver():
vTemplates.push_back(CScript() << OP_1 << OP_PUBKEY << OP_PUBKEY << OP_2 << OP_CHECKMULTISIGVERIFY); vTemplates.push_back(CScript() << OP_2 << OP_PUBKEY << OP_PUBKEY << OP_2 << OP_CHECKMULTISIGVERIFY); vTemplates.push_back(CScript() << OP_1 << OP_PUBKEY << OP_PUBKEY << OP_PUBKEY << OP_3 << OP_CHECKMULTISIGVERIFY); vTemplates.push_back(CScript() << OP_2 << OP_PUBKEY << OP_PUBKEY << OP_PUBKEY << OP_3 << OP_CHECKMULTISIGVERIFY); vTemplates.push_back(CScript() << OP_3 << OP_PUBKEY << OP_PUBKEY << OP_PUBKEY << OP_3 << OP_CHECKMULTISIGVERIFY);
... would be the right approach to support 1/2 of 2 and 1/2/3 of 3 signatures. It'd be nice if there were generic OP_N << OP_PUBKEY_N << OP_N ... template matching opcodes, but there aren't.
I'm also wondering if it makes sense to just support 2-of-2 (for validate-on-multiple-devices) and 2-of-3 (for escrow) for now.
I think all of these could use a new type of bitcoin payment address; it might make sense for THAT to be generic, maybe containing: version byte m n hash of xor of all n public keys checksum
I'm most interested in the 2-of-2 case; I think merchants and exchanges need bitcoin deposit/payment addresses that they can make secure by requiring a 2-step signature process for spending those funds.
Quoted text (2 lines)
> Mike: Did Satoshi ever tell you what he was thinking for the best way > to implement MULTISIG transactions?
He didn't. Satoshi told me very little unfortunately. What he did tell me, I've written up about half of it. I still have high frequency trading and some details of obscure SIGHASH types to go, but I wanted to find examples to illustrate them first as Satoshi only gave the vaguest of outlines.
Quoted text (2 lines)
> I'm wondering if hard-coding new standard script templates in > script.cpp Solver():
CHECKMULTISIG allows up to 20 keys, I think. So it'd probably be better to just have a bit of custom logic that checks if the script is of the right form.
Quoted text (3 lines)
> ... would be the right approach to support 1/2 of 2 and 1/2/3 of 3 > signatures. It'd be nice if there were generic > OP_N << OP_PUBKEY_N << OP_N ... template matching opcodes, but there aren't.
I suppose they could be added if need be. Template matching opcodes might come in useful later when clients only want to download transactions of interest to them.
Quoted text (2 lines)
> I'm also wondering if it makes sense to just support 2-of-2 (for > validate-on-multiple-devices) and 2-of-3 (for escrow) for now.
Given the costs involved with adding new transaction types, I'd go for allowing any number of signatures up to the max.
Quoted text (7 lines)
> I think all of these could use a new type of bitcoin payment address; > it might make sense for THAT to be generic, maybe containing: > version byte > m > n > hash of xor of all n public keys > checksum
I don't understand what this is for. For triggering such a transaction via the UI, I think establishing a higher level protocol would be needed. It's a separate step.
For instance, it's not safe to use escrow until you've checked that the escrow key is owned by who you think it is. Otherwise a buyer could give you a 2-of-3 transaction where they own both keys. So there needs to be some kind of protocol (probably HTTP based) where the buyer communicates to the merchant a list of acceptable escrow agencies, the merchant intersects with the list of agencies it accepts, there needs to be a way to request a pubkey from a remote domain, one side needs to be able to challenge that domain with a nonce, etc. It's quite complicated and would need to be specced out independently of supporting multipay transactions.
Quoted text (4 lines)
> I'm most interested in the 2-of-2 case; I think merchants and > exchanges need bitcoin deposit/payment addresses that they can make > secure by requiring a 2-step signature process for spending those > funds.
Yes it's one way to achieve security. Having BitBanks that store your coins and require you to verify tx acceptance with an external device is even stronger, because that external device can be guaranteed virus/clone-proof. Some banks do this today for wire transfers (they implicitly assume you get the wire details out of band or that no virus can rewrite wiring instructions to point somewhere else).
But it'll be a while yet before any such company arises. Until then 2-of-2 transactions are probably a good halfway point.
...
Quoted text (11 lines)
>> I think all of these could use a new type of bitcoin payment address; >> it might make sense for THAT to be generic, maybe containing: >> version byte >> m >> n >> hash of xor of all n public keys >> checksum > > I don't understand what this is for. For triggering such a transaction > via the UI, I think establishing a higher level protocol would be > needed. It's a separate step.
You're right, it doesn't make sense. The use case I would like to work is:
I setup an escrow that requires m of n signatures to release funds, securely getting public keys from the other n-1 parties.
Now we all need to fund the escrow. Or maybe other people can fund the escrow (it just takes m of n of us to decide when/how/where to spend the funds).
It would be spiffy to publish a new type of bitcoin address that is an "m of n address", that anybody could pay into, but would require m of n signatures to spend. Publishing a really really long address with all n public keys would work.
It would be great if the "higher level protocol" for pay-to-escrow was just get a bitcoin address via https (or other secure mechanism), like we do now for pay-to-single-party. Where the person you're paying has their own mechanisms for generating or fetching/authenticating the public keys, and knows which bitcoin addresses they've published.
All of which makes me wonder if the straightforward "n PUBKEYS m CHECKMULTISIG" transaction type is the right thing to do. Following the pattern of our standard DUP HASH160 etc. transaction type, maybe 2 of 2 and 2 of three should be:
2DUP ADD HASH160 ...hash(pubkey1+2)... EQUALVERIFY 2 2 ROLL CHECKMULTISIGVERIFY 3DUP ADD ADD HASH160 ...hash(pubkey1+2+3)... EQUALVERIFY 2 3 ROLL CHECKMULTISIGVERIFY
Spending those transactions would mean putting the m signatures and the n public keys in the TxIn, but sending funds you'd only need the hash of the sum of the public keys.
Quoted text (5 lines)
> Oh, one other thing - as you point out yourself, escrow is only one use > case > for multsig transactions. So I suggest you don't use the word in the > patch. > Maybe instead call them multisign or multipay transactions.
Agreed. I'll rename to multisign.
Quoted text (2 lines)
> All of which makes me wonder if the straightforward "n PUBKEYS m > CHECKMULTISIG" transaction type is the right thing to do.
As far as I understand the only reason for hashing the public key is for typing convenience. Otherwise we'd all just pass raw public keys around and use the simple form seen in the direct-to-ip case.
But as there'd need to be a higher level protocol on top of the multipay transactions in order to verify who the other parties are, there's no need for typing convenience. It'd all be done automatically.
Gavin said:
Quoted text (4 lines)
> It would be spiffy to publish a new type of bitcoin address that is an > "m of n address", that anybody could pay into, but would require m of > n signatures to spend. Publishing a really really long address with > all n public keys would work.
I currently have 2,ADDR1,ADDR2,ADDR3 (2-of-3 example) as this new address type.
Quoted text (6 lines)
> > It would be great if the "higher level protocol" for pay-to-escrow was > just get a bitcoin address via https (or other secure mechanism), like > we do now for pay-to-single-party. Where the person you're paying has > their own mechanisms for generating or fetching/authenticating the > public keys, and knows which bitcoin addresses they've published.
Agreed.
Quoted text (13 lines)
> All of which makes me wonder if the straightforward "n PUBKEYS m > CHECKMULTISIG" transaction type is the right thing to do. > Following the pattern of our standard DUP HASH160 etc. transaction > type, maybe 2 of 2 and 2 of three should be: > > 2DUP ADD HASH160 ...hash(pubkey1+2)... EQUALVERIFY 2 2 ROLL > CHECKMULTISIGVERIFY > 3DUP ADD ADD HASH160 ...hash(pubkey1+2+3)... EQUALVERIFY 2 3 ROLL > CHECKMULTISIGVERIFY > > Spending those transactions would mean putting the m signatures and > the n public keys in the TxIn, but sending funds you'd only need the > hash of the sum of the public keys.
This is similar to the way the current implementation works. It uses HASH160, but there's no attempt to save space by hashing the sum of the pubkeys. The major advantage of summing is shorter address for the end user to copy-paste. The disadvantage is the need for long term storage of the key set so you know what keys to sign with.
Quoted text (3 lines)
> -- > Gavin Andresen > http://clearcoin.com/
Quoted text (3 lines)
> Gavin said: >> 3DUP ADD ADD HASH160 ...hash(pubkey1+2+3)... EQUALVERIFY 2 3 ROLL >> CHECKMULTISIGVERIFY
On second thought, I'm not sure this is workable. You would have to distribute each party's pubkey ahead of time, otherwise you run the risk that a party falls off the face of the earth and then you can't provide the pubkeys to have hash(pubkey1+2+3) EQUALVERIFY.
If you have to distribute the pubkeys ahead of time, then the reduction in address length becomes moot.
So it seems to be either distribute the pubkeys or distribute the hash160(pubkey)'s.
Gavin wrote:
Quoted text (4 lines)
> It would be spiffy to publish a new type of bitcoin address that is an > "m of n address", that anybody could pay into, but would require m of > n signatures to spend. Publishing a really really long address with > all n public keys would work.
Here's a strawman use-case for a browser centric flow for a 2-of-3 scenario.
Funding:
* User is on Merchant site on the checkout page * User selects a transaction Observer (I'm trying to get away from using the word escrow, because the funds are not held by the third party) * Merchant redirects to the Observer, passing in the Merchant's payout address * The User enters User's address * Observer presents multisign address "2,merchant-addr,user-addr,observer-addr" and terms and conditions - i.e. under what circumstances the Observer will sign * User copy/pastes the multisign address to their bitcoin client and sends funds * After some blocks go by, merchant ships
Redemption:
* Merchant reminds User to release funds * User creates a partial tx paying out to merchant-addr and emails or copy-pastes to Merchant * Merchant signs and publishes the tx
Funding requires two pastes and redemption requires one. A browser plug-in would reduce the User effort to a couple of confirmatory clicks - "do you want to send X BTC to Merchant Y with Observer Z?" and "do you want to release X BTC to Merchant Y?".