-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How do you spend from multisig address in Python? #28
Comments
Hey @gustavklopp thanks for opening the issue and sorry for the problem. I've never tried to redeem funds send to a multisig address with the python library, but this library should support it. I'm not 100% sure, but I think that the error you're running into here is in building the transaction, which would happen on the call to
Does that make sense? Unfortunately, in order for us to help you debug this will require you sharing your addresses (not the private keys of course!). If you'd rather not do this over github, you can email support@blockcypher.com and reference this github issue. |
Thanks a lot for your help
|
Sorry for the trouble @gustavklopp. I think you actually need to send the pubkey array as the inputs' addresses when spending money from a multisig address...otherwise we won't be able to send the proper data to sign to unlock P2SH funds: http://dev.blockcypher.com/#multisig-transactions So in the code snippet above, I'd change inputs = [{'address':multisig_addr}] into: inputs = [{'address':pubkey_list}] After that, you might run into some trouble signing multiple signatures with different priv-pub-key pairs; just have to make sure the pubkeys and addrs you supply are in the right order for |
Thanks.
So apparently, the assertion check doesn't recognize a list, only address:
modified to :
Now when I use:
this results in:
|
Hi @gustavklopp, thanks for the info and sorry for all the trouble. We'll get this working! @acityinohio, why does this curl call work?
The docs seem to suggest that you have to pass an array of pubkeys as inputs and not the address. Since the API should know that this input is a p2sh address (which requires an array of pubkeys) it should be throwing an error here, no? If that's the case, this should be the curl call:
I've update the python SDK to accept this, if you pull the latest version (1.0.56) the following should work:
Next up we have to deal with signing. @gustavklopp , can you figure out how to do that from here? Relevant part of the docs here. Basically, you want to feed into
Does that make sense? |
Yes, it's working! Proof: https://live.blockcypher.com/btc-testnet/tx/4e98c0c54b6ae13f934fbe59342b362fd97c604cdbd6d04623f8cb512dfcda75/ :) I've used as you noted (example with one of the private key):
That's very great! Thanks again a lot |
Awesome! 👍 Glad to hear it @gustavklopp and @mflaxman . Re: the error on cURL, you're right @mflaxman; any time a P2SH address is used as an input we should throw an error. I'll take a look at the transaction builder code and see if I can patch it soon. (cc @matthieu ) |
Glad to hear it @gustavklopp! I'm a little surprised/confused though, that code seems to show you only signing with one private key. Don't you need to sign with 2 of the 3? Thanks @acityinohio for looking into the tx builder code. |
I've signed with two of the 3, one after another. I've put only one portion of the code for the example. Sorry for the confusion |
On second thought, @acityinohio , why is this a requirement? The end-user will later need those pubkeys for broadcast (and the private keys of course for signing), but at the time of generating the transaction there's no reason to require the pubkeys. Perhaps since they'll be needed at the next step it's best to just ensure they have them at the beginning? cc @matthieu |
Unfortunately because of the nature of P2SH addresses it is required for us to have pubkeys as inputs prior to generating data for the user to sign. Remember that when you use a prior P2SH address as an input, what you are actually pushing onto the Script stack is the full multisig script as an input in the transaction, and by its nature that includes the pubkeys. Correct me if I'm wrong but I'm pretty sure we won't be able to generate the right tosign data without having the pubkeys as inputs (instead of a P2SH address). Wish it wasn't so, because it really does make things more complicated. :-/ |
Gotcha, thanks! So is having the API throw an error on submitting a p2sh address (not pubkeys) still on your list? |
No prob, and yup! I was just discussing with @hbcheng the right place to put it in the code and will have a PR forthcoming; will definitely let you know when it's merged. |
Thanks! No rush, the python code isn't dependent on it. Just wanted to make it didn't fall through the cracks. |
So, I think I was slightly mistaken; apologies for the misinformation! We can't accept P2SH addresses without the corresponding script_type "multisig-n-of-m" field in the input (turns out we can in fact add the pubkeys later, prior to the |
Thanks for the update @acityinohio. Hmm, based on your earlier comments I wrote the If I'm understanding you correctly, you are saying:
Can you please confirm? I don't know the p2sh protocol that well, but this doesn't sound correct. In practical terms, imagine the scenario where people A, B, and C provide their own keys to create a 2 of 3 p2sh address. Person A loses their keys, so when they want to spend funds controlled by that p2sh address, person B & C go to sign a transaction. If and 2 are correct, you are saying that unless someone kept a copy of person A's pubkey the funds would not be recoverable. In a 2-of-3 multisig, that's quite confusing. |
Best practice is definitely to use all pubkeys as address inputs for On your scenario, that's (sadly) actually correct; if you lose A's pubkey, the funds are, in fact, undependable. :( That's because the ScriptSig (aka the unlocking script on a transaction input) contains the full Redeem Script, which includes all three pubkeys, in this form:
P2SH redeem script described here: https://bitcoin.org/en/developer-guide#term-redeem-script My original confusion was that I believed that you needed the Redeem Script to generate the data to sign, but I forgot that you actually remove all ScriptSigs before signing (which includes the Redeem Script). Sorry for the mix-up, but I actually think your simple_spend_p2sh follows the right course of action; you'll need all the pubkeys anyway when you broadcast. |
Thanks @acityinohio , that was a perfect answer! |
hey @acityinohio , it seems I am having to supply an API token to be able to use
(or else it fails complaining |
It requires an API token because Blockcypher is fetching all the UTXOs Does that make sense? On Friday, June 10, 2016, Kumar Ghosh notifications@github.com wrote:
Sent from my iPhone |
yes absolutely mate, sorry that was a bit of a dumb question :s |
'sallgood @kumrzz! no such thing, always good to have opportunities for clarification. 👍 |
I'm getting an assertion error:
|
How to spend a particular UTXOs for a Multisig address? If I give the previous hash and output index as input it doesn't work. |
I've generated a multisig address thanks to
generate_multisig_address()
.Now I don't get it how to spend it using
create_unsigned_tx
,make_tx_signatures
thenbroadcast_signed_transaction
.But it's not working:
The text was updated successfully, but these errors were encountered: