Bitcoin Forum
November 04, 2024, 09:50:52 AM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Second signature in multisig  (Read 1342 times)
cimm (OP)
Newbie
*
Offline Offline

Activity: 5
Merit: 0


View Profile
April 22, 2014, 10:23:15 AM
 #1

Trying to understand the following:

I signed a 2-3 multisig raw transaction and sent the signed hash to the counter-party. The counter-party will sign with their private key and send the transaction to the network.

As far as I understand it the counter-party will need to include the unspent outputs to the signrawtransaction RPC command like I had to do the first time (the hash I signed is not enough, is it?). Now, how does the counter-party know which unspent outputs to include? I suppose the counter-party needs the same outputs as me and he might pick different ones or pick a different fee. Am I supposed to send him the signed hash and the transaction array I used to sign it the first time (including the redeemScript)?

Thanks!
fbueller
Sr. Member
****
Offline Offline

Activity: 412
Merit: 287


View Profile
April 22, 2014, 11:25:56 AM
 #2

Trying to understand the following:

I signed a 2-3 multisig raw transaction and sent the signed hash to the counter-party. The counter-party will sign with their private key and send the transaction to the network.

As far as I understand it the counter-party will need to include the unspent outputs to the signrawtransaction RPC command like I had to do the first time (the hash I signed is not enough, is it?). Now, how does the counter-party know which unspent outputs to include? I suppose the counter-party needs the same outputs as me and he might pick different ones or pick a different fee. Am I supposed to send him the signed hash and the transaction array I used to sign it the first time (including the redeemScript)?

Thanks!

If you are both using Bitcoin Core, you just need to do:
addmultisigaddress 2 '["pubkey1","pubkey2","pubkey3"]'

Your wallet will import the address to your wallet, and make it possible to sign the transaction.

When you added the first signature, you would have needed to supply the unspent outputs, because the redeemScript needs to be supplied. You don't need to do this the second time, because the redeemScript is now embedded in the signature.  (Normal transactions are <sig> <pubkey>, but 2of3 P2SH is: OP_0 <sig1> <sig2><redeemScript, which is just 3 pubkeys encoded>)

You will only need to give him the partially signed transaction, and he should naturally be able to do the addmultisigaddress command himself.

Bitwasp Developer.
edmundedgar
Sr. Member
****
Offline Offline

Activity: 352
Merit: 250


https://www.realitykeys.com


View Profile WWW
April 22, 2014, 01:31:00 PM
 #3

Trying to understand the following:

I signed a 2-3 multisig raw transaction and sent the signed hash to the counter-party. The counter-party will sign with their private key and send the transaction to the network.

As far as I understand it the counter-party will need to include the unspent outputs to the signrawtransaction RPC command like I had to do the first time (the hash I signed is not enough, is it?). Now, how does the counter-party know which unspent outputs to include? I suppose the counter-party needs the same outputs as me and he might pick different ones or pick a different fee. Am I supposed to send him the signed hash and the transaction array I used to sign it the first time (including the redeemScript)?

Thanks!

To be clear, you've already put some money in a transaction that requires 2/3 multisigs to spend, and you want to create a new transaction to redeem it, right?

Maybe this is what you meant, but what you'd normally send wouldn't be the signed _hash_ of the transaction, it would be the actual (partially) signed transaction. So you've already specified the outputs in the transaction that you send to your counterparty, and they're in the transaction you're giving him to sign. Your counterparty just needs to add signatures, and you're done.

If you're using bitcoind for this you might want to peek at the thing that you're trying to send to your counterparty, which should make this clear, eg:
Code:
./bitcoind decoderawtransaction 0100000001aca7f3b45654c230e0886a57fb988c3044ef5e8f7f39726d305c61d5e818903c00000000fd5d010048304502200187af928e9d155c4b1ac9c1c9118153239aba76774f775d7c1f9c3e106ff33c0221008822b0f658edec22274d0b6ae9de10ebf2da06b1bbdaaba4e50eb078f39e3d78014730440220795f0f4f5941a77ae032ecb9e33753788d7eb5cb0c78d805575d6b00a1d9bfed02203e1f4ad9332d1416ae01e27038e945bc9db59c732728a383a6f1ed2fb99da7a4014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353aeffffffff0140420f00000000001976a914ae56b4db13554d321c402db3961187aed1bbed5b88ac00000000
fbueller
Sr. Member
****
Offline Offline

Activity: 412
Merit: 287


View Profile
April 22, 2014, 01:34:49 PM
 #4

I figured he meant the signed hex.

I just tested this out on 0.9, once you have added the address to your wallet using addmultisigaddress, and the wallet is fully up to date, it will add the signature without having to supply the inputs. But nothing stops you from supplying them anyway if they're valid.




Bitwasp Developer.
kjj
Legendary
*
Offline Offline

Activity: 1302
Merit: 1026



View Profile
April 22, 2014, 02:12:09 PM
 #5

I figured he meant the signed hex.

I just tested this out on 0.9, once you have added the address to your wallet using addmultisigaddress, and the wallet is fully up to date, it will add the signature without having to supply the inputs. But nothing stops you from supplying them anyway if they're valid.

This has been true for a while.  But it is pointless.  Adding all of the keys to one wallet really defeats the purpose of having multisig.

Trying to understand the following:

I signed a 2-3 multisig raw transaction and sent the signed hash to the counter-party. The counter-party will sign with their private key and send the transaction to the network.

As far as I understand it the counter-party will need to include the unspent outputs to the signrawtransaction RPC command like I had to do the first time (the hash I signed is not enough, is it?). Now, how does the counter-party know which unspent outputs to include? I suppose the counter-party needs the same outputs as me and he might pick different ones or pick a different fee. Am I supposed to send him the signed hash and the transaction array I used to sign it the first time (including the redeemScript)?

What the second signer needs is enough information to sign the transaction, nothing more, nothing less.

Because a P2SH prevout doesn't include enough information for signing in the block chain, the first signer needs to provide the redeemscript.  The script gets incorporated into the new transaction during the first signing, and does not need to be supplied again by the second signer.

In the scenario described, you should be able to just send the partially signed transaction.

17Np17BSrpnHCZ2pgtiMNnhjnsWJ2TMqq8
I routinely ignore posters with paid advertising in their sigs.  You should too.
fbueller
Sr. Member
****
Offline Offline

Activity: 412
Merit: 287


View Profile
April 23, 2014, 12:40:15 AM
 #6

This has been true for a while.  But it is pointless.  Adding all of the keys to one wallet really defeats the purpose of having multisig.

I said using the addmultisigaddress command with the three public keys, not adding all the private keys to the wallet?

Because a P2SH prevout doesn't include enough information for signing in the block chain, the first signer needs to provide the redeemscript.  The script gets incorporated into the new transaction during the first signing, and does not need to be supplied again by the second signer.

In the scenario described, you should be able to just send the partially signed transaction.

Doing addmultisigaddress stores the address and the redeemScript in the wallet. And since all parties to the transaction should have the public keys, they can see the redeemScript for themselves using createmultisig <same arguments as addmultisigaddress>. But they won't need to do this, because the wallet stores it, and watches for transactions to this pay-to-script-hash address.

The redeemScript is just the public keys encoded, along with m, and n, (m-of-n address). Once imported the wallet will create the redeemScript on the fly and use that when creating the transaction. The wallet still needs to know the scriptPubKey, which it will have if it's fully synced. If it's being kept offline, you need to pass the previous TxOuts, so the client knows key to sign the new input with.


Bitwasp Developer.
berliston
Jr. Member
*
Offline Offline

Activity: 52
Merit: 21


View Profile
April 26, 2014, 04:40:03 PM
 #7

now I'm trying to understand all of this. it's beyond my comprehension!
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
May 08, 2014, 02:37:04 PM
Last edit: May 08, 2014, 02:47:33 PM by DeathAndTaxes
 #8

Is it possible to announce a partially signed transaction to the network?

No the network only handles fully signed transactions.  There are a lot of DOS type issues to work out before the network will support direct relaying of partially signed transactions (if ever).

Quote
If not, how can I tell Bob "please sign this transaction I already signed" without Bob having to know which unspent outputs I used to sign my part?

You will need to provide all the signers with everything they need to complete the signrawtransaction RPC (except their private keys obviously).  The output of signrawtransaction will show complete if it has the required number of signatures and the output from the first signer is passed to the second signer to the third signer ... to the mth signer.  Once m signatures have been obtained the output will show "complete" and the hex output provided is now a fully signed tx which can be submitted to the network by anyone using the sendrawtransaction call.

Gavin had a demo of a 2 of 3 signing I just need to find it in my totally unmanageable list of bookmarks.  I need a human "bookmark manager" to run by bookmark manager. Smiley
edmundedgar
Sr. Member
****
Offline Offline

Activity: 352
Merit: 250


https://www.realitykeys.com


View Profile WWW
May 08, 2014, 02:41:30 PM
 #9

The network won't relay a transaction unless it's valid, and it won't be valid until Bob has signed it.

