Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: monsterer on September 03, 2013, 03:25:44 PM



Title: Multi-signature address never receives bitcoins
Post by: monsterer on September 03, 2013, 03:25:44 PM
Hi guys,

So I'm experimenting with multi-signature addresses on testnet.

I've created myself a two-of-two multi-signature address for an account named "1":

Code:
bitcoind -testnet addmultisigaddress 2 ["""04E062CB0F8E305AE452C191C39D74B3E30C9E3DDDB63F8121FC14F4134825AAAD0169F1E3762CFA3BD840F1C36BD1D60F0407FD50D79B2FBA6B407CF0A6498198""","""04B735503ECF6D7D73F58A64E2EAB7DA78EB78B1CDF5F4BB8A3FFA8941EE725492E9A86AB3D3374B0729E1A74EF93A9DFCDA1527DEBBD1CB7B1ACC08166C8E1E6B"""] "1"

2NBSBcf2KfjPEEqVusmrWdmUeNHRiUTS3Li

Confirmed that the address is associated with the account:

Code:
C:\Program Files\Bitcoin\daemon>bitcoind -testnet getaddressesbyaccount 1
[
    "2NBSBcf2KfjPEEqVusmrWdmUeNHRiUTS3Li"
]

Sent a transaction to this address from another account:

Code:
C:\Program Files\Bitcoin\daemon>bitcoind -testnet sendfrom "" 2NBSBcf2KfjPEEqVusmrWdmUeNHRiUTS3Li 3.14159

9254bd323e58e58271801a54af1192bf0a5a6574c8fa032e893f8d22147c1a26

Confirmed that the transaction exists:

Code:
C:\Program Files\Bitcoin\daemon>bitcoind -testnet gettransaction 9254bd323e58e58271801a54af1192bf0a5a6574c8fa032e893f8d22147c1a26
{
    "amount" : -3.14159000,
    "fee" : 0.00000000,
    "confirmations" : 1,
    "blockhash" : "00000000008d949940f0860593d2eed0886ab07cb324b6c894753825a1535
690",
    "blockindex" : 5,
    "blocktime" : 1378220260,
    "txid" : "9254bd323e58e58271801a54af1192bf0a5a6574c8fa032e893f8d22147c1a26",

    "time" : 1378219996,
    "timereceived" : 1378219996,
    "details" : [
        {
            "account" : "",
            "address" : "2NBSBcf2KfjPEEqVusmrWdmUeNHRiUTS3Li",
            "category" : "send",
            "amount" : -3.14159000,
            "fee" : 0.00000000
        }
    ]
}

But the transaction just never arrives (yet it has been deducted from my main balance):

Code:
C:\Program Files\Bitcoin\daemon>bitcoind -testnet listaccounts 0
{
    "" : 6.85841000,
    "1" : 0.00000000,
}

Any idea what's going on here?


Cheers, Paul.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 04, 2013, 09:32:15 AM
getreceivedbyaddress returns 0 as well.

Code:
C:\Program Files\Bitcoin\daemon>bitcoind -testnet getreceivedbyaddress 2NBSBcf2KfjPEEqVusmrWdmUeNHRiUTS3Li

0.00000000

Anyone?


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 04, 2013, 04:30:31 PM
As far as I can tell, sending to a multi-sig address will only show up in your balance or at an address if *all* private keys for the multi-sig are in your wallet. This negates the whole point of multi-sig transactions.

I cannot work out how you're supposed to tell if a multi-sig address where *less than all* private keys are in your wallet has received any bitcoins, or what the balance is. It could be there is no way to tell (making this functionality extremely limited) or it could be that bitcoins simply never arrive at all.

Either way this is such a shame as multi-sig would be a nice secure way to store your bitcoins, but with this currently functionality, it's pretty much useless. :|


Title: Re: Multi-signature address never receives bitcoins
Post by: gmaxwell on September 04, 2013, 05:06:45 PM
As far as I can tell, sending to a multi-sig address will only show up in your balance or at an address if *all* private keys for the multi-sig are in your wallet. This negates the whole point of multi-sig transactions.

Correct. It doesn't make sense to show as part of your balance coins which you have no idea if you can spend them or not.

They can still be spent, manually.

