GithubHelp home page GithubHelp logo

Comments (24)

mflaxman avatar mflaxman commented on June 25, 2024

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 create_unsinged_tx. You can confirm this by making the following CURL call without even needing to use the python library at all:

$ curl -d '{"inputs":[{"addresses": ["multisig_addr_goes_here"]}],"outputs":[{"addresses": ["dest_addr_goes_here"], "value": 200000000}]}' https://api.blockcypher.com/v1/btc/test3/txs/new?includeToSign=true

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 [email protected] and reference this github issue.

from blockcypher-python.

gustavklopp avatar gustavklopp commented on June 25, 2024

Thanks a lot for your help
curl gives me exactly the same result in fact: http://pastebin.com/VeH8EQdX
Here's the script. (one of the private key is included... but since it's multisig...)

dest_addr = "mgMZ3UdQsEmJ1ebjRV9ibTn1DFCxgmMo7a"

priv1 = "9c46389dde9e820294b68defd44e01da12cfe1374324cf27c198e4822e7d9d1e"
pub1 = "0471b0e83960b9a8ad980400fc7ee85e9739009f0ee08ef033784bdcefe7f38c64e9ba2b9d842089486735556e0b1940304db510ad521865bb5b028dee229c1dbd"
addr1 = "mySFV5esqFZqz8maEVjEodxwc9xyhXMmmY"

priv2 = XXX
pub2 = '04a3cc3225df2ef6ca72e960c5cab0059731301d5efe61e7ffa1c4cac3a8e4994adcb27f01a282b7747d96ffdad324e774087c4a35197e99016bca62541af26eab'
addr2 = 'mouKAz9iAgMJzZjiiw4bZ4rxkJapkTXVDZ'

priv3 = XXX
pub3 = '04db43666cf4206e7848aaaf551e2ea6af2488b23046c155f1456d0dd175c782eef61acc42ededcd45a37012c7e096125e356c839e9c0a5f9c75d48aeddcad6712'
addr3 = 'mkmCeTJCLuhQw37xGCW7gFSSh3z4wXxGQ1'

pubkey_list = [pub1, pub2, pub3]
multisig = generate_multisig_address(pubkey_list, coin_symbol='btc-testnet')
# so we got:
multisig_addr = '2NEMZM6bLwdT18sKSrnfXcdcdGfqgccc9Qj'

from blockcypher import create_unsigned_tx, make_tx_signatures, broadcast_signed_transaction

inputs = [{'address':multisig_addr}]
outputs = [{'address': dest_addr, 'value':200000 }]

unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs, coin_symbol='btc-testnet')
# pprint(unsigned_tx)

privkey_list = [priv1]
pubkey_list = [pub1]

tx_signatures = make_tx_signatures(txs_to_sign=unsigned_tx['tosign'], privkey_list=privkey_list, pubkey_list=pubkey_list)

r = broadcast_signed_transaction(unsigned_tx, tx_signatures, pubkey_list, coin_symbol='btc-testnet')
print(r)

from blockcypher-python.

acityinohio avatar acityinohio commented on June 25, 2024

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 make_tx_signatures.

from blockcypher-python.

gustavklopp avatar gustavklopp commented on June 25, 2024

Thanks.
I've tried to use
inputs = [{'address':pubkey_list}] or inputs = [{'address':adress_list}]
but I've got now:

Traceback (most recent call last):
  File "/home/gus/workspace/btcc_project/test_of_blockcypher_multisig.py", line 53, in <module>
    unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs, coin_symbol='btc-testnet')
  File "/home/gus/.Envs/bitcoin/lib/python3.5/site-packages/blockcypher/api.py", line 1494, in create_unsigned_tx
    ), address
AssertionError: ['mySFV5esqFZqz8maEVjEodxwc9xyhXMmmY', 'mouKAz9iAgMJzZjiiw4bZ4rxkJapkTXVDZ', 'mkmCeTJCLuhQw37xGCW7gFSSh3z4wXxGQ1']

