def test_zprv(self): mnemonic, priv = HDPrivateKey.generate(entropy=1 << 128) for word in mnemonic.split(): self.assertTrue(word in WORD_LIST) zprv = priv.zprv() self.assertTrue(zprv.startswith('zprv')) zpub = priv.pub.zpub() self.assertTrue(zpub.startswith('zpub')) derived = HDPrivateKey.parse(zprv) self.assertEqual(zprv, derived.zprv()) mnemonic, priv = HDPrivateKey.generate(testnet=True) zprv = priv.zprv() self.assertTrue(zprv.startswith('vprv')) zpub = priv.pub.zpub() self.assertTrue(zpub.startswith('vpub')) xpub = priv.pub.xpub() self.assertTrue(xpub.startswith('tpub')) derived = HDPrivateKey.parse(zprv) self.assertEqual(zprv, derived.zprv()) derived_pub = HDPublicKey.parse(zpub) self.assertEqual(zpub, derived_pub.zpub()) with self.assertRaises(ValueError): bad_zprv = encode_base58_checksum(b'\x00' * 78) HDPrivateKey.parse(bad_zprv) with self.assertRaises(ValueError): bad_zpub = encode_base58_checksum(b'\x00' * 78) HDPublicKey.parse(bad_zpub) with self.assertRaises(ValueError): derived_pub.child(1 << 31)
def test_zprv(self): mnemonic, priv = HDPrivateKey.generate(entropy=1<<128) for word in mnemonic.split(): self.assertTrue(word in WORD_LIST) zprv = priv.zprv() self.assertTrue(zprv.startswith('zprv')) zpub = priv.pub.zpub() self.assertTrue(zpub.startswith('zpub')) derived = HDPrivateKey.parse(BytesIO(zprv.encode('ascii'))) self.assertEqual(zprv, derived.zprv()) mnemonic, priv = HDPrivateKey.generate(testnet=True) zprv = priv.zprv() self.assertEqual(zprv.encode('ascii'), priv.serialize()) self.assertTrue(zprv.startswith('vprv')) zpub = priv.pub.zpub() self.assertEqual(zpub.encode('ascii'), priv.pub.serialize()) self.assertTrue(zpub.startswith('vpub')) xpub = priv.pub.xpub() self.assertTrue(xpub.startswith('tpub')) derived = HDPrivateKey.parse(BytesIO(zprv.encode('ascii'))) self.assertEqual(zprv, derived.zprv()) derived_pub = HDPublicKey.parse(BytesIO(zpub.encode('ascii'))) self.assertEqual(zpub, derived_pub.zpub()) self.assertTrue(derived_pub.p2wpkh_script_pubkey().is_p2wpkh_script_pubkey()) with self.assertRaises(ValueError): bad_zprv = encode_base58_checksum(b'\x00' * 78) HDPrivateKey.parse(BytesIO(bad_zprv.encode('ascii'))) with self.assertRaises(ValueError): bad_zpub = encode_base58_checksum(b'\x00' * 78) HDPublicKey.parse(BytesIO(bad_zpub.encode('ascii'))) with self.assertRaises(ValueError): priv.child(1 << 58) with self.assertRaises(ValueError): derived_pub.child(1 << 58)
def _pub(self, version): '''Returns the base58-encoded x/y/z pub. Expects a 4-byte version.''' # get the serialization raw = self._serialize(version) # base58-encode the whole thing return encode_base58_checksum(raw)
def address(self, compressed=True, testnet=False): '''Returns address string''' h160 = self.hash160(compressed) prefix = b'\x00' if testnet: prefix = b'\x6f' return encode_base58_checksum(prefix + h160)
def address(self, compressed=True, testnet=False): h160 = self.hash160(compressed) if testnet: prefix = b"\x6f" else: prefix = b"\x" return encode_base58_checksum(prefix+h160)
def address(self, testnet=False): if testnet: prefix = b'\xc4' else: prefix = b'\x05' # return the encode_base58_checksum the prefix and h160 return encode_base58_checksum(prefix + self.hash160())
def p2pk_address(self, compressed=True, testnet=False): sec = self.sec(compressed) if testnet: prefix = b'\x6f' else: prefix = b'\x00' return encode_base58_checksum(prefix + sec)
def address(self, compressed=True, testnet=False): '''Returns legacy address string''' h160 = self.hash160(compressed) prefix = P2PKH_MAIN_PREFIX if testnet: prefix = P2PKH_TEST_PREFIX return encode_base58_checksum(prefix + h160)
def address(self, compressed=True, testnet=False): # Returns the address string h160 = self.hash160(compressed) if testnet: prefix = b'\x6f' else: prefix = b'\x00' return encode_base58_checksum(prefix + h160)
def _prv(self, version): raw = version raw += int_to_byte(self.depth) raw += self.parent_fingerprint raw += int_to_big_endian(self.child_number, 4) raw += self.chain_code raw += int_to_big_endian(self.private_key.secret, 33) return encode_base58_checksum(raw)
def address(self, compressed=True, testnet=False): '''Returns the address string''' h160 = self.hash160(compressed) print("Address Hash160: {}".format(h160)) if testnet: prefix = b'\x6f' else: prefix = b'\x00' return encode_base58_checksum(prefix + h160)
def to_address(self, testnet=False): # TODO maybe pass script type ? if self.is_p2pkh_script_pubkey(): h160 = self.cmds[2] prefix = P2PKH_TEST_PREFIX if testnet else P2PKH_MAIN_PREFIX return Address(encode_base58_checksum(prefix + h160)) elif self.is_p2sh_script_pubkey(): h160 = self.cmds[1] prefix = P2SH_TEST_PREFIX if testnet else P2SH_MAIN_PREFIX return Address(encode_base58_checksum(prefix + h160)) elif self.is_p2wpkh_script_pubkey(): h160 = self.cmds[1] return Address(h160_to_p2wpkh(h160, witver=0, testnet=testnet)) elif self.is_p2wsh_script_pubkey(): h256 = self.cmds[1] return Address(h256_to_p2wsh(h256, witver=0, testnet=testnet)) else: return None
def test_base58(self): addr = '1BenRpVUFK65JFWcQSuHnJKzc4M8ZP8Eqa' h160 = unhexlify('0074d691da1574e6b3c192ecfb52cc8984ee7b6c56') self.assertEqual(decode_base58(addr), h160) self.assertRaises(ValueError, decode_base58, addr+'1') got = encode_base58_checksum(h160) self.assertEqual(got, addr) wif = '5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf' want = unhexlify('800000000000000000000000000000000000000000000000000000000000000001') self.assertEqual(decode_base58(wif, num_bytes=38, strip_leading_zeros=True), want)
def wif(self, compressed=True, testnet=False): secret_bytes = self.secret.to_bytes(32, "big") if testnet: prefix = b"\xef" else: prefix = b"\x80" if compressed: suffix = b"\x01" else: suffix = "" return encode_base58_checksum(prefix + secret_bytes + suffix)
def address(self, compressed=True, testnet=False): # prefix depends on address being testnet or mainnet and type of address. if testnet: prefix = b'\x6f' else: prefix = b'\x00' # hash 160 of the sec format h160 = self.hash160(compressed) # combine prefix with hash 160 of sec combined = prefix + h160 return encode_base58_checksum(combined)
def wif(self, compressed=True, testnet=False): secret_bytes = self.secret.to_bytes(32, 'big') if testnet: prefix = b'\xef' else: prefix = b'\x80' if compressed: suffix = b'\x01' else: suffix = b'' return encode_base58_checksum(prefix + secret_bytes + suffix)
def wif(self, prefix=b'\x80'): # convert the secret from integer to a 32-bytes in big endian using # num.to_bytes(32, 'big') secret_bytes = self.secret.to_bytes(32, 'big') # append b'\x01' if compressed if self.compressed: suffix = b'\x01' else: suffix = b'' # encode_base58_checksum the whole thing return encode_base58_checksum(prefix + secret_bytes + suffix)
def wif(self, compressed=True, testnet=False): if testnet: prefix = b'\xef' else: prefix = b'\x80' if compressed: postfix = b'\x01' else: postfix = b'' binary = self.secret.to_bytes(32, 'big') return encode_base58_checksum(prefix + binary + postfix)
def xprv(self): if self.testnet: version = unhexlify('04358394') else: version = unhexlify('0488ADE4') depth = bytes([self.depth]) fingerprint = self.fingerprint child_number = self.child_number.to_bytes(4, 'big') chain_code = self.chain_code prv = bytes([0]) + self.private_key.secret.to_bytes(32, 'big') return encode_base58_checksum(version + depth + fingerprint + child_number + chain_code + prv)
def xpub(self): if self.testnet: version = unhexlify('043587CF') else: version = unhexlify('0488B21E') depth = bytes([self.depth]) fingerprint = self.fingerprint child_number = self.child_number.to_bytes(4, 'big') chain_code = self.chain_code sec = self.point.sec() return encode_base58_checksum(version + depth + fingerprint + child_number + chain_code + sec)
def zprv(self): if self.testnet: version = TESTNET_ZPRV else: version = MAINNET_ZPRV depth = int_to_little_endian(self.depth, 1) fingerprint = self.fingerprint child_number = self.child_number.to_bytes(4, 'big') chain_code = self.chain_code prv = b'\x00' + self.private_key.secret.to_bytes(32, 'big') return encode_base58_checksum( version + depth + fingerprint + child_number + chain_code + prv)
def address(self, compressed=True, testnet=False, p2sh=True): '''Returns the address string''' if testnet: prefix = b'\x6f' else: prefix = b'\x00' if p2sh: dat_address = self.hash160(compressed) else: dat_address = self.sec(compressed) return encode_base58_checksum(prefix + dat_address)
def address(self, compressed=True, testnet=False): '''Returns the address string''' # get the sec sec = self.sec(compressed) # hash160 the sec h160 = hash160(sec) # prefix is b'\x00' for mainnet, b'\x6f' for testnet if testnet: prefix = b'\x6f' else: prefix = b'\x00' # return the encode_base58_checksum of the prefix and h160 return encode_base58_checksum(prefix + h160)
def zpub(self): if self.testnet: version = TESTNET_ZPUB else: version = MAINNET_ZPUB depth = int_to_little_endian(self.depth, 1) fingerprint = self.fingerprint child_number = self.child_number.to_bytes(4, 'big') chain_code = self.chain_code sec = self.point.sec() return encode_base58_checksum( version + depth + fingerprint + child_number + chain_code + sec)
def address(self, compressed=True, testnet=False, p2sh=False): '''Returns the address string''' print(self.hash160) h160 = self.hash160(compressed) print(h160) print(testnet) print(p2sh) if testnet and p2sh == False: prefix = b'\x6f' elif p2sh == True and testnet == True: prefix = b'\xc4' else: prefix = b'\x00' return encode_base58_checksum(prefix + h160)
def wif(self, compressed=True, testnet=False): # convert the secret from integer to a 32-bytes in big endian using num.to_bytes(32, 'big') secret_bytes = self.secret.to_bytes(32, 'big') # prepend b'\xef' on testnet, b'\x80' on mainnet if testnet: prefix = b'\xef' else: prefix = b'\x80' # append b'\x01' if compressed if compressed: suffix = b'\x01' else: suffix = b'' # encode_base58_checksum the whole thing return encode_base58_checksum(prefix + secret_bytes + suffix)
def wif(self, compressed=True): # convert the secret from integer to a 32-bytes in big endian using int_to_big_endian(x, 32) secret_bytes = int_to_big_endian(self.secret, 32) # prepend b'\xef' on testnet, b'\x80' on mainnet if self.testnet: prefix = b'\xef' else: prefix = b'\x80' # append b'\x01' if compressed if compressed: suffix = b'\x01' else: suffix = b'' # encode_base58_checksum the whole thing return encode_base58_checksum(prefix + secret_bytes + suffix)
def _prv(self, version): '''Returns the base58-encoded x/y/z prv. Expects a 4-byte version.''' # version + depth + parent_fingerprint + child number + chain code + private key # start with version, which should be a constant depending on testnet raw = version # add depth, which is 1 byte using int_to_byte raw += int_to_byte(self.depth) # add the parent_fingerprint raw += self.parent_fingerprint # add the child number 4 bytes using int_to_big_endian raw += int_to_big_endian(self.child_number, 4) # add the chain code raw += self.chain_code # add the 0 byte and the private key's secret in big endian, 33 bytes raw += int_to_big_endian(self.private_key.secret, 33) # return the whole thing base58-encoded return encode_base58_checksum(raw)
def wif(self, compressed=True, testnet=False): # 1 Encode the secret in 32 bytes big-endian secret_bytes = self.secret.to_bytes(32, 'big') # 2 For mainnet private keys start prefix with 0x80 and testnet with 0xef if testnet: prefix = b'\xef' else: prefix = b'\x80' # 3 if SEC format used for public key is compressed add a suffix of 0x01 if compressed: suffix = b'\x01' else: suffix = b'' # 4 Combine prefix + secret_bytes + suffix # 5 Do hash256 (double sha256) of secret_combination # 6 Take result combination and the first 4 bytes of hash256 and encoded it in Base58 return encode_base58_checksum(prefix + secret_bytes + suffix)
def handle_address(args): wallet = Wallet.open() public_key = wallet.private_key.point if args.type == 'p2pkh': return public_key.address(compressed=True, testnet=True) elif args.type == 'p2sh': # FIXME: hacky from helper import encode_base58_checksum sec = public_key.sec(compressed=True) redeem_script = Script(cmds=[sec, 172]) raw_redeem = redeem_script.raw_serialize() h160 = hash160(raw_redeem) p2sh_script(h160) # FIXME prefix = b'\xc4' # testnet return encode_base58_checksum(prefix + h160) elif args.type == 'p2wpkh': return public_key.bech32_address(testnet=True) else: raise ValueError('unknown address type')