mirror of
				https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
				synced 2025-10-31 10:27:29 +00:00 
			
		
		
		
	edited & standardized first half of article
This commit is contained in:
		
							parent
							
								
									c4f6203eef
								
							
						
					
					
						commit
						223fcf851b
					
				| @ -1,24 +1,29 @@ | |||||||
| # 18.4: Accessing Bitcoind with Python | # 17.4: Accessing Bitcoind with Python | ||||||
| 
 | 
 | ||||||
| > NOTE: This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. | > :information_source: **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. | ||||||
| 
 | 
 | ||||||
| Interacting with the bitcoind directly and using command-line curl can get simple if you understand how it works, but there's a project [Python-BitcoinRPC](https://github.com/jgarzik/python-bitcoinrpc) that provides the functionality in a Python-API level, making it even easier to interact with your Bitcoin Server. | This section explains how to interact with `bitcoind` using the Python programming language and the [Python-BitcoinRPC](https://github.com/jgarzik/python-bitcoinrpc). | ||||||
| 
 | 
 | ||||||
| ## Setup Python | ## Setting Up Python | ||||||
| 
 | 
 | ||||||
| We are going to be using python 3 for this chapter. Debian 10 installs python3 and if you have bitcoin-core installed, you should have it installed. Let's check, run: | If you already have Bitcoin Core installed, you should have Python 3 available as well. | ||||||
|  | You can check this by running: | ||||||
| 
 | 
 | ||||||
| `$ python3 --version` | `$ python3 --version` | ||||||
| 
 | 
 | ||||||
| If it returns the version number then you have python3 installed. If it returns nothing or an error then we will build python from source, do: | If it returns a version number (e.g., `3.7.3` or `3.8.3`) then you have python3 installed. Continue on to the next header. | ||||||
| 
 | 
 | ||||||
| #### 1. Install dependencies: | However, if you somehow do not have Python installed, you'll need build it from source as follows: | ||||||
|  | 
 | ||||||
|  | ### Building Python from Source | ||||||
|  | 
 | ||||||
|  | #### 1. Install Dependencies | ||||||
| ```sh | ```sh | ||||||
| $ sudo apt-get install build-essential checkinstall | $ sudo apt-get install build-essential checkinstall | ||||||
| $ sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev | $ sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| #### 2. Download & extract Python: | #### 2. Download & Extract Python | ||||||
| ```sh | ```sh | ||||||
| $ wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz | $ wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz | ||||||
| $ tar -xzf Python-3.8.3.tgz | $ tar -xzf Python-3.8.3.tgz | ||||||
| @ -39,49 +44,60 @@ After you get the version output, remove the source file: | |||||||
| $ rm Python-3.8.3.tgz | $ rm Python-3.8.3.tgz | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Setup Dependency | ### Setting Up BitcoinRPC | ||||||
| 
 | 
 | ||||||
| We are going to install the `python-bitcoinrpc` library, like so: | sudo apt-get install python3-pip | ||||||
| 
 | 
 | ||||||
| `python3.8 -m pip install python-bitcoinrpc` | Whether you used an existing Python or built it from source, you're now ready to install  the `python-bitcoinrpc` library: | ||||||
| 
 | 
 | ||||||
| ## Build Your Connection | ``` | ||||||
|  | $ pip3 install python-bitcoinrpc | ||||||
|  | ``` | ||||||
|  | If you don't have `pip` installed, you'll need to run the following: | ||||||
|  | ``` | ||||||
|  | $ sudo apt install python3-pip | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| We are now ready to start interacting with `bitcoind`, but first we need to establish a connection. Create a file called `btcrpc.py` and type the following: | ### Creating a BitcoinRPC Project | ||||||
| 
 | 
 | ||||||
|  | You'll generally need to include appropriate declarations from `bitcoinrpc` in your Bitcoin projects in Python: | ||||||
| ```py | ```py | ||||||
| from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException | from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException | ||||||
|  | ``` | ||||||
|  | You may also find the following useful: | ||||||
|  | ```py | ||||||
| from pprint import pprint | from pprint import pprint | ||||||
| import logging | import logging | ||||||
|  | ``` | ||||||
|  | `pprint` will pretty print the `json` response from `bitcoind`. | ||||||
| 
 | 
 | ||||||
|  | `logging` will print out the call you make to `bitcoind` and `bitcoind`'s respose, which is useful when you make a bunch of calls together. If you don't want the excessive output in the terminal just comment out the `logging` block. | ||||||
|  | 
 | ||||||
|  | ## Building Your Connection | ||||||
|  | 
 | ||||||
|  | You are now ready to start interacting with `bitcoind` by establishing a connection. Create a file called `btcrpc.py` and type the following: | ||||||
|  | 
 | ||||||
|  | ```py | ||||||
| logging.basicConfig() | logging.basicConfig() | ||||||
| logging.getLogger("BitcoinRPC").setLevel(logging.DEBUG) | logging.getLogger("BitcoinRPC").setLevel(logging.DEBUG) | ||||||
| # rpc_user and rpc_password are set in the bitcoin.conf file | # rpc_user and rpc_password are set in the bitcoin.conf file | ||||||
| rpc_user = "<ENTER_THE_RPC_USER_FROM_bitcoin.conf>" | rpc_user = "StandUp" | ||||||
| rpc_pass = "<ENTER_THE_RPC_PASSWORD_FROM_bitcoin.conf>" | rpc_pass = "6305f1b2dbb3bc5a16cd0f4aac7e1eba" | ||||||
| rpc_host = "127.0.0.1" | rpc_host = "127.0.0.1" | ||||||
| rpc_client = AuthServiceProxy(f"http://{rpc_user}:{rpc_pass}@{rpc_host}:18332", timeout=120) | rpc_client = AuthServiceProxy(f"http://{rpc_user}:{rpc_pass}@{rpc_host}:18332", timeout=120) | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| `pprint` is a nifty library to pretty print the `json` response from `bitcoind`. | The arguments in the URL are `<rpc_username>:<rpc_password>@<host_IP_address>:<port>`. As usual, the `user` and `pass` are found in your `~/.bitcoin/bitcoin.conf`, while the `host` is your localhost, and the port is `18332` for testnet. The `timeout` argument is specified since sockets timeout under heavy load on the mainnet. If you get `socket.timeout: timed out` response, be patient and increase the `timeout`. | ||||||
| 
 | 
 | ||||||
| `logging` will print out the call we make to `bitcoind` and `bitcoind`'s respose, which is useful when we make a bunch of calls together. If you don't want the excessive output in the terminal just comment out the `logging` block. | > :link: MAINNET VS TESTNET: The port would be 8332 for a mainnet setup. | ||||||
| 
 | 
 | ||||||
| The arguments in the URL are `<rpc_username>:<rpc_password>@<host_IP_address>:<port>`. We covered the relevant information in our work with `curl` . The IP address `127.0.0.1` and port `18332` should be correct for the standard testnet setup described in these documents, while you can extract the user and password from `~/.bitcoin/bitcoin.conf`. We specify the `timeout` argument since socket timeouts under heavy load on the mainnet. If you get `socket.timeout: timed out` response, be patient and increase the `timeout`. | ### Making  an RPC Call | ||||||
| 
 |  | ||||||
| > MAINNET VS TESTNET: The port would be 8332 for a mainnet setup. |  | ||||||
| 
 | 
 | ||||||
| If `rpc_client` is successfully initialized, you'll be able to send off RPC commands to your bitcoin node. | If `rpc_client` is successfully initialized, you'll be able to send off RPC commands to your bitcoin node. | ||||||
| 
 | 
 | ||||||
| In order to use an RPC method using `python-bitcoinrpc`, you'll find that the `rpc_client` provides most of the functionality that can be accessed through `bitcoin-cli` or `curl`, using the same method names. For more details about the commands that you are able to execute and what to expect back, you should refer to [3.2: Knowing Your Bitcoin Setup](https://github.com/jodobear/Learning-Bitcoin-from-the-Command-Line/blob/master/03_2_Knowing_Your_Bitcoin_Setup.md). | In order to use an RPC method using `python-bitcoinrpc`, you'll use `rpc_client`, which provides most of the functionality that can be accessed through `bitcoin-cli`, using the same method names. | ||||||
| 
 | 
 | ||||||
| ## Getting Basic Info | For example, the following will retrieve the blockcount of your node: | ||||||
| 
 |  | ||||||
| Let's start with getting basic information about our node. Enter the following lines under `rpc_client`, save and run it in the terminal as `python3 bitcrpc.py`: |  | ||||||
| 
 |  | ||||||