So apparently, the assertion check doesn't recognize a list, only address:
I've tried to modify utils.py :

def is_valid_address_for_coinsymbol(b58_address, coin_symbol):
    '''
    Is an address both valid *and* start with the correct character
    for its coin symbol (chain/network)
    '''
    assert is_valid_coin_symbol(coin_symbol)

    if b58_address[0] in COIN_SYMBOL_MAPPINGS[coin_symbol]['address_first_char_list']:
        if is_valid_address(b58_address):
            return True
    return False

modified to :

def is_valid_address_for_coinsymbol(b58_address, coin_symbol):
    '''
    Is an address both valid *and* start with the correct character
    for its coin symbol (chain/network)
    '''
    assert is_valid_coin_symbol(coin_symbol)

    if isinstance(b58_address, list):
        for addr in b58_address:
            if b58_address[0] in COIN_SYMBOL_MAPPINGS[coin_symbol]['address_first_char_list']:
                if not is_valid_address(b58_address):
                    return False
        return True
    else:
        if b58_address[0] in COIN_SYMBOL_MAPPINGS[coin_symbol]['address_first_char_list']:
            if is_valid_address(b58_address):
                return True
    return False

Now when I use:

inputs = [{'address':pubkey_list}]
outputs = [{'address': addr1, 'value':200000 }]
unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs, coin_symbol='btc-testnet')
pprint(unsigned_tx)

this results in:

{'error': "Couldn't deserialize request: json: cannot unmarshal array into Go "
          'value of type string'}

from blockcypher-python.

mflaxman avatar mflaxman commented on June 25, 2024

Hi @gustavklopp, thanks for the info and sorry for all the trouble. We'll get this working!

@acityinohio, why does this curl call work?

$ curl -d '{"inputs":[{"addresses": ["2NEMZM6bLwdT18sKSrnfXcdcdGfqgccc9Qj"]}],"outputs":[{"addresses": ["mgMZ3UdQsEmJ1ebjRV9ibTn1DFCxgmMo7a"], "value": 200000000}]}' https://api.blockcypher.com/v1/btc/test3/txs/new?includeToSignTx=true

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:

curl -d '{ "inputs" : [ {"addresses": ["0471b0e83960b9a8ad980400fc7ee85e9739009f0ee08ef033784bdcefe7f38c64e9ba2b9d842089486735556e0b1940304db510ad521865bb5b028dee229c1dbd", "04a3cc3225df2f6ca72e960c5cab0059731301d5efe61e7ffa1c4cac3a8e4994adcb27f01a282b7747d96ffdad324e774087c4a35197e99016bca62541af26eab", "04db43666cf4206e7848aaaf551e2ea6af2488b23046c155f1456d0dd175c782eef61acc42ededcd45a37012c7e096125e356c839e9c0a5f9c75d48aeddcad6712"], "script_type" : "multisig-2-of-3" }],"outputs":[{"addresses": ["mgMZ3UdQsEmJ1ebjRV9ibTn1DFCxgmMo7a"], "value": 200000000}]}' https://api.blockcypher.com/v1/btc/test3/txs/new?includeToSignTx=true

I've update the python SDK to accept this, if you pull the latest version (1.0.56) the following should work:

from blockcypher import create_unsigned_tx

dest_addr = "mgMZ3UdQsEmJ1ebjRV9ibTn1DFCxgmMo7a"

priv1 = "9c46389dde9e820294b68defd44e01da12cfe1374324cf27c198e4822e7d9d1e"
pub1 = "0471b0e83960b9a8ad980400fc7ee85e9739009f0ee08ef033784bdcefe7f38c64e9ba2b9d842089486735556e0b1940304db510ad521865bb5b028dee229c1dbd"
addr1 = "mySFV5esqFZqz8maEVjEodxwc9xyhXMmmY"

