Exemple #1
0
def address_type(addr):
    if addr.startswith(('1', '2', '3', 'm', 'n')):
        try:
            address = base58.decode(addr).rjust(25, b'\x00')
        except Base58DecodeError as e:
            raise InvalidAddress(f"{addr} : {e}") from None
        payload, checksum = address[:-4], address[-4:]
        version_byte, digest = payload[0:1], payload[1:].rjust(20, b'\x00')
        if len(digest) != 20:
            raise InvalidAddress(f"{addr} : Bad Payload") from None
        if sha256(sha256(payload))[:4] != checksum:
            raise InvalidAddress(f"{addr} : Invalid checksum") from None
        try:
            return {network('keyhash'): ADDRESS.P2PKH, network('scripthash'): ADDRESS.P2SH}[version_byte]
        except KeyError:
            raise InvalidAddress(f"{addr} : Invalid version byte") from None
    elif addr.startswith(network('hrp')):
        try:
            witness_version, witness_program = bech32.decode(network('hrp'), addr)
        except Bech32DecodeError as e:
            raise InvalidAddress(f"{addr} : {e}") from None

        if not witness_version == 0x00:
            raise InvalidAddress(f"{addr} : Invalid witness version") from None
        if len(witness_program) == 20:
            return ADDRESS.P2WPKH
        elif len(witness_program) == 32:
            return ADDRESS.P2WSH
        else:
            raise InvalidAddress(f"{addr} : Invalid witness program") from None
    else:
        raise InvalidAddress(f"{addr} : Invalid leading character") from None
Exemple #2
0
 def _receive(self, value: int):
     """Creates an output that sends to this address"""
     addr_type = self.type()
     output = Output(value=value, script=b'')
     if addr_type == ADDRESS.P2PKH:
         address = base58.decode(self.address).rjust(25, b'\x00')
         keyhash = address[1:-4]
         output.script = OP.DUP.byte + OP.HASH160.byte + push(keyhash) + OP.EQUALVERIFY.byte + OP.CHECKSIG.byte
     elif addr_type == ADDRESS.P2SH:
         address = base58.decode(self.address).rjust(25, b'\x00')
         scripthash = address[1:-4]
         output.script = OP.HASH160.byte + push(scripthash) + OP.EQUAL.byte
     elif addr_type in (ADDRESS.P2WPKH, ADDRESS.P2WSH):
         witness_version, witness_program = bech32.decode(network('hrp'), self.address)
         output.script = OP(bytes_to_int(witness_byte(witness_version))).byte + push(bytes(witness_program))
     else:
         raise ValidationError(f"Cannot create output of type {addr_type}")
     return output
Exemple #3
0
 def from_wif(cls, wif: str) -> 'PrivateKey':
     from cryptotools.BTC import base58, sha256
     from cryptotools.BTC.network import network
     bts = base58.decode(wif)
     network_byte, key, checksum = bts[0:1], bts[1:-4], bts[-4:]
     assert sha256(sha256(network_byte + key))[:4] == checksum, 'Invalid Checksum'
     assert network_byte == network('wif'), 'Invalid Network byte'
     if key.endswith(b'\x01'):
         key = key[:-1]
         compressed = True  # TODO
     else:
         compressed = False  # TODO
     return cls(key)
Exemple #4
0
 def decode(cls, string: str) -> 'ExtendedKey':
     bts = base58.decode(string)
     assert len(bts) == 82, f'Invalid length {len(bts)})'
     data, checksum = bts[:78], bts[78:]
     assert sha256(sha256(data)).startswith(checksum), 'Invalid checksum'
     return cls.deserialize(data)