edgecase_datafeed 189 2020-11-05 This is the date at the time of creation of this datafeed article. A checkpoint article containing a hash of this datafeed article may be created on this date or at a later date. 144 9 2020-05-28 bitcoin b27618deae05910f529240cc6960aeb87f017b12d302327253ee893825ce2bd4 632100 1HtwyqFWNVDoSEVqZwjBRRAV2oEsi8aQXr 13MfGs39pR5aEK4iKdoLjVYXKwi6Y3uyPq
Generating_a_standard_Bitcoin_address_#2 stjohn_piano 2020-11-03 yes GOAL Develop a tool for generating a Bitcoin address from a private key. This tool should have a good command-line interface and a test suite. CONTENTS - Goal - Contents - Summary - Downloadable Assets - How To Use The Tools - Project Log SUMMARY I developed: - a tool for deriving a Bitcoin address from a private key. - an accompanying test suite. The tool has a useful command-line interface. Please see the Downloadable Assets section for the tool and the test suite, and the How To Use The Tools section for instructions and examples. DOWNLOADABLE ASSETS Assets of this article: List: - private_key_to_address.py - test_private_key_to_address.py Asset: A tool that derives a Bitcoin address from a private key. Python 2.7.12. asset private_key_to_address.py private_key_to_address.py dc6da10180110faf728902eecc6c39da86312a7e82c2966b950cdf54a6a1ecaa Asset: A test suite for the derivation tool. Python 2.7.12, Pytest 4.6.11. asset test_private_key_to_address.py test_private_key_to_address.py 83b6d3501d7b8c7bee6101741b9317076f460a22feda76c0e3196f884c12678d Assets of other articles: List: - bitcoin_functions_2.py - bjorn_edstrom_ripemd160.py - ecdsa-0.10.tar.gz - pypy_sha256.py Asset: A library of functions for handling standard Bitcoin data types. Python 2.7. asset_of_another_article Creating_a_Bitcoin_transaction_with_two_outputs edgecase 85 bitcoin_functions_2.py bitcoin_functions_2.py 653f38ebab7f7c176ce7925364b5916c32b8e97ab5d4c00a66b990a0b6e0074c Asset: An implementation of RIPEMD-160, written by B_j_o:r_n_ E_d_s_t_r_o:m_. Python 2.7. asset_of_another_article Reading_and_verifying_a_standard_raw_bitcoin_transaction edgecase 51 bjorn_edstrom_ripemd160.py bjorn_edstrom_ripemd160.py a5ca6eb289989861e30806ff7e39165622bd366a1c6cd5edd2dbd7dfc4877666 Asset: A Python implementation of ECDSA cryptography, written by Peter Pearson. Python 2.7. asset_of_another_article Reading_and_verifying_a_standard_raw_bitcoin_transaction edgecase 51 ecdsa-0.10.tar.gz ecdsa-0.10.tar.gz 67dae9e1af2b0fd71bc9a378654f7dc89211c1c5aee71e160f8cfce1fa6d6980 Asset: A Python implementation of SHA256. Author unknown. Python 2.7. asset_of_another_article Reading_and_verifying_a_standard_raw_bitcoin_transaction edgecase 51 pypy_sha256.py pypy_sha256.py 2bbd4a83b69625e2f7ece5201475af2803f0ea11f3815c83d8afab3773d8f47b Dependency tree: - test_private_key_to_address.py -- private_key_to_address.py --- bitcoin_functions_2.py ---- bjorn_edstrom_ripemd160.py ---- ecdsa-0.10.tar.gz ---- pypy_sha256.py HOW TO USE THE TOOLS Help: python private_key_to_address.py --help Main: python private_key_to_address.py -f privateKey.txt Note: By default, the tool looks for a file named 'privateKey.txt' in its local directory, so in the above command the filepath argument is optional. python private_key_to_address.py Test: pytest -q test_private_key_to_address.py Note: The test suite file needs to be in the same directory as the tool file. Examples: stjohn@judgement:work$ python private_key_to_address.py --privateKeyFilePath privateKey.txt 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT [same as above, but in shorthand] stjohn@judgement:work$ python private_key_to_address.py -f privateKey.txt 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ cat privateKey.txt 089f7ffa2076aeb36d09a0d095296116cf6e3a93a1fcce0ca31e7628c43001d8 [default privateKey filepath is 'privateKey.txt'.] stjohn@judgement:work$ python private_key_to_address.py 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ python private_key_to_address.py --privateKeyString 089f7ffa2076aeb36d09a0d095296116cf6e3a93a1fcce0ca31e7628c43001d8 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ python private_key_to_address.py -f privateKey.txt --debug INFO [92: deriveBitcoinAddress] Private key: 089f7ffa2076aeb36d09a0d095296116cf6e3a93a1fcce0ca31e7628c43001d8 INFO [94: deriveBitcoinAddress] Private key (WIF): 5Ht5r13wvzsUJKPoqCasYH1hpBCjKMgQkXE4e538CcQLHum2Uyz INFO [96: deriveBitcoinAddress] Bitcoin address: 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ pytest -q test_private_key_to_address.py ........................ [100%] 24 passed in 2.94 seconds PROJECT LOG The article Edgecase_Bitcoin_Storage_Toolset_version_2 edgecase 148 Edgecase Bitcoin Storage Toolset version 2 already contains a tool for generating a bitcoin address from a private key, called: generate_bitcoin_address_4.py I'll reuse the underlying code from it and its dependencies. The previous project article Generating_entropy_from_dice_#2 edgecase 188 Generating entropy from dice #2 contains an good command-line tool and test suite. I'll use the same approach. Work machine: - Name: Judgement - Windows 10 - Windows Subsystem for Linux (WSL): Ubuntu 16.04 - I'm working in the WSL Ubuntu terminal. My Python version: stjohn@judgement:work$ python --version Python 2.7.12 My Pytest version: stjohn@judgement:work$ pytest --version This is pytest version 4.6.11, imported from /home/stjohn/.local/lib/python2.7/site-packages/pytest.pyc Create a project directory, called: "generating_a_standard_bitcoin_address_2" Browse to the linked EBSTv2 article and download the various assets for the address generation tool. Dependency tree: - generate_bitcoin_address_4.py -- bitcoin_functions_2.py --- bjorn_edstrom_ripemd160.py --- ecdsa-0.10.tar.gz --- pypy_sha256.py Create a new directory named "work" in the project directory. Unpack the zipped tape archive file ecdsa-0.10.tar.gz, by opening a terminal, changing directory to the work directory, and running the following command: tar -zxvf ecdsa-0.10.tar.gz This unpacking produced a new directory named "ecdsa-0.10" in the work directory. The directory "ecdsa-0.10" contains a directory named "ecdsa". Copy the "ecdsa" directory into the work directory, using the following command: cp -r ecdsa-0.10/ecdsa . Delete ecdsa-0.10 and ecdsa-0.10.tar.gz. I'll use the data from the previous project article Bitcoin_address_test_set edgecase 146 Bitcoin address test set when writing tests. [development work occurs here.] I've written a tool for generating a bitcoin address from a private key, and an accompanying test suite: - private_key_to_address.py - test_private_key_to_address.py Let's record some examples of using private_key_to_address.py stjohn@judgement:work$ python private_key_to_address.py --help usage: private_key_to_address.py [-h] [-f PRIVATEKEYFILEPATH] [-p PRIVATEKEYSTRING] [-l {debug,info,warning,error}] [-d] Derive a Bitcoin address from a Bitcoin private key. optional arguments: -h, --help show this help message and exit -f PRIVATEKEYFILEPATH, --privateKeyFilePath PRIVATEKEYFILEPATH path to file containing the private key (default: 'privateKey.txt'). -p PRIVATEKEYSTRING, --privateKeyString PRIVATEKEYSTRING private key passed as a direct argument. This overrides --privateKeyFilePath. -l {debug,info,warning,error}, --logLevel {debug,info,warning,error} Choose logging level (default: 'error'). -d, --debug Sets logLevel to 'debug'. This overrides --logLevel. Supplementary Notes: - A standard Bitcoin address is an uncompressed single-signature Pay-To-Public-Key-Hash (P2PKH) address. - A Bitcoin private key is a sequence of 32 bytes. In hex, 1 byte is written as two characters. So, a private key written in hex is 64 characters. -- Example: 089f7ffa2076aeb36d09a0d095296116cf6e3a93a1fcce0ca31e7628c43001d8 stjohn@judgement:work$ cat privateKey.txt 089f7ffa2076aeb36d09a0d095296116cf6e3a93a1fcce0ca31e7628c43001d8 stjohn@judgement:work$ python private_key_to_address.py --privateKeyFilePath privateKey.txt 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT [same, but in shorthand] stjohn@judgement:work$ python private_key_to_address.py -f privateKey.txt 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT [Note: By default, the tool looks for a file named 'privateKey.txt' in its local directory, so the filepath argument is optional.] stjohn@judgement:work$ python private_key_to_address.py 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ python private_key_to_address.py --privateKeyString 089f7ffa2076aeb36d09a0d095296116cf6e3a93a1fcce0ca31e7628c43001d8 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT [same, but in shorthand] stjohn@judgement:work$ python private_key_to_address.py -p 089f7ffa2076aeb36d09a 0d095296116cf6e3a93a1fcce0ca31e7628c43001d8 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ python private_key_to_address.py -f privateKey.txt --debug INFO [92: deriveBitcoinAddress] Private key: 089f7ffa2076aeb36d09a0d095296116cf6e3a93a1fcce0ca31e7628c43001d8 INFO [94: deriveBitcoinAddress] Private key (WIF): 5Ht5r13wvzsUJKPoqCasYH1hpBCjKMgQkXE4e538CcQLHum2Uyz INFO [96: deriveBitcoinAddress] Bitcoin address: 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ python private_key_to_address.py -f privateKey.txt --logLevel=info - Private key: 089f7ffa2076aeb36d09a0d095296116cf6e3a93a1fcce0ca31e7628c43001d8 - Private key (WIF): 5Ht5r13wvzsUJKPoqCasYH1hpBCjKMgQkXE4e538CcQLHum2Uyz - Bitcoin address: 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT And some examples of testing the tool. stjohn@judgement:work$ pytest test_private_key_to_address.py ============================= test session starts ============================== platform linux2 -- Python 2.7.12, pytest-4.6.11, py-1.9.0, pluggy-0.13.1 rootdir: /mnt/c/Users/User/Desktop/stuff/articles/generating_a_standard_bitcoin_address_2/work collected 24 items test_private_key_to_address.py ........................ [100%] ========================== 24 passed in 1.52 seconds =========================== stjohn@judgement:work$ pytest test_private_key_to_address.py --quiet ........................ [100%] 24 passed in 1.44 seconds stjohn@judgement:work$ pytest test_private_key_to_address.py::test_one --quiet . [100%] 1 passed in 0.03 seconds stjohn@judgement:work$ pytest -o log_cli=true --log-cli-level=DEBUG --log-format="%(levelname)s [%(lineno)s: %(funcName)s] %(message)s" test_private_key_to_address.py::test_one ============================= test session starts ============================== platform linux2 -- Python 2.7.12, pytest-4.6.11, py-1.9.0, pluggy-0.13.1 rootdir: /mnt/c/Users/User/Desktop/stuff/articles/generating_a_standard_bitcoin_address_2/work collected 1 item test_private_key_to_address.py::test_one -------------------------------- live log call --------------------------------- INFO [92: deriveBitcoinAddress] Private key: 0000000000000000000000000000000000000000000000000000000000000001 INFO [94: deriveBitcoinAddress] Private key (WIF): 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf INFO [96: deriveBitcoinAddress] Bitcoin address: 1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm PASSED [100%] =========================== 1 passed in 0.05 seconds =========================== stjohn@judgement:work$ pytest -o log_cli=true --log-cli-level=DEBUG --log-format="%(levelname)s [%(lineno)s: %(funcName)s] %(message)s" test_private_key_to_address.py::test_pair_1 ============================= test session starts ============================== platform linux2 -- Python 2.7.12, pytest-4.6.11, py-1.9.0, pluggy-0.13.1 rootdir: /mnt/c/Users/User/Desktop/stuff/articles/generating_a_standard_bitcoin_address_2/work collected 1 item test_private_key_to_address.py::test_pair_1 -------------------------------- live log call --------------------------------- INFO [92: deriveBitcoinAddress] Private key: 0000000000000000000000007468655f6c6962726172795f6f665f626162656c INFO [94: deriveBitcoinAddress] Private key (WIF): 5HpHagT65TZzG1PH3CdWbVZG75U59A8FphH7EtKwbFCZf3p6bjg INFO [96: deriveBitcoinAddress] Bitcoin address: 1CTumCMjzBfccCJBTkHoPQmAwEqU9Uj2sQ PASSED [100%] =========================== 1 passed in 0.11 seconds =========================== Good. That's the end of this project. List of previous tools for deriving Bitcoin addresses from private keys, together with the projects in which they were published: Tool 1: asset_of_another_article Generating_a_standard_Bitcoin_address edgecase 54 generate_bitcoin_address.py generate_bitcoin_address.py 70f1288a5957ffc02dd43625446043b27c4132c02a609ea959a574f7ff6af563 Project: article Generating_a_standard_Bitcoin_address edgecase 54 Generating a standard Bitcoin address Tool 2: asset_of_another_article Verifying_a_signed_deed_of_the_GPG_1.4.10_source_code edgecase 60 generate_bitcoin_address_2.py generate_bitcoin_address_2.py 18be6cc5c66f9f672bf2247184b416340a9309de789f9737714d17efffb67a4e Project: article Verifying_a_signed_deed_of_the_GPG_1.4.10_source_code edgecase 60 Verifying a signed deed of the GPG 1.4.10 source code Tool 3: asset_of_another_article Creating_and_signing_a_standard_raw_Bitcoin_transaction:_Iteration_#2 edgecase 63 generate_bitcoin_address_3.py generate_bitcoin_address_3.py b18c438fe479095eff17702c52968309351b6e5f9d147758ce5924b116f5a8ef Project: article Creating_and_signing_a_standard_raw_Bitcoin_transaction:_Iteration_#2 edgecase 63 Creating and signing a standard raw Bitcoin transaction: Iteration #2 Tool 4: asset_of_another_article Edgecase_Bitcoin_Storage_Toolset_version_2 edgecase 148 generate_bitcoin_address_4.py generate_bitcoin_address_4.py f8fad8e3c31555b9ff309d52fca360a9e22ea0f8b3689bfa9fc8e6370339f456 Project: article Edgecase_Bitcoin_Storage_Toolset_version_2 edgecase 148 Edgecase Bitcoin Storage Toolset version 2
iQIcBAABCgAGBQJfo92nAAoJEC8RP+HmG9MX6OgP/0Z0aqufmfR2i6RWAzKoWlXy NwI02O2p7AtybNSKAkrkwD+nI67aUdH94zqTvFzjBXdDFM78rxefORtTwZL2jcAl Qk6eRiyDDkiWijCGImcwBvSnF3ULdjm0+ooBIuzBEOCI508KClnSNfHFGPXT+Mlo Ge3uM+fgo3aY2autNijtrnmlsLVbz9LBwLx8HOtD8e7EIXv/jRM/RPEfd/P5C7VE UvXId7M4jpNJaVA9Spy+PE3fjzCE6TKNtYv/M6fsG0zai4wlO4Z/mpnDGOCSk1A2 mm9BO9E9xo7glTo7D6SizwZzGxWDOXrJnC+QqTp7Y/6uZJspBr+1Ksl+VHCF3etJ DG7gYuZfLIsrloK2M5MuMXFELsrMlumhySemHtWqNkW1Hwg0cmp4K7/addt+roxE bAmecyapNyWDdoaAGjqq5vpGzLRImkmCUKqmIhNePf+5RD5VeQBO5NDwKDD0/uXF cUleaONiFqyA5EbaYEGYsR5f646vOXXWdDNjJmQTNSz4wCqDhU7sHQDPVSX7lrF4 20oxROYzT8C43rpnlL4W/Vp47QV4L3Ruo/Cb1spAWTnoJDcftCZYrWDSRfsQGz+I aySgENzf6v+1oWfZ3ukdffSfP17mPPs3vk/2gPjtGZLq2f5lafz/jKQ/EPf6VId6 Ezohq9RIuLXuln5jEbN1 =wTeG
iQIcBAABCgAGBQJfo935AAoJECL1OzZgiBhw5zEP/AxZuMIPBt3DLtoGcmcTFF2G iyBgVNm2OAcFBxPD7yy43nWABtvEqAQpvKPDpBjThtlaOAf8uUZ+Dsbd63wU78LY aOgwQLImZWXm+HbU8PEpeSXUe1+ti1/eX+xt8A3BYtazTcv6wFlo9oWhQZvgrucF tOLF3fI+7KXSsXRUMwtPvUTAmZCRtgqEhjTKg8ymvn3vsETDTP/WDQnLGRXeJ4Aw iWAQ53NF4/+smKN8v6qQbUEgretFqTKacISMxQcD3TgvtWS/Zo2RQkhZwIXmLfQv 5+8+8YPKPHz30b0kiqkjrD4I0DMySl5vhl4bBh7sALcz74gajp8yyeJ5CaCSj0yT 6jnjjTRB38RL21pA7rLDi+vosJHHgVP71EUsBtjIShfoziT6WuXBhRRcHgpBREAS +qq8j7uyYWAirn6TuDbIDIbRgvvdo4vK+HO3zsM020sC6zCEQHqNO/w4oanLNgvR sKl4zLF5ujCzwyc2/qGH19aEjBQSTOBASXOglD1SZTxpq/fd1cE+nHq2rNf0ZyMu 3t+JW5/SFjRAo7Xmy2aRFvkZqMYiayQU6g8L1hGxbZquEVindKAR2jwhSwIAH5zg wYBJfQ8iMEE0+c3zZKA6rZPnReDzGQQkCRZvsTsRJGNeG+DI7SwqTfP1F1hPVd9C hkn+a6zlRwLjEEByovKh =NMNU