pub2 = '04a3cc3225df2ef6ca72e960c5cab0059731301d5efe61e7ffa1c4cac3a8e4994adcb27f01a282b7747d96ffdad324e774087c4a35197e99016bca62541af26eab'
addr2 = 'mouKAz9iAgMJzZjiiw4bZ4rxkJapkTXVDZ'

pub3 = '04db43666cf4206e7848aaaf551e2ea6af2488b23046c155f1456d0dd175c782eef61acc42ededcd45a37012c7e096125e356c839e9c0a5f9c75d48aeddcad6712'
addr3 = 'mkmCeTJCLuhQw37xGCW7gFSSh3z4wXxGQ1'

pubkey_list = [pub1, pub2, pub3]
#multisig = generate_multisig_address(pubkey_list, coin_symbol='btc-testnet')
# so we got:
multisig_addr = '2NEMZM6bLwdT18sKSrnfXcdcdGfqgccc9Qj'

inputs = [{'pubkeys':pubkey_list, 'script_type': 'multisig-2-of-3'}]
outputs = [{'address': dest_addr, 'value':200000 }]

unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs, coin_symbol='btc-testnet', include_tosigntx=True)

import pprint; pprint.pprint(unsigned_tx, width=1)

## -- End pasted text --
{'tosign': ['35fc0f055ec9145631c6216c6cbba3d2e6f75b061b4bfb828a530c4788393608'],
 'tosign_tx': ['01000000017b99e6ed1b439965cae0c2be942eb1622fbc7cb1c12e139795d38eaa9f333be400000000c952410471b0e83960b9a8ad980400fc7ee85e9739009f0ee08ef033784bdcefe7f38c64e9ba2b9d842089486735556e0b1940304db510ad521865bb5b028dee229c1dbd4104a3cc3225df2ef6ca72e960c5cab0059731301d5efe61e7ffa1c4cac3a8e4994adcb27f01a282b7747d96ffdad324e774087c4a35197e99016bca62541af26eab4104db43666cf4206e7848aaaf551e2ea6af2488b23046c155f1456d0dd175c782eef61acc42ededcd45a37012c7e096125e356c839e9c0a5f9c75d48aeddcad671253aeffffffff02400d0300000000001976a9140930f90fe591bf98350dbf21a9e52a25cd2bfbd588ac98ae955a0000000017a914e78d4c143f67da579214af60bd4a94fad4e086d5870000000001000000'],
 'tx': {'addresses': ['mgMZ3UdQsEmJ1ebjRV9ibTn1DFCxgmMo7a',
                      '2NEMZM6bLwdT18sKSrnfXcdcdGfqgccc9Qj'],
        'block_height': -1,
        'block_index': -1,
        'confidence': 0,
        'confirmations': 0,
        'double_spend': False,
        'fees': 20400,
        'hash': 'be8dd537919a337e171b47408fbf0f9d15bd33faa59fd3f5827d7cc0d14ef3ce',
        'inputs': [{'addresses': ['0471b0e83960b9a8ad980400fc7ee85e9739009f0ee08ef033784bdcefe7f38c64e9ba2b9d842089486735556e0b1940304db510ad521865bb5b028dee229c1dbd',
                                  '04a3cc3225df2ef6ca72e960c5cab0059731301d5efe61e7ffa1c4cac3a8e4994adcb27f01a282b7747d96ffdad324e774087c4a35197e99016bca62541af26eab',
                                  '04db43666cf4206e7848aaaf551e2ea6af2488b23046c155f1456d0dd175c782eef61acc42ededcd45a37012c7e096125e356c839e9c0a5f9c75d48aeddcad6712'],
                    'age': 365,
                    'output_index': 0,
                    'output_value': 1519979400,
                    'prev_hash': 'e43b339faa8ed39597132ec1b17cbc2f62b12e94bec2e0ca6599431bede6997b',
                    'script': '',
                    'script_type': 'multisig-2-of-3',
                    'sequence': 4294967295}],
        'lock_time': 0,
        'outputs': [{'addresses': ['mgMZ3UdQsEmJ1ebjRV9ibTn1DFCxgmMo7a'],
                     'script': '76a9140930f90fe591bf98350dbf21a9e52a25cd2bfbd588ac',
                     'script_type': 'pay-to-pubkey-hash',
                     'value': 200000},
                    {'addresses': ['2NEMZM6bLwdT18sKSrnfXcdcdGfqgccc9Qj'],
                     'script': 'a914e78d4c143f67da579214af60bd4a94fad4e086d587',
                     'script_type': 'pay-to-script-hash',
                     'value': 1519759000}],
        'preference': 'high',
        'received': '2016-01-14T17:17:12.766551971Z',
        'relayed_by': '207.38.134.25, '
                      '127.0.0.1',
        'size': 117,
        'total': 1519959000,
        'ver': 1,
        'vin_sz': 1,
        'vout_sz': 2}}

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 make_tx_signatures the following (notice the repeating because we want to sign it twice):

