Esempio n. 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
Esempio n. 2
0
    def test_bech32_decode(self):
        private, public = generate_keypair()

        witprog = hash160(public.encode(compressed=True))
        address = bech32.encode(self.hrp, self.witver, witprog)
        wv, decoded = bech32.decode(self.hrp, address)
        self.assertEqual(wv, self.witver)
        self.assertEqual(bytes(decoded), bytes(witprog))
Esempio n. 3
0
def address_to_script(addr: str) -> bytes:
    """https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#segwit-address-format"""
    hrp, _ = bech32.bech32_decode(addr)
    if hrp not in [net['hrp'] for net in networks.values()]:
        raise Bech32DecodeError('Invalid human-readable part')
    witver, witprog = bech32.decode(hrp, addr)
    if not (0 <= witver <= 16):
        raise Bech32DecodeError('Invalid witness version')

    script = witness_byte(witver) + push(bytes(witprog))
    return script
Esempio n. 4
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