| ### Get Blockcount |  | ||||||
| 
 |  | ||||||
| Let's get the blockcount of our node: |  | ||||||
| 
 | 
 | ||||||
| ```py | ```py | ||||||
| block_count = rpc_client.getblockcount() | block_count = rpc_client.getblockcount() | ||||||
| @ -99,6 +115,72 @@ DEBUG:BitcoinRPC:<-3- 1773020 | |||||||
| Block Count: 1773020 | Block Count: 1773020 | ||||||
| --------------------------------------------------------------- | --------------------------------------------------------------- | ||||||
| ``` | ``` | ||||||
|  | ### Making an RPC Call with Arguments | ||||||
|  | 
 | ||||||
|  | You can then use that blockcount as an argument to retrieve the blockhash of a block and also to retrieve details of that block: | ||||||
|  | ```py | ||||||
|  | blockhash = rpc_client.getblockhash(block_count) | ||||||
|  | block = rpc_client.getblock(blockhash) | ||||||
|  | nTx = block['nTx'] | ||||||
|  | if nTx > 10: | ||||||
|  |     it_txs = 10 | ||||||
|  |     list_tx_heading = "First 10 transactions: " | ||||||
|  | else: | ||||||
|  |     it_txs = nTx | ||||||
|  |     list_tx_heading = f"All the {it_txs} transactions: " | ||||||
|  | print("---------------------------------------------------------------") | ||||||
|  | print("BLOCK: ", block_count) | ||||||
|  | print("-------------") | ||||||
|  | print("Block Hash...: ", blockhash) | ||||||
|  | print("Merkle Root..: ", block['merkleroot']) | ||||||
|  | print("Block Size...: ", block['size']) | ||||||
|  | print("Block Weight.: ", block['weight']) | ||||||
|  | print("Nonce........: ", block['nonce']) | ||||||
|  | print("Difficulty...: ", block['difficulty']) | ||||||
|  | print("Number of Tx.: ", nTx) | ||||||
|  | print(list_tx_heading) | ||||||
|  | print("---------------------") | ||||||
|  | i = 0 | ||||||
|  | while i < it_txs: | ||||||
|  |     print(i, ":", block['tx'][i]) | ||||||
|  |     i += 1 | ||||||
|  | print("---------------------------------------------------------------\n") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Running Your Code | ||||||
|  | 
 | ||||||
|  | You can retrieve [the src doe](src/17_4_getinfo.py) and run it with `python3`: | ||||||
|  | ``` | ||||||
|  | $ python3 blockinfo.py | ||||||
|  | --------------------------------------------------------------- | ||||||
|  | Block Count: 1831106 | ||||||
|  | --------------------------------------------------------------- | ||||||
|  | --------------------------------------------------------------- | ||||||
|  | BLOCK:  1831106 | ||||||
|  | ------------- | ||||||
|  | Block Hash...:  00000000000003b2ea7c2cdfffd86156ad1f5606ab58e128940a2534d1348b04 | ||||||
|  | Merkle Root..:  056a547fe59208167eef86fa694263728fb684119254b340c1f86bdd423a8082 | ||||||
|  | Block Size...:  52079 | ||||||
|  | Block Weight.:  128594 | ||||||
|  | Nonce........:  1775583700 | ||||||
|  | Difficulty...:  4194304 | ||||||
|  | Number of Tx.:  155 | ||||||
|  | First 10 transactions:  | ||||||
|  | --------------------- | ||||||
|  | 0 : d228d55112e3aa26265b0118cfdc98345c229d20fe074b9afb87107c03ce11b5 | ||||||
|  | 1 : 92822e8e34fafb472b87c99ea3f3e16440452b3f361ed86c6fa62175173fb750 | ||||||
|  | 2 : fa7c67600c14d4aa350a9674688f1429577954f4a6c5e4639d06c8964824f647 | ||||||
|  | 3 : 3a91d1527e308e5603dafde7ab17824f441a73a779d2571d073466dc9e8451b2 | ||||||
|  | 4 : 30fd0e5527b1522e7b26a4818b9edac80fe47c0c39fc34705478a49e684708d0 | ||||||
|  | 5 : 24c5372b38c78cbaf5b0b305925502a491bc0c1b5758f50c0bd335abb6ae85f5 | ||||||
|  | 6 : be70e125a5793efc5e32051fecba0668df971bdf371138c8261201c2a46b2d38 | ||||||
|  | 7 : 41ebf52c847a59ba0aeb4425c74e89a01e91defa86a82785ff53ed4668054561 | ||||||
|  | 8 : dc8211b4ce122f87692e7c203672e3eb1ffc44c0a307eafcc560323fcc5fae78 | ||||||
|  | 9 : 59e2d8e11cad287eacf3207e64a373f65059286b803ef0981510193ae29cbc8c | ||||||
|  | --------------------------------------------------------------- | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ---ETH--- | ||||||
| 
 | 
 | ||||||
