Bitcoin Forum
November 09, 2024, 01:29:38 PM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: [SOLVED] [HELP NEEDED] MultiSig transactions in real life (working scenario)  (Read 1843 times)
xand (OP)
Member
**
Offline Offline

Activity: 107
Merit: 10


View Profile
February 16, 2014, 01:17:55 AM
Last edit: February 16, 2014, 03:05:36 PM by xand
 #1

Hello all,

I'm looking for how to make 2-of-3 multisig transactions. I was looking for a solution for a whole day but I just don't get it.

As I can understand the starting point is having three keypairs (let's suppose they are in form user/public key/private key):

1. Alice/AlicePublicKey/AlicePrivateKey. (Alice is actual buyer)
2. John/JohnPublicKey/JohnPrivateKey. (John is actual seller)
3. Ben/BenPublicKey/BenPrivateKey. (Ben holds the escrow)

This is input data, private key are not known by everyone at this point.

So, according to Gavin's example, the first step is to create multisig address:

Code:
./bitcoind createmultisig 2 '["AlicePublicKey","JohnPublicKey","BenPublicKey"]'

OK. The output is:

Code:
{
    "address" : "[b]3C1qwWFkRxuu7ConqheN1BXChDXMhXtH89[/b]",
    "redeemScript" : "522103d5d32e915a2e6ba094b33614b317e79f270649c6203047de1df3702f24f99ffa2102cefd67d750ba01e5c34d00ffb7de1cd63f7c1ca1ee64ed4cd00e86e3840a12cd21034fc4f66fca3b82384d8c6f9eeaacda61aa29119d683680455baeb831542f2eda53ae"
}

Let's suppose that this is done for escrow purposes and Alice is buying something from John. So, here goes my first question. Can I use the address 3C1qwWFkRxuu7ConqheN1BXChDXMhXtH89 to put funds in this transaction? I mean, at this point, can I tell Alice "OK Alice, make the payment to address 3C1qwWFkRxuu7ConqheN1BXChDXMhXtH89. I guess the answer is yes, but I need confirmation.

This is the first part. Now the second part. Let's suppose the delivery goes smooth and now John needs to get the funds stored in the transaction. He asks Alice: "Hey, give me your private key", and Alice gives him AlicePrivateKey. Now John has two private keys: AlicePrivateKey and JohnPrivateKey (his own).

And now I get completely lost. What should John do in order to get his bitcoins? As long as I can understand it's not enough to have just two private keys and the address for the transaction. More data is required, what is that data?

By the way Gavin's example is fine. Only that, imho it does not apply to the real world, I mean, I get lost and confused when he uses all that low-level methods. What I need to know first is the minimum amount of infomation required to get the funds from the multisig transaction.

Thanks in advance.

P.D. I want to see how can this be achieved with reference bitcoin client implementation.
xand (OP)
Member
**
Offline Offline

Activity: 107
Merit: 10


View Profile
February 16, 2014, 11:12:17 AM
 #2

Nobody?
xand (OP)
Member
**
Offline Offline

Activity: 107
Merit: 10


View Profile
February 16, 2014, 02:59:52 PM
 #3

OK. Finally I solved the problem. I put the scenario.

Participants:
  • Alice. She wants to buy a product.
  • John. He want to sell a product.
  • Shop. Acts as a marketplace providing all necessary infrastructure.

Scenario: Alice wants to buy a product John is offering. They meet at Shop and agree the price. They want to use 2-of-3 mutisig transaction in order to assure everything goes smooth, like an escrow system. Let's say that Alice needs to pay to John BTC0.001. Here the shop comes to the scenario and prepares the transactions.
Shop asks to John and Alice to generate keypairs and also he generates his own keypair, they execute commands getnewaddress, validateaddress and dumpprivkey

At this point we have the following input data (I will use a real data from the example, the format is pubkey/privatekey). The information in bold is actually what the participants submit to shop.
  • Alice: 03ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb5 / L2RD2bMZzEwEvFw3pHD9oWZf32kR1NxeAYMjW4Qwnf7UpEVbVkUX
  • John: 03cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e / L5ieGS7c5sY5NVSck7ZnBLtYbAiKBmRdAJQGArpKRwBWEi9cEFm6
  • Shop: 03becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c / L5KeMAjfbNMAF17x1Vo1KZXt1EZLQKYkJXEznX3APiiKSznCZzbw

Now, the Shop has 3 public keys, we assume that the Shop knows his own public key.

The Shop generates bitcoin address to make the payment issuing the following command:

Code:
createmultisig 2 '["03cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e", "03ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb5", "03becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c"]'

The output is:

Code:
{
    "address" : "3M9ENELPqJKqDsU8BfEuoyEcKHVz78jJoE",
    "redeemScript" : "522103cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e2103ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb52103becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c53ae"
}

As you can see we have two more inputs, the address and the redeemScript.

Now, it's extremely important that the Shop makes public this information between the other participants. After this point we assume that John and Alice know the redeemScript and the address.

Next step. The Shop asks to Alice to transfer funds to the generated address. Alice transfers the funds.

Time passes. John checks the address and sees that the balance is ok. So, he ships the product to Alice. Alice receives the product and wants to release funds to John.

At this points two scenarios are possible. If we assume that the shop is trusted by all participants the operation may be done by the Shop automatically. Otherwise, the operation must be done by John. Let's suppose the the best case that the Shop is trusted by everyone so John provides the address to get paid the funds Alice releases to him.

So, I told that Alice received the product from John and now she wants to release the funds to him. She provides her private key to the Shop. The Shop will transfer funds from multisig transaction to John's personal address.

The input data for this is following:
  • Multisig address: 3M9ENELPqJKqDsU8BfEuoyEcKHVz78jJoE
  • redeemScript: 522103cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e2103ccd25 2273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb52103becc7cf66dbfe291 0c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c53ae
  • Alice private key: L2RD2bMZzEwEvFw3pHD9oWZf32kR1NxeAYMjW4Qwnf7UpEVbVkUX
  • Shop private key: L5KeMAjfbNMAF17x1Vo1KZXt1EZLQKYkJXEznX3APiiKSznCZzbw

In order to proceed the Shop must collect some additional info from the blockchain.

First of all the Shop needs txid for the transaction. For this he can use blockchain.info, for example, or his own in-house blockchain parser since the reference Bitcoin client does not offer this functionality.
Let's say he decides to use blockchain.info, so he make a query with the multisig address: 3M9ENELPqJKqDsU8BfEuoyEcKHVz78jJoE. The txid is 30007445ce2b81b17ad202cd8485a6d6d4607a8fe7da3bee1eddc5e129e6879a, this is the transaction that Alice issued to pay.

Now the Shop has all the infomation for issuing the payment to John.

Step 1. Get raw transaction.

Code:
getrawtransaction 30007445ce2b81b17ad202cd8485a6d6d4607a8fe7da3bee1eddc5e129e6879a

Output:

Code:
01000000022b9c78e5e1195c11720e09720d9f3afc0e7d32e7bc8bfa1276123c21b30eeec5000000006c49304602210083afb8b9e942eb685f54a901a40c0541114d30f4b41c66e01099dab737bd97f0022100b948c5ce1646b925dfcf117300c1fe33556b27192f7751de90289643114c24f9012102afdb375f849a6cc9dfd677f300e792e1189756faf674503db47cb635bb8b1303ffffffff373f2b7842530a1039b64dbf4fa297762cbf5d41eefd8a0185794342f491b577000000006b4830450220013f9228f06175327f7319c406207ad6357858bbf51d6736515bb3a9d508db29022100f1429410ec5c20bea03be5c6579136d9323c72061428be2b509eaf1642665a1b012102133ca1119814debbfe7f3d38baa70df8b849caa441a6a2c686c928b8172c27f3ffffffff01a08601000000000017a914d55f97790544910751f9bf46834131b6defcb5248700000000

Step 2. Collect data from raw transaction. The Shop needs to find the scriptPubKey field (it's hex value).

Code:
decoderawtransaction 01000000022b9c78e5e1195c11720e09720d9f3afc0e7d32e7bc8bfa1276123c21b30eeec5000000006c49304602210083afb8b9e942eb685f54a901a40c0541114d30f4b41c66e01099dab737bd97f0022100b948c5ce1646b925dfcf117300c1fe33556b27192f7751de90289643114c24f9012102afdb375f849a6cc9dfd677f300e792e1189756faf674503db47cb635bb8b1303ffffffff373f2b7842530a1039b64dbf4fa297762cbf5d41eefd8a0185794342f491b577000000006b4830450220013f9228f06175327f7319c406207ad6357858bbf51d6736515bb3a9d508db29022100f1429410ec5c20bea03be5c6579136d9323c72061428be2b509eaf1642665a1b012102133ca1119814debbfe7f3d38baa70df8b849caa441a6a2c686c928b8172c27f3ffffffff01a08601000000000017a914d55f97790544910751f9bf46834131b6defcb5248700000000

Output:

Code:
{
"txid" : "30007445ce2b81b17ad202cd8485a6d6d4607a8fe7da3bee1eddc5e129e6879a",
"version" : 1,
"locktime" : 0,
"vin" : [
{
"txid" : "c5ee0eb3213c127612fa8bbce7327d0efc3a9f0d72090e72115c19e1e5789c2b",
"vout" : 0,
"scriptSig" : {
"asm" : "304602210083afb8b9e942eb685f54a901a40c0541114d30f4b41c66e01099dab737bd97f0022100b948c5ce1646b925dfcf117300c1fe33556b27192f7751de90289643114c24f901 02afdb375f849a6cc9dfd677f300e792e1189756faf674503db47cb635bb8b1303",
"hex" : "49304602210083afb8b9e942eb685f54a901a40c0541114d30f4b41c66e01099dab737bd97f0022100b948c5ce1646b925dfcf117300c1fe33556b27192f7751de90289643114c24f9012102afdb375f849a6cc9dfd677f300e792e1189756faf674503db47cb635bb8b1303"
},
"sequence" : 4294967295
},
{
"txid" : "77b591f442437985018afdee415dbf2c7697a24fbf4db639100a5342782b3f37",
"vout" : 0,
"scriptSig" : {
"asm" : "30450220013f9228f06175327f7319c406207ad6357858bbf51d6736515bb3a9d508db29022100f1429410ec5c20bea03be5c6579136d9323c72061428be2b509eaf1642665a1b01 02133ca1119814debbfe7f3d38baa70df8b849caa441a6a2c686c928b8172c27f3",
"hex" : "4830450220013f9228f06175327f7319c406207ad6357858bbf51d6736515bb3a9d508db29022100f1429410ec5c20bea03be5c6579136d9323c72061428be2b509eaf1642665a1b012102133ca1119814debbfe7f3d38baa70df8b849caa441a6a2c686c928b8172c27f3"
},
"sequence" : 4294967295
}
],
"vout" : [
{
"value" : 0.00100000,
"n" : 0,
"scriptPubKey" : {
"asm" : "OP_HASH160 d55f97790544910751f9bf46834131b6defcb524 OP_EQUAL",
"hex" : "a914d55f97790544910751f9bf46834131b6defcb52487",
"reqSigs" : 1,
"type" : "scripthash",
"addresses" : [
"3M9ENELPqJKqDsU8BfEuoyEcKHVz78jJoE"
]
}
}
]
}

Step 3. Create transaction for John.

Code:
createrawtransaction '[{"txid":"30007445ce2b81b17ad202cd8485a6d6d4607a8fe7da3bee1eddc5e129e6879a","vout":0,"scriptPubKey":"a914d55f97790544910751f9bf46834131b6defcb52487","redeemScript":"522103cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e2103ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb52103becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c53ae"}]' '{"1NxTtvhRce68MTAbogosj9zCK5mTG493XZ":0.001}'

Output (the transaction itself not signed):

Code:
01000000019a87e629e1c5dd1eee3bdae78f7a60d4d6a68584cd02d27ab1812bce457400300000000000ffffffff01a0860100000000001976a914f0d7f86c2d958d62824e43e2e7814a17bf2887fd88ac00000000

Step 4. Sign the transaction with the  the first key (Shop's key).

Code:
signrawtransaction '01000000019a87e629e1c5dd1eee3bdae78f7a60d4d6a68584cd02d27ab1812bce457400300000000000ffffffff01a0860100000000001976a914f0d7f86c2d958d62824e43e2e7814a17bf2887fd88ac00000000' '[{"txid":"30007445ce2b81b17ad202cd8485a6d6d4607a8fe7da3bee1eddc5e129e6879a","vout":0,"scriptPubKey":"a914d55f97790544910751f9bf46834131b6defcb52487","redeemScript":"522103cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e2103ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb52103becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c53ae"}]' '["L5KeMAjfbNMAF17x1Vo1KZXt1EZLQKYkJXEznX3APiiKSznCZzbw"]'
Output:

Code:
{
"hex" : "01000000019a87e629e1c5dd1eee3bdae78f7a60d4d6a68584cd02d27ab1812bce4574003000000000b600493046022100ddeda29cb8553a1200add8f344c1a71e6ed433f5c0911c892aa73ea72e47d5d1022100ee6bf9ffbb2401e67ed0f3aebade755dd28b84ca9608fb0849b8685541f38761014c69522103cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e2103ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb52103becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c53aeffffffff01a0860100000000001976a914f0d7f86c2d958d62824e43e2e7814a17bf2887fd88ac00000000",
"complete" : false
}

Step 5. Sign the transaction with the second private key (Alice's key).
Code:
signrawtransaction '01000000019a87e629e1c5dd1eee3bdae78f7a60d4d6a68584cd02d27ab1812bce4574003000000000b600493046022100ddeda29cb8553a1200add8f344c1a71e6ed433f5c0911c892aa73ea72e47d5d1022100ee6bf9ffbb2401e67ed0f3aebade755dd28b84ca9608fb0849b8685541f38761014c69522103cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e2103ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb52103becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c53aeffffffff01a0860100000000001976a914f0d7f86c2d958d62824e43e2e7814a17bf2887fd88ac00000000' '[{"txid":"30007445ce2b81b17ad202cd8485a6d6d4607a8fe7da3bee1eddc5e129e6879a","vout":0,"scriptPubKey":"a914d55f97790544910751f9bf46834131b6defcb52487","redeemScript":"522103cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e2103ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb52103becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c53ae"}]' '["L2RD2bMZzEwEvFw3pHD9oWZf32kR1NxeAYMjW4Qwnf7UpEVbVkUX"]'

Output:

Code:
{
"hex" : "01000000019a87e629e1c5dd1eee3bdae78f7a60d4d6a68584cd02d27ab1812bce4574003000000000fd000100493046022100ddeda29cb8553a1200add8f344c1a71e6ed433f5c0911c892aa73ea72e47d5d1022100ee6bf9ffbb2401e67ed0f3aebade755dd28b84ca9608fb0849b8685541f3876101493046022100b05e0e9b19546fc0ab712aad2c6a66874ae80050415c855fb8b1fadfba579e620221008f8502d5da831e7a837bdf3ffbca2a92deb7ad2aea749dcae7759555873faf8f014c69522103cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e2103ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb52103becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c53aeffffffff01a0860100000000001976a914f0d7f86c2d958d62824e43e2e7814a17bf2887fd88ac00000000",
"complete" : true
}

Step 6. Send the transaction to John.

Code:
sendrawtransaction 01000000019a87e629e1c5dd1eee3bdae78f7a60d4d6a68584cd02d27ab1812bce4574003000000000fd000100493046022100ddeda29cb8553a1200add8f344c1a71e6ed433f5c0911c892aa73ea72e47d5d1022100ee6bf9ffbb2401e67ed0f3aebade755dd28b84ca9608fb0849b8685541f3876101493046022100b05e0e9b19546fc0ab712aad2c6a66874ae80050415c855fb8b1fadfba579e620221008f8502d5da831e7a837bdf3ffbca2a92deb7ad2aea749dcae7759555873faf8f014c69522103cb6c09843e606b59336b3272618077936bf962ecc35ae60f5028436e9ddec72e2103ccd252273248b3ebd34595976126361882edeb00af0c519b6b23e49341165bb52103becc7cf66dbfe2910c86ce2e63c6876db6620f931e207ce36bd9a2d446658e8c53aeffffffff01a0860100000000001976a914f0d7f86c2d958d62824e43e2e7814a17bf2887fd88ac00000000

Output:

Code:
3428e9c1bc3b9382af1cd5921a0f6f31b7b152194aef9302589dfa1877a58dde

John receives the money.

That's all folks, the transaction is complete.

I think I will update this thread later with things that I will go improving.
fbueller
Sr. Member
****
Offline Offline

Activity: 412
Merit: 287


View Profile
February 18, 2014, 01:58:56 AM
Last edit: March 15, 2014, 11:06:08 PM by fbueller
 #4

You shouldn't ask anyone to expose their private key. You should give the buyer and seller the unsigned transaction. One of them signs the transaction, pastes it to the site (it could be an email, or PM, but really you should check that a signature was added using that users public key) and then the vendor signs it to complete the transaction, and then broadcast it.

The transaction is mined, and then your site can detect that the payment went through. I'm coding a site that implements all this in PHP: http://multisig.bitwasp.co

Bitwasp Developer.
waxwing
Sr. Member
****
Offline Offline

Activity: 469
Merit: 253


View Profile
February 19, 2014, 06:00:57 AM
 #5

You shouldn't ask anyone to expose their private key. You should give the buyer and seller the unsigned transaction. One of them signs the transaction, pastes it to the site (it could be an email, or PM, but really you should check that a signature was added using that users public key) and then the vendor signs it to complete the transaction, and then broadcast it.
Yes, or Alice just sends the signature itself rather than a partially signed transaction. Arguably simpler. But for sure, not private key Smiley

I'm still not sure what xand found unclear about Gavin's example.

PGP fingerprint 2B6FC204D9BF332D062B 461A141001A1AF77F20B (use email to contact)
ponchoman
Newbie
*
Offline Offline

Activity: 39
Merit: 0


View Profile
February 19, 2014, 08:04:36 AM
 #6

In your second example Alice ends up giving the shop the same private key on two occasions.
fbueller
Sr. Member
****
Offline Offline

Activity: 412
Merit: 287


View Profile
February 19, 2014, 01:53:21 PM
 #7

Yes, or Alice just sends the signature itself rather than a partially signed transaction. Arguably simpler. But for sure, not private key Smiley

I'm still not sure what xand found unclear about Gavin's example.

waxwing, how do you mean they could pass just the signature itself? The signature would be embedded in the transaction hex?

Bitwasp Developer.
waxwing
Sr. Member
****
Offline Offline

Activity: 469
Merit: 253


View Profile
February 20, 2014, 01:56:12 AM
 #8

I'm not sure how else to say it; you transfer the signature (as hex, say) to the other party and they insert it into the transaction. It's not really different from passing the partially signed transaction (since the signature fixes the transaction anyway).

PGP fingerprint 2B6FC204D9BF332D062B 461A141001A1AF77F20B (use email to contact)
fbueller
Sr. Member
****
Offline Offline

Activity: 412
Merit: 287


View Profile
February 21, 2014, 11:18:25 AM
 #9

I'm not sure how else to say it; you transfer the signature (as hex, say) to the other party and they insert it into the transaction. It's not really different from passing the partially signed transaction (since the signature fixes the transaction anyway).

I mean how does the other party do it as you propose? Using software other than the client? Or will people be pasting hex into hex?

Bitwasp Developer.
waxwing
Sr. Member
****
Offline Offline

Activity: 469
Merit: 253


View Profile
February 21, 2014, 03:36:06 PM
 #10

I'm not sure how else to say it; you transfer the signature (as hex, say) to the other party and they insert it into the transaction. It's not really different from passing the partially signed transaction (since the signature fixes the transaction anyway).

I mean how does the other party do it as you propose? Using software other than the client? Or will people be pasting hex into hex?

Ah yes, I see your question. It needs to be coded of course into any multisig application you develop. And perhaps it is not so simple using bitcoind's API, I'm not sure. I've been using pybitcointools by Vitalik Buterin. It allows me to easily build a signature using a call to a function multisign() and then my software can message that between clients.

There is a thread on pybitcointools here in the Dev forum that walks through how to do a multisig transaction in that library.

PGP fingerprint 2B6FC204D9BF332D062B 461A141001A1AF77F20B (use email to contact)
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!