Quote
I cannot work out how you're supposed to tell if a multi-sig address where *less than all* private keys are in your wallet has received any bitcoins, or what the balance is. It could be there is no way to tell (making this functionality extremely limited) or it could be that bitcoins simply never arrive at all.

Either way this is such a shame as multi-sig would be a nice secure way to store your bitcoins, but with this currently functionality, it's pretty much useless. :|
The idea is that for now you use them manually. In the future yet undeveloped functionality would replace the private key for the other siginers in your wallet with some instructions that tells the client how it can go about getting the required signature(s).

Such signers have to exist, first, before you can worry about figuring out how to interface them... thus the start with manual use.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 04, 2013, 08:44:25 PM
Correct. It doesn't make sense to show as part of your balance coins which you have no idea if you can spend them or not.

They can still be spent, manually.

Well, without being able to see the balance of an multi-sig account you completely rule out several use cases which could help secure bitcoins for merchants who are in charge of bitcoins on behalf of other users. No one can send bitcoins for you to secure if you can't tell when they've arrived.

To me it would make perfect sense to have a visible balance on a multi-sig address and not be able to spend it (without being multi-signed). That's the whole point of them in the first place.

Quote
The idea is that for now you use them manually.

But how do you even know when they've arrived at an address in order to spend them?

Cheers, Paul.


Title: Re: Multi-signature address never receives bitcoins
Post by: jgarzik on September 04, 2013, 10:27:28 PM
The tools for multisig are admittedly poor, at the moment.

Multi-sig introduces an interesting concept:  bitcoins that you might be able to spend.  Therefore, your balance only shows bitcoins when you control 100% of the private keys.

Right now, you need to take a few extra steps.  Some tools (https://bitcointalk.org/index.php?topic=249205.0) outside bitcoind exist to help with multisig, but in general, additional work is needed in this area.



Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 05, 2013, 07:13:46 AM
The tools for multisig are admittedly poor, at the moment.

Multi-sig introduces an interesting concept:  bitcoins that you might be able to spend.  Therefore, your balance only shows bitcoins when you control 100% of the private keys.

Right now, you need to take a few extra steps.  Some tools (https://bitcointalk.org/index.php?topic=249205.0) outside bitcoind exist to help with multisig, but in general, additional work is needed in this area.

Even that tool you posted still suffers from the same problem: *no one can tell that bitcoins were sent to them on a multi-sig address*.

In fact, they write:

Code:
6) Send bitcoins to the multisig address.

$ ./bitcoind -testnet sendtoaddress 2MsfxrcnDNF1kHJRxXT11TnAgDvVHkEvzSd 1.5
ad39b5d53230af4784fb46720e5bc474f16a97a2fc6e85eed5fd3ef423e97885

7) Time passes.  Now, at least two parties are happy, and want
   to spend the bitcoins.

Time passes. How much time? Are they sure the coins actually arrived?

IMO, all this could be solved simply by allowing the balance to include multi-sig addresses.

Cheers, Paul.


Title: Re: Multi-signature address never receives bitcoins
Post by: dserrano5 on September 05, 2013, 12:39:38 PM
In fact, they write:

Code:
6) Send bitcoins to the multisig address.

$ ./bitcoind -testnet sendtoaddress 2MsfxrcnDNF1kHJRxXT11TnAgDvVHkEvzSd 1.5
ad39b5d53230af4784fb46720e5bc474f16a97a2fc6e85eed5fd3ef423e97885

7) Time passes.  Now, at least two parties are happy, and want
   to spend the bitcoins.

Time passes. How much time? Are they sure the coins actually arrived?

You can check whether the transaction was included in a block.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 05, 2013, 01:55:56 PM
In fact, they write:

Code:
6) Send bitcoins to the multisig address.

$ ./bitcoind -testnet sendtoaddress 2MsfxrcnDNF1kHJRxXT11TnAgDvVHkEvzSd 1.5
ad39b5d53230af4784fb46720e5bc474f16a97a2fc6e85eed5fd3ef423e97885

7) Time passes.  Now, at least two parties are happy, and want
   to spend the bitcoins.

Time passes. How much time? Are they sure the coins actually arrived?

You can check whether the transaction was included in a block.

You can only do that if you have the transaction ID. If someone simply sends you some bitcoins without the transaction ID, you're buggered. :)


