1#!/usr/bin/env python3
2# Copyright (c) 2016-2018 The Bitcoin Core developers
3# Distributed under the MIT software license, see the accompanying
4# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5"""Encode and decode BASE58, P2PKH and P2SH addresses."""
6
7from .script import hash256, hash160, sha256, CScript, OP_0
8from .util import bytes_to_hex_str, hex_str_to_bytes
9
10from . import segwit_addr
11
12ADDRESS_BCRT1_UNSPENDABLE = 'rltc1qt5aqjfq74dfdcjaep37028ympxtf5u55tp7efm'
13
14chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
15
16
17def byte_to_base58(b, version):
18    result = ''
19    str = bytes_to_hex_str(b)
20    str = bytes_to_hex_str(chr(version).encode('latin-1')) + str
21    checksum = bytes_to_hex_str(hash256(hex_str_to_bytes(str)))
22    str += checksum[:8]
23    value = int('0x'+str,0)
24    while value > 0:
25        result = chars[value % 58] + result
26        value //= 58
27    while (str[:2] == '00'):
28        result = chars[0] + result
29        str = str[2:]
30    return result
31
32# TODO: def base58_decode
33
34def keyhash_to_p2pkh(hash, main = False):
35    assert (len(hash) == 20)
36    version = 0 if main else 111
37    return byte_to_base58(hash, version)
38
39def scripthash_to_p2sh(hash, main = False):
40    assert (len(hash) == 20)
41    version = 5 if main else 58
42    return byte_to_base58(hash, version)
43
44def key_to_p2pkh(key, main = False):
45    key = check_key(key)
46    return keyhash_to_p2pkh(hash160(key), main)
47
48def script_to_p2sh(script, main = False):
49    script = check_script(script)
50    return scripthash_to_p2sh(hash160(script), main)
51
52def key_to_p2sh_p2wpkh(key, main = False):
53    key = check_key(key)
54    p2shscript = CScript([OP_0, hash160(key)])
55    return script_to_p2sh(p2shscript, main)
56
57def program_to_witness(version, program, main = False):
58    if (type(program) is str):
59        program = hex_str_to_bytes(program)
60    assert 0 <= version <= 16
61    assert 2 <= len(program) <= 40
62    assert version > 0 or len(program) in [20, 32]
63    return segwit_addr.encode("ltc" if main else "rltc", version, program)
64
65def script_to_p2wsh(script, main = False):
66    script = check_script(script)
67    return program_to_witness(0, sha256(script), main)
68
69def key_to_p2wpkh(key, main = False):
70    key = check_key(key)
71    return program_to_witness(0, hash160(key), main)
72
73def script_to_p2sh_p2wsh(script, main = False):
74    script = check_script(script)
75    p2shscript = CScript([OP_0, sha256(script)])
76    return script_to_p2sh(p2shscript, main)
77
78def check_key(key):
79    if (type(key) is str):
80        key = hex_str_to_bytes(key) # Assuming this is hex string
81    if (type(key) is bytes and (len(key) == 33 or len(key) == 65)):
82        return key
83    assert(False)
84
85def check_script(script):
86    if (type(script) is str):
87        script = hex_str_to_bytes(script) # Assuming this is hex string
88    if (type(script) is bytes or type(script) is CScript):
89        return script
90    assert(False)
91