From 943b5d731d6c96c27bde5e10da50c8148d04feb2 Mon Sep 17 00:00:00 2001 From: jodobear Date: Tue, 23 Jun 2020 17:05:01 +0200 Subject: [PATCH] cleaned the code, fixed a bug and added annotations --- 18_4_Accessing_Bitcoind_with_Python .md | 55 +++++++++++----------- src/18_4_accessing_bitcoind_with_python.py | 44 ++++++++--------- 2 files changed, 49 insertions(+), 50 deletions(-) diff --git a/18_4_Accessing_Bitcoind_with_Python .md b/18_4_Accessing_Bitcoind_with_Python .md index 0c6ad10..2d8a9d7 100644 --- a/18_4_Accessing_Bitcoind_with_Python .md +++ b/18_4_Accessing_Bitcoind_with_Python .md @@ -195,7 +195,7 @@ All the 3 transactions: ## Exploring an Address -How about getting a list of all the transactions of your address? Type the following and see all the transactions of your address: +How about getting a list of all the transactions of your address? Type the following and see the transaction history of your address: ```py track_address = "" @@ -245,43 +245,42 @@ Now that we have established comfort between our python and bitcoind interface, ### 1. Create New Addresses +For the purposes of learning, we will send bitcoins to an address generated by our node. We also generate a change address to receive back change from the difference between input and recipient amounts less the miner fees. For this we use `getrawchangeaddress`. It's largely the same as `getnewaddress` but is optimized for use as a change address in a raw transaction, so it doesn't do things like make entries in your address book. + ```py print("Creating a Transaction") ## Create New Addresses -new_address_01 = rpc_client.getnewaddress("Learning-Bitcoin-from-the-Command-Line-01") -new_address_02 = rpc_client.getnewaddress("Learning-Bitcoin-from-the-Command-Line-02") +new_address = rpc_client.getnewaddress("Learning-Bitcoin-from-the-Command-Line") +new_change_address = rpc_client.getrawchangeaddress() ``` ### 2. Select UTXO & Set Transaction Details -In the folowing code snippet we first select the UTXO which we want to spend. Then we get it's address, transaction id, vector index of the output and check the amount of bitcoins the utxo at the `vout`. - -Then we add the recipent address to which we want to send the bitcoins, enter the amount of bitcoins we want to send, set miner fee and calculate the change amount. +In the folowing code snippet we first select the UTXO which we want to spend. Then we get it's address, transaction id, vector index of the output. Then we add the recipent address to which we want to send the bitcoins, enter the amount of bitcoins we want to send, set miner fee and calculate the change amount. ```py -utxos = rpc_client.listunspent() -second_utxo = utxos[1] -utxo_address = second_utxo["address"] -utxo_txid = second_utxo["txid"] -vector_id = second_utxo["vout"] -utxo_amt = float(second_utxo["amount"]) -# here we are sending bitcoins to an address generated by us in out own wallet. -recipient_address = new_address_01 -recipient_amt = utxo_amt / 2 -miner_fee = 0.00000200 -change_address = new_address_02 -change_amt = float((utxo_amt - recipient_amt) - miner_fee) +selected_utxo = utxos[0] # we select the first utxo here +utxo_address = selected_utxo['address'] +utxo_txid = selected_utxo['txid'] +utxo_vout = selected_utxo['vout'] +utxo_amt = float(selected_utxo['amount']) +# here we are sending bitcoins to an address generated by us in our own wallet. +recipient_address = new_address +recipient_amt = utxo_amt / 2 # sending half coins to recipient +miner_fee = 0.00000200 # choose appropriate fee based on your tx size +change_address = new_change_address +change_amt = float('%.8f'%((utxo_amt - recipient_amt) - miner_fee)) print("---------------------------------------------------------------") print("Transaction Details:") print("-------------------") print("UTXO Address.......: ", utxo_address) print("UTXO Txid..........: ", utxo_txid) -print("Vector ID of Output: ", vector_id) +print("Vector ID of Output: ", utxo_vout) print("UTXO Amount........: ", utxo_amt) print("Tx Amount..........: ", recipient_amt) print("Recipient Address..: ", recipient_address) print("Change Address.....: ", change_address) -print("Miner Fee..........: ", '%f'%(miner_fee)) +print("Miner Fee..........: ", miner_fee) print("Change Amount......: ", change_amt) print("---------------------------------------------------------------\n") ``` @@ -309,9 +308,9 @@ Change Amount......: 0.004998 Now we have all the information to send a transaction, but before we can send one, we have to create a transaction, we do that by creating a raw transaction, like so: ```py -txid_vout = {"txid": utxo_txid, "vout": vector_id} +txids_vouts = [{"txid": utxo_txid, "vout": utxo_vout}] addresses_amts = {f"{recipient_address}": recipient_amt, f"{change_address}": change_amt} -create_raw_tx = rpc_client.createrawtransaction([txid_vout], addresses_amts) +create_raw_tx = rpc_client.createrawtransaction(txids_vouts, addresses_amts) unsigned_tx_hex = create_raw_tx print("---------------------------------------------------------------") print("Unsigned Transaction Hex: ", unsigned_tx_hex) @@ -330,25 +329,25 @@ The format of the `createrawtransaction` command is: `$ bitcoin-cli createrawtransaction '[{"txid": , "vout": }]' '{"
": }'` -Hence, we have constructed `txid_vout` and `addresses_amts` in this manner. +The `txids_vouts` is a list and `addresses_amts` is a python dictionary to match with the format of `createrawtransaction`. Try checking the details of the transaction, hint: use `decoderawtransaction`. ### 4. Sign Raw Transaction -Now that we have a raw transaction, we use it's hex and the private key of the utxo we are spending to sign the transaction like so: +Now that we have a raw transaction, we use it's hex and the private key of the utxos we are spending to sign the transaction like so: ```py -address_priv_key = [] +address_priv_key = [] # list of priv keys of each utxo address_priv_key.append(rpc_client.dumpprivkey(utxo_address)) -sign_tx = rpc_client.signrawtransactionwithkey(unsigned_tx_hex, address_priv_key) +signed_tx = rpc_client.signrawtransactionwithkey(unsigned_tx_hex, address_priv_key) print("---------------------------------------------------------------") print("Signed Transaction: ") print("----------------------") pprint(signed_tx) print("---------------------------------------------------------------\n") ``` -This returns a json object with the signed transaction's hex and whether it was completed successfully or not: +This returns a json object with the signed transaction's hex and whether it was signed completely or not: ```sh --------------------------------------------------------------- @@ -364,7 +363,7 @@ Signed Transaction: Finally, we are now ready to broadcast our signed transaction on the bitcoin network like so: ```py -send_tx = rpc_client.sendrawtransaction(signed_tx_hex['hex']) +send_tx = rpc_client.sendrawtransaction(signed_tx['hex']) print("---------------------------------------------------------------") print("TXID of sent transaction: ", send_tx) print("---------------------------------------------------------------\n") diff --git a/src/18_4_accessing_bitcoind_with_python.py b/src/18_4_accessing_bitcoind_with_python.py index 577b9a3..bb0e770 100644 --- a/src/18_4_accessing_bitcoind_with_python.py +++ b/src/18_4_accessing_bitcoind_with_python.py @@ -119,43 +119,43 @@ print("---------------------------------------------------------------\n") # Creating a Transaction print("Creating a Transaction") ## Create New Addresses -new_address_01 = rpc_client.getnewaddress("Learning-Bitcoin-from-the-Command-Line-01") -new_address_02 = rpc_client.getnewaddress("Learning-Bitcoin-from-the-Command-Line-01") +new_address = rpc_client.getnewaddress("Learning-Bitcoin-from-the-Command-Line") +new_change_address = rpc_client.getrawchangeaddress() print("---------------------------------------------------------------") -print("New Address Recipient: ", new_address_01) -print("New Address Change...: ", new_address_02) +print("New Address Recipient: ", new_address) +print("New Address Change...: ", new_change_address) print("---------------------------------------------------------------\n") ## Set Transaction Details -second_utxo = utxos[1] -utxo_address = second_utxo["address"] -utxo_txid = second_utxo["txid"] -vector_id = second_utxo["vout"] -utxo_amt = float(second_utxo["amount"]) -# here we are sending bitcoins to an address generated by us in out own wallet. -recipient_address = new_address_01 -recipient_amt = utxo_amt / 2 -miner_fee = 0.00000200 -change_address = new_address_02 -change_amt = float((utxo_amt - recipient_amt) - miner_fee) +selected_utxo = utxos[0] # we select the first utxo here +utxo_address = selected_utxo['address'] +utxo_txid = selected_utxo['txid'] +utxo_vout = selected_utxo['vout'] +utxo_amt = float(selected_utxo['amount']) +# here we are sending bitcoins to an address generated by us in our own wallet. +recipient_address = new_address +recipient_amt = utxo_amt / 2 # sending half coins to recipient +miner_fee = 0.00000200 # choose appropriate fee based on your tx size +change_address = new_change_address +change_amt = float('%.8f'%((utxo_amt - recipient_amt) - miner_fee)) print("---------------------------------------------------------------") print("Transaction Details:") print("-------------------") print("UTXO Address.......: ", utxo_address) print("UTXO Txid..........: ", utxo_txid) -print("Vector ID of Output: ", vector_id) +print("Vector ID of Output: ", utxo_vout) print("UTXO Amount........: ", utxo_amt) print("Tx Amount..........: ", recipient_amt) print("Recipient Address..: ", recipient_address) print("Change Address.....: ", change_address) -print("Miner Fee..........: ", '%f'%(miner_fee)) +print("Miner Fee..........: ", miner_fee) print("Change Amount......: ", change_amt) print("---------------------------------------------------------------\n") ## create a raw transacion -txid_vout = {"txid": utxo_txid, "vout": vector_id} +txids_vouts = [{"txid": utxo_txid, "vout": utxo_vout}] addresses_amts = {f"{recipient_address}": recipient_amt, f"{change_address}": change_amt} -create_raw_tx = rpc_client.createrawtransaction([txid_vout], addresses_amts) +create_raw_tx = rpc_client.createrawtransaction(txids_vouts, addresses_amts) unsigned_tx_hex = create_raw_tx print("---------------------------------------------------------------") print("Unsigned Transaction Hex: ", unsigned_tx_hex) @@ -171,12 +171,12 @@ pprint(tx_details) print("---------------------------------------------------------------\n") ## Sign Transanciton -address_priv_key = [] +address_priv_key = [] # list of priv keys of each utxo address_priv_key.append(rpc_client.dumpprivkey(utxo_address)) print("---------------------------------------------------------------") print(f"Private key of address {utxo_address}: ", address_priv_key) print("---------------------------------------------------------------\n") -sign_tx = rpc_client.signrawtransactionwithkey(unsigned_tx_hex, address_priv_key) +signed_tx = rpc_client.signrawtransactionwithkey(unsigned_tx_hex, address_priv_key) print("---------------------------------------------------------------") print("Signed Transaction: ") print("----------------------") @@ -184,7 +184,7 @@ pprint(signed_tx) print("---------------------------------------------------------------\n") ## Send Transaction -send_tx = rpc_client.sendrawtransaction(signed_tx_hex['hex']) +send_tx = rpc_client.sendrawtransaction(signed_tx['hex']) print("---------------------------------------------------------------") print("TXID of sent transaction: ", send_tx) print("---------------------------------------------------------------\n")