Title: Re: Multi-signature address never receives bitcoins
Post by: kjj on September 05, 2013, 02:18:12 PM
You can check whether the transaction was included in a block.

You can only do that if you have the transaction ID. If someone simply sends you some bitcoins without the transaction ID, you're buggered. :)

???

Multisig addresses are fully visible in blocks, just like regular addresses.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 05, 2013, 04:34:42 PM
???

Multisig addresses are fully visible in blocks, just like regular addresses.

I was talking about using the bitcoind client. Are you suggesting that bitcoin users should manually parse the blockchain to determine if their funds arrived?


Title: Re: Multi-signature address never receives bitcoins
Post by: jgarzik on September 05, 2013, 04:52:29 PM
???

Multisig addresses are fully visible in blocks, just like regular addresses.

I was talking about using the bitcoind client. Are you suggesting that bitcoin users should manually parse the blockchain to determine if their funds arrived?

This is a fair criticism, and no, average users cannot be expected to parse the block chain.

Average users can, however, watch a specific address on blockchain/block explorer.



Title: Re: Multi-signature address never receives bitcoins
Post by: kjj on September 05, 2013, 04:58:40 PM
???

Multisig addresses are fully visible in blocks, just like regular addresses.

I was talking about using the bitcoind client. Are you suggesting that bitcoin users should manually parse the blockchain to determine if their funds arrived?

Multisig addresses are not useful as-is.  External tools of some sort are required.

The reference implementation could be improved to be sure, but it will never be able to be the whole infrastructure for multisig.

As jgarzik notes, there are tools available already that are suitable for infrequent multisig usage.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 05, 2013, 05:00:22 PM
This is a fair criticism, and no, average users cannot be expected to parse the block chain.

Average users can, however, watch a specific address on blockchain/block explorer.

This is true, but the primary job of bitcoind is to parse the blockchain, so having to use another parser seems... wasteful. :)


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 05, 2013, 05:02:20 PM
Multisig addresses are not useful as-is.  External tools of some sort are required.

The reference implementation could be improved to be sure, but it will never be able to be the whole infrastructure for multisig.

As jgarzik notes, there are tools available already that are suitable for infrequent multisig usage.

The thing is, if bitcoind would simply include multi-sig transactions in the balance of each account, this entire problem goes away doesn't it?


Title: Re: Multi-signature address never receives bitcoins
Post by: kjj on September 05, 2013, 05:13:56 PM
Multisig addresses are not useful as-is.  External tools of some sort are required.

The reference implementation could be improved to be sure, but it will never be able to be the whole infrastructure for multisig.

As jgarzik notes, there are tools available already that are suitable for infrequent multisig usage.

The thing is, if bitcoind would simply include multi-sig transactions in the balance of each account, this entire problem goes away doesn't it?

A tiny little part of the problem goes away, sure.  But not the whole thing.

What would be needed is a general means to monitor specific scriptPubKeys.  There has been a lot of discussion on that topic over the last few months.  Check the mailing list and IRC logs to see why it isn't a simple change to make.


Title: Re: Multi-signature address never receives bitcoins
Post by: ninjabanker on September 07, 2013, 01:51:44 AM
Multisig addresses are not useful as-is.  External tools of some sort are required.

The reference implementation could be improved to be sure, but it will never be able to be the whole infrastructure for multisig.
Here's is an outline of how one such external tool might work:

http://praesto.airdns.org:63853/issues/5


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 16, 2013, 08:27:17 AM
Is it trivial for me to modify my build of bitcoind to consider multi-sig addresses in the balance calculations?

So, listsinceblock, gettransactions, listaccounts (and the rest of the commands which return transaction info) commands would consider multi-sig addresses?


Title: Re: Multi-signature address never receives bitcoins
Post by: jgarzik on September 16, 2013, 02:15:10 PM
Is it trivial for me to modify my build of bitcoind to consider multi-sig addresses in the balance calculations?

If, and only if, you control all keys involved in a multisig transaction.

Otherwise, such a transaction may be considered "partially controlled" and not really part of your "fully controlled" balance.  bitcoind cannot prove that you can spend a multisig.



Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 17, 2013, 07:50:05 AM
If, and only if, you control all keys involved in a multisig transaction.

Otherwise, such a transaction may be considered "partially controlled" and not really part of your "fully controlled" balance.  bitcoind cannot prove that you can spend a multisig.

