Constructing, signing, and pushing a Bitcoin transaction by using pybitcointools with Python

2

1

I'm utilizing the pybitcointools module in python 3.4

I've went through time and time again in the examples listed on the github page, but it isn't documented very well nor is the code.

My situation is this: I have a list of private keys in a CSV and I want to generate a raw transaction for each address and spend their unspent_outputs to a single address by pushing the signed transaction to blockchain.info

I'm having a problem when it comes to the these functions: mktx, mksend, sign

If someone could create an example of the process while also documenting each step and explaining what each argument for each function is for and how it's used. This would be an amazing help if someone could give a hand here! I've searched far and low, but I just can't find a good documentation of this process. I'm sure this would help many others as well!

encodex

Posted 2015-08-21T22:42:42.023

Reputation: 23

Give me an hour and I'll write up an answer. You're right, the code is severely lacking in documentation. Check out this fork for some better code comments until i reply but note it's not tested for 3.4 only 2.7,

Wizard Of Ozzie 2015-08-22T06:49:09.527

Answers

3

OK, so first off:

  1. Use Python 2.7; there's numerous pieces of code which doesn't work with Python 3.4, namely make_request
  2. Check out this pybitcointools fork, as there's a lot of added functionality (see the README.txt file)

The functions you've named work as so:

  • mktx(ins, outs) where ins is an array of "hexTxIdString:index" and outs is an array of {"value": 12345, "address": 1base58addressString}
  • mksend(ins, outs, txfee, 1changeAddress) where txfee is again in Satoshis
    • sign(unsignedtx, index to sign, privkey for utxo) where index is the input index to sign

We'll start by making the ins:

utxos = [(utxo_txid, utxo_index), (txid2, i2)....]
ins = ["%s:%d" % utxo for utxo in utxos]
change_addr = "1thisIsAChangeAddressYouOwn123"
txfee = int(0.45 * len(ins) * 10000) # you may want to check this 10000 value, it could be 100000
rawtx = mksend(ins, txfee, change_addr)

Right, so let's assume, you have the UTXOs' TxID and corresponding vout for each private key. Make an dict of privkeys ={ 'TxID:vout' : privkey, 'TxID2:vout2': privkey2 } Then finally, signall(rawtx, privkeys) to get your signed Tx. Then to broadcast it, use pushtx(signedTx, source="bci") or pushtx(signedTx, "testnet", source="blockr") for Testnet. Done!

Wizard Of Ozzie

Posted 2015-08-21T22:42:42.023

Reputation: 4 535

What function are you using to easily get the values for utxos ? What's the best way to go about it?encodex 2015-08-22T13:45:01.137

I use that fork I linked; you can filter a list of the history/unspent, then use get_outputs to return the string required. Have had this exact same issueWizard Of Ozzie 2015-08-22T13:46:29.963

In the code block above you have there doesn't show you using mktx but you explained it above.encodex 2015-08-22T13:52:54.650

address = 164QpJNZPYtHNVZiNmzuG2yEeWok2UfymZ

So, I should use history(address) rather than unspent(address) ?

It doesn't look like history gives me the unspent_output hash? I'm still really, really confused because it seems like in the pybitcointools example they do it in a completely different way.

I'm trying to imagine how to do it from the very beginning with creating my variables and everything.

"2e204724677fb2f6cc80ed4cc92f0d068e8ec7774f49bfbf4b075aea76154f2b:0"

is the outspent output and index, am I right?

Getting my ass kicked with formatting on here for some reason. – encodex 2015-08-22T14:23:41.407

Actually, you're right, use unspent: unspent_1 = [unspent(privtoaddr(x)) for x in privs]. I believe that'll return an array of "txid:index", which you'll need to filter through for unspents which have len>1, with [x for y in unspent_1 for x in y] which returns the flattened list. Re: mktx, mksend calls mktx, it just works out the difference and refunds that to a change addressWizard Of Ozzie 2015-08-22T15:07:25.797

I'll give it a whirl here in a bit. Thanks for all the help.encodex 2015-08-22T15:28:50.003

@encodex cool, I'll edit my answer shortly to show you exactly the processWizard Of Ozzie 2015-08-23T04:56:22.190