| ### Get Wallet Info | ### Get Wallet Info | ||||||
| 
 | 
 | ||||||
| @ -139,58 +221,7 @@ Wallet Info: | |||||||
| 
 | 
 | ||||||
| Try out other commands like `getblockchaininfo`, `getnetworkinfo`, `getpeerinfo`, `getblockchaininfo`, etc. | Try out other commands like `getblockchaininfo`, `getnetworkinfo`, `getpeerinfo`, `getblockchaininfo`, etc. | ||||||
| 
 | 
 | ||||||
| ### Exploring a Block |  | ||||||
| 
 | 
 | ||||||
| Let's explore a block on the testnet. First we get the blockhash of a block we want so that we ask bitcoind to return the details of that block. Then we print some details of that block along with a few transactions. |  | ||||||
| 
 |  | ||||||
| ```py |  | ||||||
| blockhash_630000 = rpc_client.getblockhash(630000) |  | ||||||
| block_630000 = rpc_client.getblock(blockhash_630000) |  | ||||||
| nTx = block_630000['nTx'] |  | ||||||
| if nTx > 10: |  | ||||||
|     it_txs = 10 |  | ||||||
|     list_tx_heading = "First 10 transactions: " |  | ||||||
| else: |  | ||||||
|     it_txs = nTx |  | ||||||
|     list_tx_heading = f"All the {it_txs} transactions: " |  | ||||||
| print("---------------------------------------------------------------") |  | ||||||
| print("BLOCK No. 630000 :") |  | ||||||
| print("-------------") |  | ||||||
| print("Block Hash...: ", blockhash_630000) |  | ||||||
| print("Merkle Root..: ", block_630000['merkleroot']) |  | ||||||
| print("Block Size...: ", block_630000['size']) |  | ||||||
| print("Block Weight.: ", block_630000['weight']) |  | ||||||
| print("Nonce........: ", block_630000['nonce']) |  | ||||||
| print("Difficulty...: ", block_630000['difficulty']) |  | ||||||
| print("Number of Tx.: ", nTx) |  | ||||||
| print(list_tx_heading) |  | ||||||
| print("---------------------") |  | ||||||
| i = 0 |  | ||||||
| while i < it_txs: |  | ||||||
|     print(i, ":", block_630000['tx'][i]) |  | ||||||
|     i += 1 |  | ||||||
| print("---------------------------------------------------------------\n") |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| You should see the following output: |  | ||||||
| 
 |  | ||||||
| ```sh |  | ||||||
| --------------------------------------------------------------- |  | ||||||
| BLOCK No. 630000 : |  | ||||||
| ------------- |  | ||||||
| Block Hash...:  0000000000007c21a9190d3eb43517032ba0077229cbff4e6a2a43357011bebb |  | ||||||
| Merkle Root..:  a8dc7bf722a4ca6869d99fea465fc65dbf68df07026a4142f4b8213d3749ed7f |  | ||||||
| Block Size...:  4519 |  | ||||||
| Block Weight.:  18076 |  | ||||||
| Nonce........:  265038597 |  | ||||||
| Difficulty...:  126320.64 |  | ||||||
| Number of Tx.:  3 |  | ||||||
| All the 3 transactions: |  | ||||||
| --------------------- |  | ||||||
| 0 : b4d2c5442554ebcdfcbf08a71cf2c510d21acac48f93fc2802b8bc52c5cebfeb |  | ||||||
| 1 : c3f8177522be84bc023e61e53b9bbff674e1f825fc9d68c3f4c2e21a2161d5a9 |  | ||||||
| 2 : 4ab80958fea242285056ffcf88f7d65b65d357f761796104109839ad7da2255f |  | ||||||
| --------------------------------------------------------------- |  | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Exploring an Address | ## Exploring an Address | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user