But this is already the case - if I have both private keys in the wallet, then the balance is displayed by bitcoind. But I'm asking whether a trivial code change would allow me to work with partially controlled multi-sig addresses?


Title: Re: Multi-signature address never receives bitcoins
Post by: jgarzik on September 17, 2013, 01:24:27 PM

But this is already the case - if I have both private keys in the wallet, then the balance is displayed by bitcoind. But I'm asking whether a trivial code change would allow me to work with partially controlled multi-sig addresses?

No -- because it's not trivial.



Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on September 17, 2013, 07:12:41 PM

But this is already the case - if I have both private keys in the wallet, then the balance is displayed by bitcoind. But I'm asking whether a trivial code change would allow me to work with partially controlled multi-sig addresses?

No -- because it's not trivial.

Thanks, I feared as much from browsing the code.


Title: Re: Multi-signature address never receives bitcoins
Post by: Peter Todd on September 17, 2013, 07:31:45 PM
Is it trivial for me to modify my build of bitcoind to consider multi-sig addresses in the balance calculations?

If, and only if, you control all keys involved in a multisig transaction.

Otherwise, such a transaction may be considered "partially controlled" and not really part of your "fully controlled" balance.  bitcoind cannot prove that you can spend a multisig.

Keep in mind Bitcoin actually goes a bit further than that: bitcoind will only add a multi-sig transaction output to your wallet if you have all the keys, instead of only enough keys.

I ran into this with my timestamper, which would create 1-of-2 multisig outputs where the other key was actually invalid and was only there to timestamp data. The code that actually implements this is in script.cpp:


   case TX_MULTISIG:
    {
        // Only consider transactions "mine" if we own ALL the
        // keys involved. multi-signature transactions that are
        // partially owned (somebody else has a key that can spend
        // them) enable spend-out-from-under-you attacks, especially
        // in shared-wallet situations.
        vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
        return HaveKeys(keys, keystore) == keys.size();
    }


As a quick hack I changed changed the last line (IIRC) to only require that I had enough of the keys to spend the txout. You can do that too if you just want to test some multisig-using code out, just remember that you'll need to do a fair bit more than that to make it robust against attacks. FWIW my timestamper never ran into the problems mentioned above, but someone certainly could have caused it some trouble if they tried.

Remember too that this only applies to bare CHECKMULTISIG txouts; P2SH is different. For a P2SH-using txout the scriptPubKey is just a hash of the real script, so bitcoin has no idea what the actual scriptPubKey is, and hence whether or not you have the keys required to spend the txout.

However for real-world applications this is never a problem because you know the scriptPubKey - they're funds you know you have access too. I wrote a patch that adds the RPC command "addredeemscript" to bitcoind to make it possible to add a P2SH redeemscript to your wallet. It's not merged yet (and may never be) but if you are working on the right application it might be useful to you: http://github.com/petertodd/bitcoin/ (github is down right now, but the branch name is "rpc-addredeemscript" or something)

Again, remember that you may mess up your wallet experimenting with the above hacks, so don't use it on anything other than testnet for now.

Also, if you're working on some code, use P2SH rather than bare CHECKMULTISIG scriptPubKeys - it's possible the later will be made non-standard in the future to discourage people from putting data in the UTXO set.


Title: Re: Multi-signature address never receives bitcoins
Post by: JaSK on October 17, 2013, 01:37:13 PM
I just ran into the same problem while working on the Moneychanger project for open-transactions.