make_tx_signatures(
    txs_to_sign['35fc0f055ec9145631c6216c6cbba3d2e6f75b061b4bfb828a530c4788393608', '35fc0f055ec9145631c6216c6cbba3d2e6f75b061b4bfb828a530c4788393608']
    privkey_list=[privkey1, privkey2],
    pubkey_list=[pubkey1, pubkey2],
)

Does that make sense?

from blockcypher-python.

gustavklopp avatar gustavklopp commented on June 25, 2024

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):

""" Siging with one of the privkey """
tx_signatures = make_tx_signatures(txs_to_sign=unsigned_tx['tosign'], privkey_list=[priv1], pubkey_list=[pub1])
print(tx_signatures)
r = broadcast_signed_transaction(unsigned_tx, tx_signatures, [pub1], coin_symbol='btc-testnet')
pprint(r)

That's very great! Thanks again a lot

from blockcypher-python.

acityinohio avatar acityinohio commented on June 25, 2024

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 )

from blockcypher-python.

mflaxman avatar mflaxman commented on June 25, 2024

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.

from blockcypher-python.

gustavklopp avatar gustavklopp commented on June 25, 2024

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

from blockcypher-python.

mflaxman avatar mflaxman commented on June 25, 2024

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

from blockcypher-python.

acityinohio avatar acityinohio commented on June 25, 2024

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. :-/

from blockcypher-python.

mflaxman avatar mflaxman commented on June 25, 2024

Gotcha, thanks!

So is having the API throw an error on submitting a p2sh address (not pubkeys) still on your list?

from blockcypher-python.

acityinohio avatar acityinohio commented on June 25, 2024

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.

from blockcypher-python.

mflaxman avatar mflaxman commented on June 25, 2024

Thanks!

No rush, the python code isn't dependent on it. Just wanted to make it didn't fall through the cracks.

from blockcypher-python.

acityinohio avatar acityinohio commented on June 25, 2024

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 /txs/send step). That said, without that "multisig-n-of-m," we wouldn't know how to properly hash the scriptSig (which is what errored in this case), so we still need slightly more info than just the script. I just submitted a patch here (not merged/deployed yet). Once deployed, it should return an error when a P2SH address is used without a corresponding script_type.

from blockcypher-python.

mflaxman avatar mflaxman commented on June 25, 2024

Thanks for the update @acityinohio. Hmm, based on your earlier comments I wrote the simple_spend_p2sh method to require all pubkeys:
https://github.com/blockcypher/blockcypher-python/pull/40/files#diff-c1077949a462f79efc62028519405cbaR1913

If I'm understanding you correctly, you are saying:

  1. All pubkeys are not strictly required on /txs/new, provided you include script_type : "multisig-n-of-m" in your input?
  2. All pubkeys (not just those used in tx signing) are required when you get to /txs/send?

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.

