edgecase_datafeed 192 2020-11-10 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
Validating_a_standard_Bitcoin_address stjohn_piano 2020-11-10 yes GOAL Develop a tool for validating a standard Bitcoin address. 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 validating 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: - validate_address.py - test_validate_address.py Asset: A tool that validates a Bitcoin address from a private key. Python 2.7.12. asset validate_address.py validate_address.py 0155782d74eb16202eda0c05067e0ec6c4cf839062e619c261627b15d621c7ee Asset: A test suite for the validation tool. Python 2.7.12, Pytest 4.6.11. asset test_validate_address.py test_validate_address.py 95d445cc5cb951ae9a4219212a5828d0122051c167a041bebd836c7ddb89e672 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_validate_address.py -- validate_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 validate_address.py --help Main: python validate_address.py -f address.txt Note: By default, the tool looks for a file named 'address.txt' in its local directory, so in the above command the filepath argument is optional. python validate_address.py Test: pytest -q test_validate_address.py Note: The test suite file needs to be in the same directory as the tool file. Examples: stjohn@judgement:work$ python validate_address.py --addressFilePath address.txt [same as above, but in shorthand] stjohn@judgement:work$ python validate_address.py -f address.txt stjohn@judgement:work$ cat address.txt 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT [default address filepath is 'address.txt'] stjohn@judgement:work$ python validate_address.py stjohn@judgement:work$ python validate_address.py --addressString 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ python validate_address.py --addressString 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT --debug INFO [81: validateBitcoinAddress] Address: 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT DEBUG [89: validateBitcoinAddress] Number of leading '1' characters: 1 DEBUG [92: validateBitcoinAddress] base10 value inside address: 6230568508398901441201089632142185462656304983477985328510 INFO [95: validateBitcoinAddress] Address value in hex: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa39adbd7e INFO [100: validateBitcoinAddress] Checksum: 39adbd7e DEBUG [102: validateBitcoinAddress] Address value in hex without checksum: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa DEBUG [105: validateBitcoinAddress] Address value with leading zero bytes added back on: 00fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa DEBUG [108: validateBitcoinAddress] Recalculated checksum: 39adbd7e DEBUG [115: validateBitcoinAddress] versionByte: 00 INFO [120: validateBitcoinAddress] publicKeyHash: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa INFO [124: validateBitcoinAddress] Address 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT validated. No problems found. [invalid address - last character has been changed from 'T' to 'S'.] stjohn@judgement:work$ python validate_address.py --addressString 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbS Traceback (most recent call last): File "validate_address.py", line 172, in \ main() File "validate_address.py", line 69, in main validateBitcoinAddress(args.addressString) File "validate_address.py", line 112, in validateBitcoinAddress raise ValueError(msg) ValueError: Recalculated checksum (39adbd7d) does not match original checksum (39adbd7e). stjohn@judgement:work$ pytest -q test_validate_address.py .................... [100%] 20 passed in 0.08 seconds PROJECT LOG This project is going to be very similar to article Generating_a_standard_Bitcoin_address_#2 edgecase 189 Generating a standard Bitcoin address #2 . My working definition of a standard Bitcoin address: - An uncompressed single-signature Pay-To-Public-Key-Hash (P2PKH) address. Standard addresses start with the character '1'. Example standard Bitcoin address (34 characters): 1AGygbyEFYduWkkmZbbvirgS9kuBBMLJCP 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: "validating_a_standard_bitcoin_address" Relevant: In the previous project article Generating_a_standard_Bitcoin_address edgecase 54 Generating a standard Bitcoin address , in the Notes / Discoveries section, there is a part named "Algorithm for generating a Bitcoin address". Relevant: In the previous project article Creating_and_signing_a_standard_raw_Bitcoin_transaction edgecase 56 Creating and signing a standard raw Bitcoin transaction , in the Notes / Discoveries section, there is a part named "Algorithm for deriving the public key hash from a standard Bitcoin address". Browse to article Edgecase_Bitcoin_Storage_Toolset_version_2 edgecase 148 Edgecase Bitcoin Storage Toolset version 2 and download the following assets: Dependency tree: - bitcoin_functions_2.py -- bjorn_edstrom_ripemd160.py -- ecdsa-0.10.tar.gz -- pypy_sha256.py bitcoin_functions_2.py contains various functions that I'll use in this project. - One in particular, base58check_to_hex, is very close to what I want for this project. Create a new directory named "work" in the project directory. Move the downloaded assets into the work 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. List of things to validate: - The address begins with a '1' character. - The public key hash that it contains is 20 characters. - The double-SHA256 checksum at the end is 4 characters. - The checksum is correct. [development work occurs here.] I've written a tool for validating a bitcoin address, and an accompanying test suite: - validate_address.py - test_validate_address.py Let's record some examples of using validate_address.py stjohn@judgement:work$ python validate_address.py -h usage: validate_address.py [-h] [-f ADDRESSFILEPATH] [-s ADDRESSSTRING] [-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 ADDRESSFILEPATH, --addressFilePath ADDRESSFILEPATH path to file containing the address (default: 'address.txt'). -s ADDRESSSTRING, --addressString ADDRESSSTRING address passed as a direct argument. This overrides --addressFilePath. -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. - Standard addresses start with the character '1'. - Example standard Bitcoin address (34 characters): 1AGygbyEFYduWkkmZbbvirgS9kuBBMLJCP stjohn@judgement:work$ python validate_address.py --addressString 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ python validate_address.py --addressString 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT --debug INFO [81: validateBitcoinAddress] Address: 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT DEBUG [89: validateBitcoinAddress] Number of leading '1' characters: 1 DEBUG [92: validateBitcoinAddress] base10 value inside address: 6230568508398901441201089632142185462656304983477985328510 INFO [95: validateBitcoinAddress] Address value in hex: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa39adbd7e INFO [100: validateBitcoinAddress] Checksum: 39adbd7e DEBUG [102: validateBitcoinAddress] Address value in hex without checksum: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa DEBUG [105: validateBitcoinAddress] Address value with leading zero bytes added back on: 00fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa DEBUG [108: validateBitcoinAddress] Recalculated checksum: 39adbd7e DEBUG [115: validateBitcoinAddress] versionByte: 00 INFO [120: validateBitcoinAddress] publicKeyHash: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa INFO [124: validateBitcoinAddress] Address 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT validated. No problems found. stjohn@judgement:work$ cat address.txt 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT stjohn@judgement:work$ python validate_address.py --addressFilePath address.txt stjohn@judgement:work$ python validate_address.py -f address.txt stjohn@judgement:work$ python validate_address.py -f address.txt --logLevel=info - Address: 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT - Address value in hex: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa39adbd7e - Checksum: 39adbd7e - publicKeyHash: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa - Address 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT validated. No problems found. And some examples of testing the tool. stjohn@judgement:work$ pytest test_validate_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/validating_a_bitcoin_address/work collected 20 items test_validate_address.py .................... [100%] ========================== 20 passed in 0.13 seconds =========================== stjohn@judgement:work$ pytest test_validate_address.py -q .................... [100%] 20 passed in 0.08 seconds stjohn@judgement:work$ pytest test_validate_address.py::test_valid_address ============================= 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/validating_a_bitcoin_address/work collected 1 item test_validate_address.py . [100%] =========================== 1 passed in 0.04 seconds =========================== stjohn@judgement:work$ pytest -o log_cli=true --log-cli-level=DEBUG --log-format="%(levelname)s [%(lineno)s: %(funcName)s] %(message)s" test_validate_address.py::test_valid_address ============================= 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/validating_a_bitcoin_address/work collected 1 item test_validate_address.py::test_valid_address -------------------------------- live log call --------------------------------- INFO [81: validateBitcoinAddress] Address: 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT DEBUG [89: validateBitcoinAddress] Number of leading '1' characters: 1 DEBUG [92: validateBitcoinAddress] base10 value inside address: 6230568508398901441201089632142185462656304983477985328510 INFO [95: validateBitcoinAddress] Address value in hex: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa39adbd7e INFO [100: validateBitcoinAddress] Checksum: 39adbd7e DEBUG [102: validateBitcoinAddress] Address value in hex without checksum: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa DEBUG [105: validateBitcoinAddress] Address value with leading zero bytes added back on: 00fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa DEBUG [108: validateBitcoinAddress] Recalculated checksum: 39adbd7e DEBUG [115: validateBitcoinAddress] versionByte: 00 INFO [120: validateBitcoinAddress] publicKeyHash: fe1a2ba2103e4b61d8ad73a980cc47626ae6a0aa INFO [124: validateBitcoinAddress] Address 1QAZz5b4MzqG64Loq3qsvAQiwHqweY7mbT validated. No problems found. PASSED [100%] =========================== 1 passed in 0.04 seconds =========================== Good. That's the end of this project.
iQIcBAABCgAGBQJfqtu7AAoJEC8RP+HmG9MXFTEQALlgZO9MxUZ4f/vl2WlNq++5 db/LejBbe/jk3GkrvUFxeZ8m/9gnPCfcO2BxKuKzSJakc7WsDy4CdPPqeI1DCKCq 1DlTM+0uvpnwtgL419v1YPEMO0fBEV5q7ZExFbCWoEWRod04Dh0sHnVXx+T719/4 ZIaAsSGydp6BPKr+R1s7EErGER+15uUzM05z8K7OZ3pttq+YyrNOvhbwMb6d0Aed UlfCQ1256z4at95ziQDYM9Fi6MALjR/zbCj9Pzj3XObxVmNljnSBk+aprJXY1W0g Pt9AUMSVOgUdCslGH+ZZhTJmqqVp3ceLm9A5YWNuC2ceyscVoalmgBCaX8emity2 keR6KDwTEwF+KH/tFcZPS43o8vfcdO8hxEMhhefXvGQ9BASQ7EgwZwpu0D8H1GLc INZLyCGKIL60062Yw+0/Mfr4AniWuDNYGfIVDSPMw3WEWcB0TydPIgxAgzCtLiyM eTQNslj6aN9UdFPgyhqKIIGxQYoqNjt7IGuXW7QEyKb7LCOdJwHv0sIg9CN8ViAh IH0eD2EwXjOxcLIl19DxLI9XozZX2ZzLPOiNFd1wJ4Vb4Ta7zx58bCzyZgR0087D JEzbyh2uUDmwDIcTnUn0+9MK1DbbHYRau/IZ3X+F5Bti3swpQeQdPzgF2ugD4l0B AaZjWW3ufWrS4rRgMjOT =1lwP
iQIcBAABCgAGBQJfqtxhAAoJECL1OzZgiBhwejMP/An1wdyM+N8Ay8Z8608UeHKD uGEtSmYMlBa2zd504CuIKbiIgCUiao5bu3v8kwSy+Y8Pfc/+/dWEc3010rCJlBNz 2ocavO3BF+qplDmxc/1/RgRA0KjAdQyraZOe9wSHQeZOO2CBOq8h06vCrg4KoIux 3WbGdXCsorpV6k41SU1tJx+iwBfnDOXSJUy4uYPvYd79eIFYYGcjN13A8N+rrwzk b4UoZtoj/P9qa1zPMroi3GW/ZybeszezA7h90PP7fo+3PYdu08ALAQsx5nxSzzA/ 1HUvTSoAur7/VBglMJE+o7Y+ExpyrT0NqFkExDER5H6+6nMlGo863abtWWvYJ7fV Nk/TWOm9wWU6JCmZxKu/SyTWgUiCVe+E4AQBa4RHnLbaduYTIv3HUnwbs2/27mF4 LTWSVZVHO3tBAQy3aeRYMyrEQWUv7Rw05dhTsyUFALSlYrKQ1f83IdJ2xHNu0ZnN 59wifJFnu2W1iL0FDAsmHSEsg7zeaA0rmkpG10n06fQQ3mdtlmjfaAJ0M5TsLvds /bTanbWF8AT/rgB2o95TYJ9CvqIJuYVoCGlmnD93LQbJBL9Mx9jdbU8pLcYh865d 0WOwJBfoyZ29SSTEBqGkzWhwCUMq3UN3Nsqz1xyWLcxPZDqH44esOEzaSsfVMCBC 6VWoeynEZYR1tCWmxyxJ =R3V8