A solution (http://bitcoin.stackexchange.com/questions/6085/chronological-list-of-transaction-ids) is to use getrawtransaction <txid> to check if requested money was sent to the p2sh address in the first place,
then getrawmempool to see if it has any confirmations yet,
then getblockcount --> getblockhash(count) --> getblock(hash) --> getblock(block->previous) -->... to iterate through the blockchain to figure out how many confirmations it has.

If you don't know the txid you could scan the blockchain for new txIDs and use getrawtransaction on each of them to figure out if any outputs were sent to the multi-sig address.

Haven't implemented it yet so I'm not sure if it will work like this but so far it looks like it could imho.

This all seems very hackish and error-prone to me so I hope we'll soon get proper bitcoin API support for that kind of transactions.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on October 29, 2013, 04:23:08 PM
If you don't know the txid you could scan the blockchain for new txIDs and use getrawtransaction on each of them to figure out if any outputs were sent to the multi-sig address.

Haven't implemented it yet so I'm not sure if it will work like this but so far it looks like it could imho.

Ok, so it turns out that you are right - it *is* possible to tell if someone has sent coins to a multi-sig address. This is the process:

Code:
* Start from last processed block hash
* Call getblock
* Iterate through all transaction ids (which really are *all* txids, and not just those in your wallet - this is the first part of the key to the process)
{
   * call getrawtransaction on each txid (which also lets you inspect non-wallet transactions, 2nd part of the key to the process)
   * Iterate through all vouts
   {
      * check each address in the scriptPubKey list to see if it matches your multi-sig address
      * if it does, you've found a deposit! You can determine the number of confirmations from the call you made to getrawtransaction
   }
}
* Goto next block hash

This is huge, because it means you can give out multi-sig addresses to your users and actually be able to credit them when the coins arrive!

Cheers, Paul.


Title: Re: Multi-signature address never receives bitcoins
Post by: jgarzik on October 29, 2013, 09:05:03 PM
This is huge, because it means you can give out multi-sig addresses to your users and actually be able to credit them when the coins arrive!

That's standard fare, with pay-to-script-hash (P2SH).  Multisig P2SH addresses are easy.

"addmultisig" RPC call handles this, for bitcoind / Bitcoin-QT.



Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on October 29, 2013, 09:28:10 PM
That's standard fare, with pay-to-script-hash (P2SH).  Multisig P2SH addresses are easy.

"addmultisig" RPC call handles this, for bitcoind / Bitcoin-QT.

No its not standard fare. As the title of this thread indicates, the standard mechanisms in bitcoind (listsinceblock, listtransactions, getbalance etc etc) do not report any information about coins at multi-sig addresses unless the wallet contains all the private keys.

This method I've just described is AFAIK, the *only* way to tell that coins have arrived on an address, making it very far from standard fair, given the amount of work it is.


Title: Re: Multi-signature address never receives bitcoins
Post by: jgarzik on October 29, 2013, 09:47:15 PM
Just visit any block explorer, to see the balance at a particular address.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on October 29, 2013, 10:05:12 PM
Just visit any block explorer, to see the balance at a particular address.


Fantastic advice, thanks for taking the time.


Title: Re: Multi-signature address never receives bitcoins
Post by: Bitalo_Maciej on October 30, 2013, 01:27:09 PM
Just visit any block explorer, to see the balance at a particular address.


Fantastic advice, thanks for taking the time.

@monsterer: Message me if you'd like to receive an invite code for Bitalo (http://beta.bitalo.com), which implements multi-signature addresses for its wallets and creates/signs transactions on client-side, in Javascript. On the server side it does exactly the process that you described above - iterating over transactions in blocks and crediting users wallet balances.
It works quite well at the moment, though we're still testing it to find out any outstanding bugs in the implementation.

I'm quite familiar with how this all works so if you have any more technical questions, feel free to ask, I'm glad to help :).

Edit: Blockexplorers are tricky, because they don't handle P2SH addresses well yet. For example:

http://blockexplorer.com/testnet/tx/67a05915c2a90e9743f04fb5e76f954204002401150ab34ebaed6f721056ae23
http://testnet.btclook.com/txn/67a05915c2a90e9743f04fb5e76f954204002401150ab34ebaed6f721056ae23

This is a valid transaction from P2SH address to another. Blockexplorer lists the inputs and outputs as "Strange", and BTCLook shows "???", even though they are perfectly legal.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on October 31, 2013, 10:23:29 AM
I'm quite familiar with how this all works so if you have any more technical questions, feel free to ask, I'm glad to help :).

Thanks for the offer, I'll take you up on how to create and sign a multi-sig transaction.

I currently have:

* sent funds to a 2/2 multi-sig address
* created a raw transaction spending the output of the above
* signed with one private key (which is in wallet, but I passed it to the function anyway)
* signed with the other private key (not in wallet)

The process does not fail, but the resulting signed transaction has complete set to 'false', which isn't right.

edit: looking at the raw transaction after creating it, signing it once, signing it twice, the hex doesn't change at all, which must mean something very wrong is happening?

Hope you can help!