The solution is to dump the transaction (not just the txid/hash, the actual whole transaction) out as hex, send it to Bob by some other method like email, bitmessage or carrier pigeon, and have him sign it. He can then broadcast the completed transaction to the network. Since you're giving him the transaction, containing everything except his signatures, he doesn't need to worry about adding your outputs. They're already in the transaction you sent him, which he just has to sign and broadcast.
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
May 08, 2014, 02:44:29 PM
Last edit: May 08, 2014, 04:45:41 PM by DeathAndTaxes
 #10

Here it is.  The sad thing is google was more efficient than trying to find it in my bookmarks. Smiley
https://gist.github.com/gavinandresen/3966071

A snippet to show the chain of outputs
Quote
# Create the spend-from-multisig transaction. Since the fund-the-multisig transaction
# hasn't been sent yet, I need to give txid, scriptPubKey and redeemScript:
./bitcoind createrawtransaction '[{"txid":"3c9018e8d5615c306d72397f8f5eef44308c98fb576a88e030c25456b4f3a7ac",
"vout":0,
"scriptPubKey":"a914f815b036d9bbbce5e9f2a00abd1bf3dc91e9551087",
"redeemScript":"52410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db5 5bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020 e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8 722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097 f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46 21353ae"}]'
'{"1GtpSrGhRGY5kkrNz4RykoqRQoJuG2L6DS":0.01}'

0100000001aca7f3b45654c230e0886a57fb988c3044ef5e8f7f39726d305c61d5e818903c00000 00000ffffffff0140420f00000000001976a914ae56b4db13554d321c402db3961187aed1bbed5b 88ac00000000


# ... Now I can partially sign it using one private key:
./bitcoind signrawtransaction ' 0100000001aca7f3b45654c230e0886a57fb988c3044ef5e8f7f39726d305c61d5e818903c00000 00000ffffffff0140420f00000000001976a914ae56b4db13554d321c402db3961187aed1bbed5b88ac0 0000000'
'[{"txid":"3c9018e8d5615c306d72397f8f5eef44308c98fb576a88e030c25456b4f3a7ac",
"vout":0,
"scriptPubKey":"a914f815b036d9bbbce5e9f2a00abd1bf3dc91e9551087",
"redeemScript":"52410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db5 5bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020 e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8 722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097 f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46 21353ae"}]'
'["5JaTXbAUmfPYZFRwrYaALK48fN6sFJp4rHqq2QSXs8ucfpE4yQU"]'
 
{
    "hex" : "0100000001aca7f3b45654c230e0886a57fb988c3044ef5e8f7f39726d305c61d5e818903c00000 000fd15010048304502200187af928e9d155c4b1ac9c1c9118153239aba76774f775d7c1f9c3e106ff33c02210 08822b0f658edec22274d0b6ae9de10ebf2da06b1bbdaaba4e50eb078f39e3d78014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db5 5bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020 e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8 722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097 f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46 21353aeffffffff0140420f00000000001976a914ae56b4db13554d321c402db3961187aed1bbed5b88ac0 0000000",
   "complete" : false
}
 
# ... and then take the "hex" from that and complete the 2-of-3 signatures using one of
# the other public keys (note the "hex" result getting longer):
./bitcoind signrawtransaction 0100000001aca7f3b45654c230e0886a57fb988c3044ef5e8f7f39726d305c61d5e818903c00000 000fd15010048304502200187af928e9d155c4b1ac9c1c9118153239aba76774f775d7c1f9c3e106ff33c02210 08822b0f658edec22274d0b6ae9de10ebf2da06b1bbdaaba4e50eb078f39e3d78014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db5 5bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020 e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8 722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097 f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46 21353aeffffffff0140420f00000000001976a914ae56b4db13554d321c402db3961187aed1bbed5b88ac0 0000000' '[{"txid":"3c9018e8d5615c306d72397f8f5eef44308c98fb576a88e030c25456b4f3a7ac",
"vout":0,
"scriptPubKey":"a914f815b036d9bbbce5e9f2a00abd1bf3dc91e9551087",
"redeemScript":"52410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db5 5bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020 e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8 722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097 f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46 21353ae"}]'
'["5JFjmGo5Fww9p8gvx48qBYDJNAzR9pmH5S389axMtDyPT8ddqmw"]'
 
{
    "hex" : "0100000001aca7f3b45654c230e0886a57fb988c3044ef5e8f7f39726d305c61d5e818903c00000 000fd15010048304502200187af928e9d155c4b1ac9c1c9118153239aba76774f775d7c1f9c3e106ff33c02210 08822b0f658edec22274d0b6ae9de10ebf2da06b1bbdaaba4e50eb078f39e3d78014730440220795f0f4f5941a77ae032ecb9e33753788d7eb5cb0c78d805575d6b00a1d9bfed02203 e1f4ad9332d1416ae01e27038e945bc9db59c732728a383a6f1ed2fb99da7a4014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db5 5bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020 e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8 722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097 f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46 21353aeffffffff0140420f00000000001976a914ae56b4db13554d321c402db3961187aed1bbed5b88ac0 0000000",
    "complete" : true
}