from blockcypher-python.

acityinohio avatar acityinohio commented on June 25, 2024

Best practice is definitely to use all pubkeys as address inputs for /txs/new. But as long as the user correctly specifies "script_type": "multisig-n-of-m" (and uses the correct n and m, e.g. multisig-2-of-3) with the P2SH address as an input, they should be able to get the right data to sign. In the subsequent /txs/send they will have to include every public key for every P2SH UTXO they are spending

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:

OP_2 [A's pubkey] [B's pubkey] [C's pubkey] OP_3 OP_CHECKMULTISIG

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.

from blockcypher-python.

mflaxman avatar mflaxman commented on June 25, 2024

Thanks @acityinohio , that was a perfect answer!

from blockcypher-python.

kumrzz avatar kumrzz commented on June 25, 2024

hey @acityinohio , it seems I am having to supply an API token to be able to use create_unsigned_tx() :

unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs, coin_symbol='btc-testnet', include_tosigntx=True, api_key='blah')

(or else it fails complaining'No API token supplied')
... given this is not actually hitting the blockchain, don't you think its a bit OTT to require a token ?

from blockcypher-python.

mflaxman avatar mflaxman commented on June 25, 2024

It requires an API token because Blockcypher is fetching all the UTXOs
and selecting which ones to include in the transaction. Then Blockcypher
builds an unsigned TX to verify client side.

Does that make sense?

On Friday, June 10, 2016, Kumar Ghosh [email protected] wrote:

hey @acityinohio https://github.com/acityinohio , it seems I am having
to supply an API token to be able to use create_unsigned_tx() :

unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs,
coin_symbol='btc-testnet', include_tosigntx=True, api_key='blah')

(or else it fails complaining'No API token supplied')
... given this is not actually hitting the blockchain, don't you think its
a bit OTT to require a token ?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#28 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AAbYhPjwyyN6tkLd_S48kRFggGsbPNNFks5qKSkJgaJpZM4HEFtt
.

Sent from my iPhone

from blockcypher-python.

kumrzz avatar kumrzz commented on June 25, 2024

yes absolutely mate, sorry that was a bit of a dumb question :s

from blockcypher-python.

acityinohio avatar acityinohio commented on June 25, 2024

'sallgood @kumrzz! no such thing, always good to have opportunities for clarification. 👍

from blockcypher-python.

RamiJaloudi avatar RamiJaloudi commented on June 25, 2024

I'm getting an assertion error:
C:\Users\RJalo\Desktop>python 2of3aaa2.py
Traceback (most recent call last):
File "2of3aaa2.py", line 48, in
tx_signatures = make_tx_signatures(txs_to_sign=unsigned_tx['tosign'], privkey_list=privkey_list, pubkey_list=pubkey_list)
File "C:\Users\RJalo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\blockcypher\api.py", line 1843, in make_tx_signatures
assert len(privkey_list) == len(pubkey_list) == len(txs_to_sign)
AssertionError
#############################################################

import blockcypher

#personalWallet = {
 #   'address': 'mtiM4kphi8w9NweV8PRfJ6TBrs2cL5EscR',
 #   'private': '93S742e5hYWib7K8RC2o7pkK8xBwmAenrWwHxSRc6ZP27cDUbnU'
#}

#multisigKeys = [{
 #   'address': 'n2GFJcivbiuLy3gwa4RwUZknWrWNaKosF8',
 #   'private': '91eo9h9J5h2mgHpW4PjH4cE5UATTRkcWaynw2CvQp7q8F6shnE7', #n2GFJcivbiuLy3gwa4RwUZknWrWNaKosF8
#	#0326de79e072071956c07e39802bf4e692e1cbc570cbd3e9814e5e9b
#},{
#    'address': 'mxXpdrr1DFVNPpdXH1yzeLje9JF8TuFbvB',
#    'private': '92QmukWsv3TCNDgRccQ88vqfyEFN5zQMSYRnwC2rDxUn8eet4ay', #mxXpdrr1DFVNPpdXH1yzeLje9JF8TuFbvB
	##bc4dc326544eefc43c7cecad68c06b4ea7faa953bb944b4854134556