Cheers, Paul.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on October 31, 2013, 12:31:02 PM
Ok, managed to get something working but only in the case of using two separate wallets with one private key located in each. In addition both wallets need to have the multi-sig address you're using added to them, despite them already containing one private key each.

Is there a way to have a wallet correctly sign a multi-sig transaction without explicitly adding the multi-sig address to it?


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on October 31, 2013, 01:14:00 PM
Ok, managed to get something working but only in the case of using two separate wallets with one private key located in each. In addition both wallets need to have the multi-sig address you're using added to them, despite them already containing one private key each.

Is there a way to have a wallet correctly sign a multi-sig transaction without explicitly adding the multi-sig address to it?

Ok, to answer my own question, *yes* there is a way, and here is how:

* use createmultisig 2 [pubKeyA, pubKeyB] to generate a redeemScript and an address
* createrawtransaction as usual
* signrawtransaction using private key A, and also you must pass, for each transaction output:
{
   txid - this is the txid of the transaction you just created, NOT the funding transaction
   vout - index of transaction output
   scriptPubKey - this is from the output (indexed vout) for the transaction you just created
   redeemScript - this is from createmultisig
}
* transmit the hex transaction to the other party along with the redeemScript
* have the other party perform the same process for signing on their end
* transaction is signed correctly.

I was unable to determine if the other party could extract the redeemScript from the transaction alone which would save some messing around.

note: something which threw me was the offical documentation for signrawtransaction, which omits to mention redeemScript. This could do with fixing

Cheers, Paul.


