def test_tools_clw_transaction_with_script(self): cmd_wlt_create = '%s %s test2 --passphrase "emotion camp sponsor curious bacon squeeze bean world ' \ 'actual chicken obscure spray" -r -n bitcoinlib_test -d %s' % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) cmd_wlt_update = "%s %s test2 -d %s" % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) cmd_wlt_transaction = "%s %s test2 -d %s -t 21HVXMEdxdgjNzgfERhPwX4okXZ8WijHkvu 50000000 -f 100000 -p" % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) cmd_wlt_delete = "%s %s test2 --wallet-remove -d %s" % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) output_wlt_create = "21GPfxeCbBunsVev4uS6exPhqE8brPs1ZDF" output_wlt_transaction = 'Transaction pushed to network' output_wlt_delete = "Wallet test2 has been removed" process = Popen(cmd_wlt_create, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'y') self.assertIn(output_wlt_create, normalize_string(poutput[0])) process = Popen(cmd_wlt_update, stdout=PIPE, shell=True) process.communicate() process = Popen(cmd_wlt_transaction, stdout=PIPE, shell=True) poutput = process.communicate() self.assertIn(output_wlt_transaction, normalize_string(poutput[0])) process = Popen(cmd_wlt_delete, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'test2') self.assertIn(output_wlt_delete, normalize_string(poutput[0]))
def test_tools_clw_create_wallet(self): cmd_wlt_create = "echo y | %s %s test --passphrase 'emotion camp sponsor curious bacon squeeze bean world " \ "actual chicken obscure spray' -r -d %s" % \ (self.python_executable, self.clw_executable, DATABASEFILE_UNITTESTS) cmd_wlt_delete = "echo test | %s %s test --wallet-remove -d %s" % \ (self.python_executable, self.clw_executable, DATABASEFILE_UNITTESTS) output_wlt_create = "Receive address(es):\n14guS7uQpEbgf1e8TDo1zTEURJW3NGPc9E" output_wlt_delete = "Wallet test has been removed" self.assertIn(output_wlt_create, normalize_string(check_output(cmd_wlt_create, shell=True))) self.assertIn(output_wlt_delete, normalize_string(check_output(cmd_wlt_delete, shell=True)))
def test_tools_clw_create_litecoin_segwit_wallet(self): cmd_wlt_create = '%s %s ltcsw --passphrase "lounge chief tip frog camera build trouble write end ' \ 'sword order share" -r -d %s -y segwit -n litecoin' % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) cmd_wlt_delete = "%s %s ltcsw --wallet-remove -d %s" % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) output_wlt_create = "ltc1qgc7c2z56rr4lftg0fr8tgh2vknqc3yuydedu6m" output_wlt_delete = "Wallet ltcsw has been removed" process = Popen(cmd_wlt_create, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'y') self.assertIn(output_wlt_create, normalize_string(poutput[0])) process = Popen(cmd_wlt_delete, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'ltcsw') self.assertIn(output_wlt_delete, normalize_string(poutput[0]))
def test_tools_clw_create_wallet(self): cmd_wlt_create = '%s %s test --passphrase "emotion camp sponsor curious bacon squeeze bean world ' \ 'actual chicken obscure spray" -r -d %s' % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) cmd_wlt_delete = "%s %s test --wallet-remove -d %s" % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) output_wlt_create = "14guS7uQpEbgf1e8TDo1zTEURJW3NGPc9E" output_wlt_delete = "Wallet test has been removed" process = Popen(cmd_wlt_create, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'y') self.assertIn(output_wlt_create, normalize_string(poutput[0])) process = Popen(cmd_wlt_delete, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'test') self.assertIn(output_wlt_delete, normalize_string(poutput[0]))
def test_tools_clw_create_multisig_wallet_error(self): cmd_wlt_create = "%s %s testms2 -m 2 a -d %s" % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) output_wlt_create = "Number of signatures required (second argument) must be a numeric value" process = Popen(cmd_wlt_create, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'y') self.assertIn(output_wlt_create, normalize_string(poutput[0]))
def detect_language(words): """ Detect language of given phrase >>> Mnemonic().detect_language('chunk gun celery million wood kite tackle twenty story episode raccoon dutch') 'english' :param words: List of space separated words :type words: str :return str: Language """ words = normalize_string(words) if isinstance(words, TYPE_TEXT): words = words.split(' ') wlcount = {} for fn in os.listdir(BCL_WORDLIST_DIR): if fn.endswith(".txt"): with open(os.path.join(BCL_WORDLIST_DIR, fn)) as f: wordlist = [w.strip() for w in f.readlines()] language = fn.split('.')[0] wlcount[language] = 0 for word in words: if sys.version < '3': word = word.encode('utf-8') if word in wordlist: wlcount[language] += 1 detlang = max(wlcount.keys(), key=(lambda key: wlcount[key])) if not wlcount[detlang]: raise Warning("Could not detect language of Mnemonic sentence %s" % words) return detlang
def to_mnemonic(self, data, add_checksum=True, check_on_curve=True): """ Convert key data entropy to Mnemonic sentence >>> Mnemonic().to_mnemonic('28acfc94465fd2f6774759d6897ec122') 'chunk gun celery million wood kite tackle twenty story episode raccoon dutch' :param data: Key data entropy :type data: bytes, hexstring :param add_checksum: Included a checksum? Default is True :type add_checksum: bool :param check_on_curve: Check if data integer value is on secp256k1 curve. Should be enabled when not testing and working with crypto :type check_on_curve: bool :return str: Mnemonic passphrase consisting of a space seperated list of words """ data = to_bytes(data) data_int = change_base(data, 256, 10) if check_on_curve and not 0 < data_int < secp256k1_n: raise ValueError( "Integer value of data should be in secp256k1 domain between 1 and secp256k1_n-1" ) if add_checksum: binresult = change_base(data_int, 10, 2, len(data) * 8) + self.checksum(data) wi = change_base(binresult, 2, 2048) else: wi = change_base(data_int, 10, 2048, len(data) // 1.375 + len(data) % 1.375 > 0) return normalize_string(' '.join([self._wordlist[i] for i in wi]))
def detect_language(words): """ Detect language of given phrase :param words: List of space seperated words :type words: str :return str: Language """ words = normalize_string(words) if isinstance(words, (str, unicode if sys.version < '3' else bytes)): words = words.split(' ') wlcount = {} for fn in os.listdir(WORDLIST_DIR): if fn.endswith(".txt"): with open('%s/%s' % (WORDLIST_DIR, fn), 'r') as f: wordlist = [w.strip() for w in f.readlines()] language = fn.split('.')[0] wlcount[language] = 0 for word in words: if sys.version < '3': word = word.encode('utf-8') if word in wordlist: wlcount[language] += 1 detlang = max(wlcount.keys(), key=(lambda key: wlcount[key])) if not wlcount[detlang]: raise Warning("Could not detect language of Mnemonic sentence %s" % words) return detlang
def sanitize_mnemonic(self, words): """ Check and convert list of words to utf-8 encoding. Raises an error if unrecognised word is found :param words: List of space separated words :type words: str :return str: Sanitized list of words """ words = normalize_string(words) language = self.detect_language(words) if isinstance(words, TYPE_TEXT): words = words.split(' ') # TODO: Path(BCL_INSTALL_DIR, 'wordlist', '%s.txt' % language).open() as f: with open( os.path.join(str(BCL_INSTALL_DIR), 'wordlist', '%s.txt' % language)) as f: wordlist = [w.strip() for w in f.readlines()] for word in words: if sys.version < '3': word = word.encode('utf-8') if word not in wordlist: raise Warning("Unrecognised word %s in mnemonic sentence" % word.encode('utf8')) return ' '.join(words)
def to_mnemonic(self, data, add_checksum=True, check_on_curve=True): """ Convert key data entropy to Mnemonic sentence :param data: Key data entropy :type data: bytes, hexstring :param add_checksum: Included a checksum? Default is True :type add_checksum: bool :param check_on_curve: Check if data integer value is on secp256k1 curve. Should be enabled when not testing and working with crypto :type check_on_curve: bool :return str: Mnemonic passphrase consisting of a space seperated list of words """ data = to_bytes(data) data_int = change_base(data, 256, 10) if check_on_curve and not 0 < data_int < secp256k1_n: raise ValueError( "Integer value of data should be in secp256k1 domain between 1 and secp256k1_n-1" ) if add_checksum: binresult = change_base(data_int, 10, 2, len(data) * 8) + self.checksum(data) wi = change_base(binresult, 2, 2048) else: wi = change_base(data_int, 10, 2048) return normalize_string(' '.join([self._wordlist[i] for i in wi]))
def test_tools_clw_create_multisig_wallet(self): key_list = [ 'tprv8ZgxMBicQKsPd1Q44tfDiZC98iYouKRC2CzjT3HGt1yYw2zuX2awTotzGAZQEAU9bi2M5MCj8iedP9MREPjUgpDEBwBgGi2C8eK' '5zNYeiX8', 'tprv8ZgxMBicQKsPeUbMS6kswJc11zgVEXUnUZuGo3bF6bBrAg1ieFfUdPc9UHqbD5HcXizThrcKike1c4z6xHrz6MWGwy8L6YKVbgJ' 'MeQHdWDp' ] cmd_wlt_create = "echo y | %s %s testms -m 2 %s -r -n testnet -d %s" % \ (self.python_executable, self.clw_executable, ' '.join(key_list), DATABASEFILE_UNITTESTS) cmd_wlt_delete = "echo testms | %s %s testms --wallet-remove -d %s" % \ (self.python_executable, self.clw_executable, DATABASEFILE_UNITTESTS) output_wlt_create = "Receive address(es):\n2N7QSKcsmWPP9anG7cdZvzBUbgTVrAK2MZ9" output_wlt_delete = "Wallet testms has been removed" self.assertIn(output_wlt_create, normalize_string(check_output(cmd_wlt_create, shell=True))) self.assertIn(output_wlt_delete, normalize_string(check_output(cmd_wlt_delete, shell=True)))
def test_tools_clw_create_multisig_wallet_one_key(self): key_list = [ 'tprv8ZgxMBicQKsPd1Q44tfDiZC98iYouKRC2CzjT3HGt1yYw2zuX2awTotzGAZQEAU9bi2M5MCj8iedP9MREPjUgpDEBwBgGi2C8eK' '5zNYeiX8' ] cmd_wlt_create = "%s %s testms1 -m 2 2 %s -r -n testnet -d %s" % \ (self.python_executable, self.clw_executable, ' '.join(key_list), self.DATABASE_URI) cmd_wlt_delete = "%s %s testms1 --wallet-remove -d %s" % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) output_wlt_create = "if you understood and wrote down your key: Receive address(es):" output_wlt_delete = "Wallet testms1 has been removed" process = Popen(cmd_wlt_create, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'y\nyes') self.assertIn(output_wlt_create, normalize_string(poutput[0])) process = Popen(cmd_wlt_delete, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'testms1') self.assertIn(output_wlt_delete, normalize_string(poutput[0]))
def test_tools_clw_transaction(self): cmd_wlt_create = "echo y | %s %s test2 --passphrase 'emotion camp sponsor curious bacon squeeze bean world " \ "actual chicken obscure spray' -r -n bitcoinlib_test -d %s" % \ (self.python_executable, self.clw_executable, DATABASEFILE_UNITTESTS) cmd_wlt_update = "%s %s test2 -d %s" % \ (self.python_executable, self.clw_executable, DATABASEFILE_UNITTESTS) cmd_wlt_transaction = "%s %s test2 -d %s -t 21HVXMEdxdgjNzgfERhPwX4okXZ8WijHkvu 50000000 -f 100000 -p" % \ (self.python_executable, self.clw_executable, DATABASEFILE_UNITTESTS) cmd_wlt_delete = "echo test2 | %s %s test2 --wallet-remove -d %s" % \ (self.python_executable, self.clw_executable, DATABASEFILE_UNITTESTS) output_wlt_create = "Receive address(es):\n21GPfxeCbBunsVev4uS6exPhqE8brPs1ZDF" output_wlt_transaction = b'Transaction pushed to network' output_wlt_delete = "Wallet test2 has been removed" self.assertIn(output_wlt_create, normalize_string(check_output(cmd_wlt_create, shell=True))) print(check_output(cmd_wlt_update, shell=True)) self.assertIn(output_wlt_transaction, check_output(cmd_wlt_transaction, shell=True)) self.assertIn(output_wlt_delete, normalize_string(check_output(cmd_wlt_delete, shell=True)))
def test_tools_clw_create_multisig_wallet(self): key_list = [ 'tprv8ZgxMBicQKsPd1Q44tfDiZC98iYouKRC2CzjT3HGt1yYw2zuX2awTotzGAZQEAU9bi2M5MCj8iedP9MREPjUgpDEBwBgGi2C8eK' '5zNYeiX8', 'tprv8ZgxMBicQKsPeUbMS6kswJc11zgVEXUnUZuGo3bF6bBrAg1ieFfUdPc9UHqbD5HcXizThrcKike1c4z6xHrz6MWGwy8L6YKVbgJ' 'MeQHdWDp' ] cmd_wlt_create = "%s %s testms -m 2 2 %s -r -n testnet -d %s" % \ (self.python_executable, self.clw_executable, ' '.join(key_list), self.DATABASE_URI) cmd_wlt_delete = "%s %s testms --wallet-remove -d %s" % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) output_wlt_create = "2NBrLTapyFqU4Wo29xG4QeEt8kn38KVWRR" output_wlt_delete = "Wallet testms has been removed" process = Popen(cmd_wlt_create, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'y') self.assertIn(output_wlt_create, normalize_string(poutput[0])) process = Popen(cmd_wlt_delete, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'testms') self.assertIn(output_wlt_delete, normalize_string(poutput[0]))
def test_tools_clw_create_multisig_wallet_p2sh_segwit(self): key_list = [ 'YprvANkMzkodih9AKnvFGXTm8Fid3b6wDWoRq5GxmoFb8Rwoa4YsJvoHtbd6jFhCiCzG8Da3bFbkBeQq7Lz1YDAqufAZB5paBaZTEv8' 'A1Yxfi5R', 'YprvANkMzkodih9AJ6UamjW9rTWqBDMm5Be3M2cKybivd6V1MSMnKnGDkUXsVkz1hPKKNPFRZS9fFchRGKTgKdyTsppMuHjQQMVFBLY' 'Ghp5MTsC', 'YprvANkMzkodih9AKQ8evAkiDWCzpQsU6N1uasNtWznNj44Y2X6FJqkv9wcfavxVEkz9qru7VKRhzmQXqy562b9Tk4JGdsaVazByzmX' '7FW6wpKW' ] cmd_wlt_create = "%s %s testms-p2sh-segwit -m 3 2 %s -r -y p2sh-segwit -d %s" % \ (self.python_executable, self.clw_executable, ' '.join(key_list), self.DATABASE_URI) cmd_wlt_delete = "%s %s testms-p2sh-segwit --wallet-remove -d %s" % \ (self.python_executable, self.clw_executable, self.DATABASE_URI) output_wlt_create = "3MtNi5U2cjs3EcPizzjarSz87pU9DTANge" output_wlt_delete = "Wallet testms-p2sh-segwit has been removed" process = Popen(cmd_wlt_create, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'y') self.assertIn(output_wlt_create, normalize_string(poutput[0])) process = Popen(cmd_wlt_delete, stdin=PIPE, stdout=PIPE, shell=True) poutput = process.communicate(input=b'testms-p2sh-segwit') self.assertIn(output_wlt_delete, normalize_string(poutput[0]))
def to_mnemonic(self, data, add_checksum=True): """ Convert key data entropy to Mnemonic sentence :param data: Key data entropy :type data: bytes, hexstring :param add_checksum: Included a checksum? Default is True :type add_checksum: bool :return str: Mnemonic passphrase consisting of a space seperated list of words """ data = to_bytes(data) if add_checksum: binresult = change_base(data, 256, 2, len(data) * 8) + self.checksum(data) wi = change_base(binresult, 2, 2048) else: wi = change_base(data, 256, 2048) return normalize_string(' '.join([self._wordlist[i] for i in wi]))
def to_seed(self, words, passphrase=''): """ Use Mnemonic words and passphrase to create a PBKDF2 seed (Password-Based Key Derivation Function 2) First use 'sanitize_mnemonic' to determine language and validate and check words :param words: Mnemonic passphrase as string with space seperated words :type words: str :param passphrase: A password to protect key, leave empty to disable :type passphrase: str :return bytes: PBKDF2 seed """ words = self.sanitize_mnemonic(words) mnemonic = normalize_string(words) passphrase = passphrase.encode() return PBKDF2(mnemonic, b'mnemonic' + passphrase, iterations=PBKDF2_ROUNDS, macmodule=hmac, digestmodule=hashlib.sha512).read(64)
def sanitize_mnemonic(self, words): """ Check and convert list of words to utf-8 encoding. Raises an error if unrecognised word is found :param words: List of space seperated words :type words: str :return str: Sanitized list of words """ words = normalize_string(words) language = self.detect_language(words) if isinstance(words, (str, unicode if sys.version < '3' else bytes)): words = words.split(' ') with open('%s/%s.txt' % (WORDLIST_DIR, language), 'r') as f: wordlist = [w.strip() for w in f.readlines()] for word in words: if sys.version < '3': word = word.encode('utf-8') if word not in wordlist: raise Warning("Unrecognised word %s in mnemonic sentence" % word.encode('utf8')) return ' '.join(words)
'22ce2db091d6fd47294c9e2144fa0291949402e3003ce' print("\n=== Convert DER encoded signature ===") print(convert_der_sig(to_bytes(der_signature))) print("\n=== Varbyte Int conversions ===") print("Number 1000 as Varbyte Integer (hexstring): %s" % to_hexstring(int_to_varbyteint(1000))) print("Converted back (3 is size in bytes: 1 size byte + integer in bytes): ", varbyteint_to_int(to_bytes('fde803'))) # Normalize data print("\n=== Normalizations ===") data = [ u"guion cruz envío papel otoño percha hazaña salir joya gorra íntimo actriz", u'\u2167', u'\uFDFA', "あじわう ちしき たわむれる おくさま しゃそう うんこう ひてい みほん たいほ てのひら りこう わかれる かいすいよく こもん ねもと", '12345', ] for dt in data: print("\nInput data", dt) print("Normalized unicode string (normalize_string): ", normalize_string(dt)) print("Normalized variable (normalize_var): ", normalize_var(dt)) # Convert Bech32 address to Public key hash address = "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4" pkh = "0014751e76e8199196d454941c45d1b3a323f1433bd6" pkh_converted = addr_bech32_to_pubkeyhash(address, prefix='bc', include_witver=True, as_hex=True) print(pkh, " == ", pkh_converted) addr = pubkeyhash_to_addr_bech32(pkh_converted, address[:2].lower())