You may see differing answers because there are more than one way to perform multisig partial signing.  I find this method the most universal because everything is explicit and thus you can do this even from a bitcoind with no wallet, bitcoind is just used as a "transaction engine".  One modification is for all signers to import the P2SH address into their wallets so the redeem script doesn't need to be shared and included in the RPC call.  Another way to handle it is to have each party import the P2SH address and have their private key(s) in the wallet, private keys now don't need to be specified in the RPC.
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
May 08, 2014, 03:24:14 PM
 #11

Thank you DeathAndTaxes, I finally understand why my transactions where always rejected! Making progress and learning a lot. Thanks all!

No problem.  P2SH is tough, and the docs are sparse.  It is pretty cool stuff the first time you make it work though. Smiley  You may want to take a look at this thread and specifically this post for some "gotchas" regarding multisig.

https://bitcointalk.org/index.php?topic=585639.20

Remember with P2SH the payment to the address are just payments to a script hash so the network has no idea what the script is or if it is valid.   Script validation doesn't occur until the redeem script is supplied at the time a transaction "spending" funds from the address is created.  This  means you can lose funds (temporarily or permanently) by sending funds to an address which can never be spent because the script will be rejected.



edmundedgar
Sr. Member
****
Offline Offline

Activity: 352
Merit: 250


https://www.realitykeys.com


View Profile WWW
May 09, 2014, 12:57:41 AM
 #12

The solution is to dump the transaction (not just the txid/hash, the actual whole transaction) out as hex, send it to Bob by some other method like email.

How exactly do I do this?

With 'a hex', do you mean something like the input for the signrawtransaction command like

Code:
'010...000' '[{"txid":"3c...7ac","vout":0,"scriptPubKey":"a9...87","redeemScript":"52...ae"}]' '["5J...mw"]'

or simply a hash like:

Code:
12345abcd...12345

If so, how do I convert the partially signed transaction hash + unspent output array to a hash?

You see the bit in DeathAndTaxes's example where it says "hex"? That's a whole transaction, hex-encoded, only partly signed, which Alice can send to Bob so that Bob can provide the remaining signature and broadcast the result to the network. (It's not a hash of a transaction, aka txid, which is a different, much shorter thing).

You might like to try running bitcoind decoderawtransaction on that to see what I mean - that'll decode it for you and show you what's in it:

Code:
./bitcoind decoderawtransaction 0100000001aca7f3b45654c230e0886a57fb988c3044ef5e8f7f39726d305c61d5e818903c00000000fd15010048304502200187af928e9d155c4b1ac9c1c9118153239aba76774f775d7c1f9c3e106ff33c0221008822b0f658edec22274d0b6ae9de10ebf2da06b1bbdaaba4e50eb078f39e3d78014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353aeffffffff0140420f00000000001976a914ae56b4db13554d321c402db3961187aed1bbed5b88ac00000000
{
    "txid" : "b630b260ecba5b6fdefdaa0fd97f69d350189fc562411aca20b065f82892614e",
    "version" : 1,
    "locktime" : 0,
    "vin" : [
        {
            "txid" : "3c9018e8d5615c306d72397f8f5eef44308c98fb576a88e030c25456b4f3a7ac",
            "vout" : 0,
            "scriptSig" : {
                "asm" : "0 304502200187af928e9d155c4b1ac9c1c9118153239aba76774f775d7c1f9c3e106ff33c0221008822b0f658edec22274d0b6ae9de10ebf2da06b1bbdaaba4e50eb078f39e3d7801 52410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353ae",
                "hex" : "0048304502200187af928e9d155c4b1ac9c1c9118153239aba76774f775d7c1f9c3e106ff33c0221008822b0f658edec22274d0b6ae9de10ebf2da06b1bbdaaba4e50eb078f39e3d78014cc952410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353ae"
            },
            "sequence" : 4294967295
        }
    ],
    "vout" : [
        {
            "value" : 0.01000000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 ae56b4db13554d321c402db3961187aed1bbed5b OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a914ae56b4db13554d321c402db3961187aed1bbed5b88ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "1GtpSrGhRGY5kkrNz4RykoqRQoJuG2L6DS"
                ]
            }
        }
    ]
}

See the "txid" bit in there, which is "b630b260ecba5b6fdefdaa0fd97f69d350189fc562411aca20b065f82892614e"? That's what's meant by the transaction hash.
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!