Title: Re: Multi-signature address never receives bitcoins
Post by: dserrano5 on October 31, 2013, 01:23:59 PM
You may find this gist by Gavin (https://gist.github.com/gavinandresen/3966071) useful.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on October 31, 2013, 02:47:05 PM
You may find this gist by Gavin (https://gist.github.com/gavinandresen/3966071) useful.

I did, but it also threw me off, because its out of date.

In that example, gavin passes scriptPubKey and redeemScript to createrawtransaction. This is no longer correct. You must pass these to signrawtransaction now.


Title: Re: Multi-signature address never receives bitcoins
Post by: kjj on October 31, 2013, 03:36:12 PM
The gist is incredibly useful.  Be sure to copy out the commands and reformat them so you can see what's really going on.  The long lines can be hard to follow.  If you unpack the commands in the gist, you can see that the redemption info is needed both to create and to sign.

The transaction goes through several stages when redeeming multisig.

First, a partial transaction is created that specifies which transaction is to be redeemed, and lists the outputs.

Second, the information needed to actually redeem the P2SH input are added to the transaction.  You can see this as an explicit step if you call signrawtransaction with the redemption info, but without any private keys.

Next, one or more signatures are added.  This can be one step, or many.

Here is example PHP code.  This is not a utility suitable for production usage, it is just a demonstration of how things work, but you can use it for one-off redemption, or modify it to accept the payment info.

Code: (redeemmultisig.php)
<?php

// this file sets up the $rpc object used for RPC calls later
require_once("local_connection_info.php");

// which transaction output are you redeeming?
$redeemtxid="";
$redeemvout=0;

// what is the redeemscript that hashes to that address?
$redeemscript="";

// It may be possible to derive this from the txout info, but for now you have to enter it
$redeempubkey="";

// If you provide enough keys to complete the transaction, it will send automatically
// otherwise, it will provide the partially signed transaction
// Note that this script isn't capable of continuing a partially signed transaction
// (it should be easy to add.)
$privkeys=array(
     
"",
     
"",
);

// 3 modes
// Pay to self - ask bitcoind for a new address, send everything to it (minus the fee)
// Pay someone else, change back to me - ask bitcoind for a new address, use it for change (put "SELF" in as $changeaddr, address in as $payaddr)
// Pay someone else, change to someone else - specify addresses for both $payaddr and $changeaddr
$payaddr="SELF";
$fee=0.00;
$payamount=0;   // ignored if paying to self
$changeaddr=""// ignored if paying to self

// Thus ends the configuration section.  All below is work


// Fetch the info we need from the old transaction
$txhex=$rpc->getrawtransaction($redeemtxid);
$txbody=$rpc->decoderawtransaction($txhex);

// configure the outputs
// change amount is always calculated automatically
if("SELF"==$payaddr){
 
$paddr=$rpc->getnewaddress();
 
$pays=array($paddr=>$txbody['vout'][$redeemvout]['value']-$fee);
}elseif(
"SELF"==$changeaddr){
 
$caddr=$rpc->getnewaddress();
 
$camt=$txbody['vout'][$redeemvout]['value']-$payamount-$fee;;
 
$pays=array($payaddr=>$payamount,$caddr=>$camt);
}else{
 
$camt=$txbody['vout'][$redeemvout]['value']-$payamount-$fee;
 
$pays=array($payaddr=>$payamount,$changeaddr=>$camt);
}

// this array holds the info needed to redeem the transaction
$redeemblock=array(array("txid"=>$redeemtxid,"vout"=>$redeemvout,"scriptPubKey"=>$redeempubkey,"redeemScript"=>$redeemscript));

// now we create the transaction, complete it, and sign it
$raw=$rpc->createrawtransaction($redeemblock,$pays);
$signed=$rpc->signrawtransaction($raw,$redeemblock,$privkeys);

// This would be a good place to inspect the output.  Uncomment these to verify function.
//$decoded=$rpc->decoderawtransaction($signed['hex']);
//print_r($decoded)
//die();

if(1==$signed['complete']){
 
$outtxid=$rpc->sendrawtransaction($signed['hex']);
 echo 
$outtxid."\n";
}else{
 echo 
$signed['hex']."\n";
}

?>



Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on October 31, 2013, 04:05:14 PM
The gist is incredibly useful.  Be sure to copy out the commands and reformat them so you can see what's really going on.  The long lines can be hard to follow.  If you unpack the commands in the gist, you can see that the redemption info is needed both to create and to sign.

The transaction goes through several stages when redeeming multisig.

First, a partial transaction is created that specifies which transaction is to be redeemed, and lists the outputs.

Second, the information needed to actually redeem the P2SH input are added to the transaction.  You can see this as an explicit step if you call signrawtransaction with the redemption info, but without any private keys.

Next, one or more signatures are added.  This can be one step, or many.

Here is example PHP code.  This is not a utility suitable for production usage, it is just a demonstration of how things work, but you can use it for one-off redemption, or modify it to accept the payment info.

Code: (redeemmultisig.php)
<?php

// this file sets up the $rpc object used for RPC calls later
require_once("local_connection_info.php");

// which transaction output are you redeeming?
$redeemtxid="";
$redeemvout=0;

// what is the redeemscript that hashes to that address?
$redeemscript="";

// It may be possible to derive this from the txout info, but for now you have to enter it
$redeempubkey="";

// If you provide enough keys to complete the transaction, it will send automatically
// otherwise, it will provide the partially signed transaction
// Note that this script isn't capable of continuing a partially signed transaction
// (it should be easy to add.)
$privkeys=array(
     
"",
     
"",
);

// 3 modes
// Pay to self - ask bitcoind for a new address, send everything to it (minus the fee)
// Pay someone else, change back to me - ask bitcoind for a new address, use it for change (put "SELF" in as $changeaddr, address in as $payaddr)
// Pay someone else, change to someone else - specify addresses for both $payaddr and $changeaddr
$payaddr="SELF";
$fee=0.00;
$payamount=0;   // ignored if paying to self
$changeaddr=""// ignored if paying to self

// Thus ends the configuration section.  All below is work


// Fetch the info we need from the old transaction
$txhex=$rpc->getrawtransaction($redeemtxid);
$txbody=$rpc->decoderawtransaction($txhex);

// configure the outputs
// change amount is always calculated automatically
if("SELF"==$payaddr){
 
$paddr=$rpc->getnewaddress();
 
$pays=array($paddr=>$txbody['vout'][$redeemvout]['value']-$fee);
}elseif(
"SELF"==$changeaddr){
 
$caddr=$rpc->getnewaddress();
 
$camt=$txbody['vout'][$redeemvout]['value']-$payamount-$fee;;
 
$pays=array($payaddr=>$payamount,$caddr=>$camt);
}else{
 
$camt=$txbody['vout'][$redeemvout]['value']-$payamount-$fee;
 
$pays=array($payaddr=>$payamount,$changeaddr=>$camt);
}

// this array holds the info needed to redeem the transaction
$redeemblock=array(array("txid"=>$redeemtxid,"vout"=>$redeemvout,"scriptPubKey"=>$redeempubkey,"redeemScript"=>$redeemscript));

// now we create the transaction, complete it, and sign it
$raw=$rpc->createrawtransaction($redeemblock,$pays);
$signed=$rpc->signrawtransaction($raw,$redeemblock,$privkeys);

// This would be a good place to inspect the output.  Uncomment these to verify function.
//$decoded=$rpc->decoderawtransaction($signed['hex']);
//print_r($decoded)
//die();

if(1==$signed['complete']){
 
$outtxid=$rpc->sendrawtransaction($signed['hex']);
 echo 
$outtxid."\n";
}else{
 echo 
$signed['hex']."\n";
}

?>


If you remove scriptPubKey and redeemScript from what you pass into createrawtransaction() it will work just as well. That function does not accept those parameters. Only signrawtransaction() needs them.


Title: Re: Multi-signature address never receives bitcoins
Post by: Bitalo_Maciej on October 31, 2013, 07:25:23 PM
You can recreate the redeemScript using createmultisig command at any time, if you use the same public keys. This will result in same P2SH address & redeemScript pair. Note that the order of keys DOES matter here, if you mix it up, it will result in a different address/redeemScript pair.

You can also extract the redeemScript from the transaction hex data. It's the last parameter of the input you are signing. This could be tricky to implement correctly though, so it's definitely better to store and send the redeemScript along with the transaction.

In the end, did you manage to get "complete": true with your signed transaction? If you get false and the hex data doesn't change, it usually means that the private key was invalid, so bitcoind didn't sign anything.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on November 05, 2013, 11:54:30 AM
You can recreate the redeemScript using createmultisig command at any time, if you use the same public keys. This will result in same P2SH address & redeemScript pair. Note that the order of keys DOES matter here, if you mix it up, it will result in a different address/redeemScript pair.

You can also extract the redeemScript from the transaction hex data. It's the last parameter of the input you are signing. This could be tricky to implement correctly though, so it's definitely better to store and send the redeemScript along with the transaction.

In the end, did you manage to get "complete": true with your signed transaction? If you get false and the hex data doesn't change, it usually means that the private key was invalid, so bitcoind didn't sign anything.

Hi,

Thanks for the advice - I guess that transmitting redeemScript with the transaction doesn't expose any potential vulnerability?

As to your question, yes I did finally get complete=true :)

Cheers, Paul.


Title: Re: Multi-signature address never receives bitcoins
Post by: Bitalo_Maciej on November 05, 2013, 12:18:18 PM
I guess that transmitting redeemScript with the transaction doesn't expose any potential vulnerability?

No, it doesn't, because as I said, it gets transmitted in the transaction's hex data anyway.

Congrats on finally succeeding in signing a multisig transaction. I know how happy I was the first time I received "complete: true" :).


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on November 15, 2013, 10:40:12 AM
I guess that transmitting redeemScript with the transaction doesn't expose any potential vulnerability?