#},{
 #   'address': 'ms3K4ANfmBS3neNKbfSehMhX2dHWXkZgu6',
 #   'private': '91yoRoGbSBcRJVCYxWEwLtDuMj3SzvMg4cm9q7KqgzuhGiwSS6G', #ms3K4ANfmBS3neNKbfSehMhX2dHWXkZgu6
#	#e679aa2cf91fa54728d2d82cad72ec5223e1ba2851f3d0c6c49fbaea
#}]


finalDestinationAddress = 'mxdNW2wKGafADgYpxWo2LBp6t3VfnCqt9J'

apiKey = 'eaacdbb026814590acb6ce47918209f0'

# Get Details for personal wallet
#getWalletDetails = lambda x : blockcypher.get_address_overview(x, coin_symbol='btc-testnet')
#getWalletDetails(personalWallet['address'])

#[ getWalletDetails(x['address']) for x in multisigKeys ]
#apiKey = 'eaacdbb026814590acb6ce47918209f0'


dest_addr = "mxdNW2wKGafADgYpxWo2LBp6t3VfnCqt9J"

priv1 = "93S742e5hYWib7K8RC2o7pkK8xBwmAenrWwHxSRc6ZP27cDUbnU"
pub1 = "044D88423A9AAECC0019854E0241A3625342AA924E2A026248BC5E823407B31A579B156A8A5FD691B50A3F705E56848494E1BE896B90A6617F380AC99808982606"
addr1 = "mtiM4kphi8w9NweV8PRfJ6TBrs2cL5EscR"

priv2 = "91eo9h9J5h2mgHpW4PjH4cE5UATTRkcWaynw2CvQp7q8F6shnE7"
pub2 = '047E3B25401017ED57934CA40AA74B99CDA432BF33FBBD2BD03D3366BE2233BEEE5C13C3BA4BC4987403F504B45E2B15942B3FB59ECF485AB1D45C0E5B98675626'
addr2 = 'n2GFJcivbiuLy3gwa4RwUZknWrWNaKosF8'

priv3 = "91yoRoGbSBcRJVCYxWEwLtDuMj3SzvMg4cm9q7KqgzuhGiwSS6G"
pub3 = '0424094D9B0D12220F7CA1794ECB999F6A3B369DC8C09CEB25BEFF01CCED0E1C1F1FF3C2761EF32CF1025ADC427FD0A1175241E94A5D78F2EEDB51AAA258DC3ED8'
addr3 = 'ms3K4ANfmBS3neNKbfSehMhX2dHWXkZgu6'

#pubkey_list = [pub1, pub2, pub3]
#multisig = generate_multisig_address(pubkey_list, coin_symbol='btc-testnet')
# so we got:
multisig_addr = 'mxdNW2wKGafADgYpxWo2LBp6t3VfnCqt9J'

from blockcypher import create_unsigned_tx, make_tx_signatures, broadcast_signed_transaction

inputs = [{'address':multisig_addr}]
outputs = [{'address': dest_addr, 'value':200000 }]

unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs, coin_symbol='btc-testnet', api_key=apiKey)
# pprint(unsigned_tx)

privkey_list = [priv1]
pubkey_list = [pub1]

tx_signatures = make_tx_signatures(txs_to_sign=unsigned_tx['tosign'], privkey_list=privkey_list, pubkey_list=pubkey_list)

r = broadcast_signed_transaction(unsigned_tx, tx_signatures, pubkey_list, coin_symbol='btc-testnet', api_key=apiKey)
print(r)

from blockcypher-python.

agrawalnandini avatar agrawalnandini commented on June 25, 2024

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.

from blockcypher-python.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.