No, it doesn't, because as I said, it gets transmitted in the transaction's hex data anyway.

Congrats on finally succeeding in signing a multisig transaction. I know how happy I was the first time I received "complete: true" :).

Quick follow up question - how do you go about collecting unspent outputs from multi-sig addresses to use in future transactions?


Title: Re: Multi-signature address never receives bitcoins
Post by: Bitalo_Maciej on November 15, 2013, 01:38:00 PM
Didn't you already found out how to do that earlier?

https://bitcointalk.org/index.php?topic=287063.msg3435441#msg3435441

In any case, we store unspent outputs for every address in a database, along with information needed to spend it: txid, vout, value. For this we monitor the blockchain continuously add check for transactions involving addresses that we care about.


Title: Re: Multi-signature address never receives bitcoins
Post by: monsterer on November 17, 2013, 11:08:23 AM
Didn't you already found out how to do that earlier?

https://bitcointalk.org/index.php?topic=287063.msg3435441#msg3435441

In any case, we store unspent outputs for every address in a database, along with information needed to spend it: txid, vout, value. For this we monitor the blockchain continuously add check for transactions involving addresses that we care about.

I just wanted to double check what options I had, but I see that incrementally storing them and then revalidating is pretty much the only choice, bar a blockchain rescan at each withdrawal :)