Esempio n. 1
0
 def test_double_sha256(self):
     print("Double SHA256")
     self.assertEqual(tools.double_sha256(b"test double sha256"),
                      unhexlify("1ab3067efb509c48bda198f48c473f034202537c28b7b4c3b2ab2c4bf4a95c8d"))
     self.assertEqual(tools.double_sha256(hexlify(b"test double sha256").decode()),
                      unhexlify("1ab3067efb509c48bda198f48c473f034202537c28b7b4c3b2ab2c4bf4a95c8d"))
     self.assertEqual(tools.double_sha256(hexlify(b"test double sha256").decode(), 1),
                      "1ab3067efb509c48bda198f48c473f034202537c28b7b4c3b2ab2c4bf4a95c8d")
Esempio n. 2
0
def hash_to_address(address_hash,
                    testnet=False,
                    script_hash=False,
                    witness_version=0):
    """
    Get address from public key/script hash. In case PUBKEY, P2PKH, P2PKH public key/script hash is SHA256+RIPEMD160,
    P2WSH script hash is SHA256.


    :param address_hash: public key hash or script hash in HEX or bytes string format.
    :param testnet: (optional) flag for testnet network, by default is False.
    :param script_hash: (optional) flag for script hash (P2SH address), by default is False.
    :param witness_version: (optional) witness program version, by default is 0, for legacy
                            address format use None.
    :return: address in base58 or bech32 format.
    """
    if isinstance(address_hash, str):
        address_hash = bytes_from_hex(address_hash)
    if not isinstance(address_hash, bytes):
        raise TypeError("address hash must be HEX encoded string or bytes")

    if not script_hash:
        if witness_version is None:
            if len(address_hash) != 20:
                raise ValueError("address hash length incorrect")
            if testnet:
                prefix = TESTNET_ADDRESS_BYTE_PREFIX
            else:
                prefix = MAINNET_ADDRESS_BYTE_PREFIX
            address_hash = b"%s%s" % (prefix, address_hash)
            address_hash += double_sha256(address_hash)[:4]
            return encode_base58(address_hash)
        else:
            if len(address_hash) not in (20, 32):
                raise ValueError("address hash length incorrect")

    if witness_version is None:
        if testnet:
            prefix = TESTNET_SCRIPT_ADDRESS_BYTE_PREFIX
        else:
            prefix = MAINNET_SCRIPT_ADDRESS_BYTE_PREFIX
        address_hash = b"%s%s" % (prefix, address_hash)
        address_hash += double_sha256(address_hash)[:4]
        return encode_base58(address_hash)

    if testnet:
        prefix = TESTNET_SEGWIT_ADDRESS_BYTE_PREFIX
        hrp = TESTNET_SEGWIT_ADDRESS_PREFIX
    else:
        prefix = MAINNET_SEGWIT_ADDRESS_BYTE_PREFIX
        hrp = MAINNET_SEGWIT_ADDRESS_PREFIX

    address_hash = b"%s%s" % (witness_version.to_bytes(
        1, "big"), rebase_8_to_5(address_hash))
    checksum = bech32_polymod(b"%s%s%s" % (prefix, address_hash, b"\x00" * 6))
    checksum = rebase_8_to_5(checksum.to_bytes(5, "big"))[2:]
    return "%s1%s" % (hrp, rebase_5_to_32(address_hash + checksum).decode())
Esempio n. 3
0
def merkle_root(tx_hash_list, hex=True):
    """
    Calculate merkle root from transaction hash list

    :param tx_hash_list: list of transaction hashes in bytes or HEX encoded string.
    :param hex:  (optional) If set to True return result in HEX format, by default is True.
    :return: merkle root in bytes or HEX encoded string corresponding hex flag.
    """
    tx_hash_list = [h if isinstance(h, bytes) else s2rh(h) for h in tx_hash_list]
    if len(tx_hash_list) == 1:
        return tx_hash_list[0]
    while True:
        new_hash_list = list()
        append = new_hash_list.append
        while tx_hash_list:
            h1 = tx_hash_list.pop(0)
            try:
                h2 = tx_hash_list.pop(0)
            except:
                h2 = h1
            append(double_sha256(h1 + h2))
        if len(new_hash_list) > 1:
            tx_hash_list = new_hash_list
        else:
            return new_hash_list[0] if not hex else new_hash_list[0].hex()
Esempio n. 4
0
def private_to_public_key(private_key, compressed=True, hex=True):
    """
    Get public key from private key using ECDSA secp256k1

    :param private_key: private key in WIF, HEX or bytes.
    :param compressed: (optional) flag of public key compressed format, by default set to True.
                       In case private_key in WIF format, this flag is set in accordance with 
                       the key format specified in WIF string.
    :param hex:  (optional) if set to True return key in HEX format, by default is True.
    :return: 33/65 bytes public key in HEX or bytes string.
    """
    if not isinstance(private_key, bytes):
        if isinstance(private_key, bytearray):
            private_key = bytes(private_key)
        elif isinstance(private_key, str):
            try:
                if private_key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX,
                                      TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX):
                    compressed = False
                h = decode_base58(private_key)
                if double_sha256(h[:-4])[:4] != h[-4:]:
                    raise Exception()
                private_key = h[1:33]
            except:
                try:
                    private_key = bytes_from_hex(private_key)
                except:
                    raise ValueError("private key HEX or WIF invalid")
        else:
            raise ValueError("private key must be a bytes or WIF or hex encoded string")
        if len(private_key) != 32:
            raise ValueError("private key length invalid")
    pub = __secp256k1_ec_pubkey_create__(private_key, bool(compressed))
    return pub.hex() if hex else pub
Esempio n. 5
0
def merkle_branches(tx_hash_list, hex=True):
    """
    Calculate merkle branches for coinbase transacton

    :param tx_hash_list: list of transaction hashes in bytes or HEX encoded string.
    :param hex:  (optional) If set to True return result in HEX format, by default is True.
    :return: list of merkle branches in bytes or HEX encoded string corresponding hex flag.
    """
    tx_hash_list = [h if isinstance(h, bytes) else s2rh(h) for h in tx_hash_list]
    branches = []
    if len(tx_hash_list) == 1:
        return []
    tx_hash_list.pop(0)
    branches_append = branches.append
    while True:
        branches_append(tx_hash_list.pop(0))
        new_hash_list = list()
        new_hash_list_append = new_hash_list.append
        while tx_hash_list:
            h1 = tx_hash_list.pop(0)
            try:
                h2 = tx_hash_list.pop(0)
            except:
                h2 = h1
            new_hash_list_append(double_sha256(h1 + h2))
        if len(new_hash_list) > 1:
            tx_hash_list = new_hash_list
        else:
            if new_hash_list:
                branches_append(new_hash_list.pop(0))
            return branches if not hex else [h.hex() for h in branches]
Esempio n. 6
0
def decode_block_tx(block):
    s = get_stream(block)
    b = dict()
    b["amount"] = 0
    b["size"] = int(len(block) / 2)
    b["strippedSize"] = 80
    b["version"] = unpack("<L", s.read(4))[0]
    b["versionHex"] = pack(">L", b["version"]).hex()
    b["previousBlockHash"] = rh2s(s.read(32))
    b["merkleRoot"] = rh2s(s.read(32))
    b["time"] = unpack("<L", s.read(4))[0]
    b["bits"] = s.read(4)
    b["target"] = bits_to_target(unpack("<L", b["bits"])[0])
    b["targetDifficulty"] = target_to_difficulty(b["target"])
    b["target"] = b["target"].to_bytes(32, byteorder="little")
    b["nonce"] = unpack("<L", s.read(4))[0]
    s.seek(-80, 1)
    b["header"] = s.read(80)
    b["bits"] = rh2s(b["bits"])
    b["target"] = rh2s(b["target"])
    b["hash"] = double_sha256(b["header"], hex=0)
    b["hash"] = rh2s(b["hash"])
    b["rawTx"] = dict()
    b["tx"] = list()
    for i in range(var_int_to_int(read_var_int(s))):
        b["rawTx"][i] = Transaction(s, format="raw", keep_raw_tx=True)
        b["tx"].append(rh2s(b["rawTx"][i]["txId"]))
        b["amount"] += b["rawTx"][i]["amount"]
        b["strippedSize"] += b["rawTx"][i]["bSize"]
    b["strippedSize"] += var_int_len(len(b["tx"]))
    b["weight"] = b["strippedSize"] * 3 + b["size"]
    return b
Esempio n. 7
0
def create_master_xprivate_key(seed, testnet=False, base58=None, hex=None):
    """
    Create extended private key from seed

    :param str,bytes key: seed HEX or bytes string. 
    :param boolean base58: (optional) return result as base58 encoded string, by default True.
    :param boolean hex: (optional) return result as HEX encoded string, by default False.
                        In case True base58 flag value will be ignored.
    :return: extended private key  in base58, HEX or bytes string format.
    """
    seed = get_bytes(seed)
    i = hmac_sha512(b"Bitcoin seed", seed)
    m, c = i[:32], i[32:]
    m_int = int.from_bytes(m, byteorder="big")

    if m_int <= 0 or m_int > ECDSA_SEC256K1_ORDER:  # pragma: no cover
        return None
    prefix = TESTNET_XPRIVATE_KEY_PREFIX if testnet else MAINNET_XPRIVATE_KEY_PREFIX
    key = b''.join(
        [prefix, b'\x00\x00\x00\x00\x00\x00\x00\x00\x00', c, b'\x00', m])
    if base58 is None and hex is None:
        base58 = True
    if base58:
        key = b"".join([key, double_sha256(key)[:4]])
        return encode_base58(key)
    else:
        if hex is None:
            hex = False
        return key if not hex else key.hex()
Esempio n. 8
0
def create_master_xprivate_key(seed, testnet=False, base58=True, hex=False):
    """
    Create extended private key from seed

    :param str,bytes key: seed HEX or bytes string. 
    :param boolean base58: (optional) return result as base58 encoded string, by default True.
    :param boolean hex: (optional) return result as HEX encoded string, by default False.
                        In case True base58 flag value will be ignored.
    :return: extended private key  in base58, HEX or bytes string format.
    """
    if isinstance(seed, str):
        seed = bytes.fromhex(seed)
    if not isinstance(seed, bytes):
        raise TypeError("seed should be bytes or hex encoded string")
    i = hmac_sha512(b"Bitcoin seed", seed)
    m, c = i[:32], i[32:]
    m_int = int.from_bytes(m, byteorder="big")

    if m_int <= 0 or m_int > ECDSA_SEC256K1_ORDER:
        return None
    prefix = TESTNET_XPRIVATE_KEY_PREFIX if testnet else MAINNET_XPRIVATE_KEY_PREFIX
    key = b''.join(
        [prefix, b'\x00\x00\x00\x00\x00\x00\x00\x00\x00', c, b'\x00', m])
    if base58:
        key = b"".join([key, double_sha256(key)[:4]])
        return encode_base58(key)
    else:
        return key
Esempio n. 9
0
def merkle_root(tx_hash_list, return_hex=True, receive_hex=True):
    """
    Calculate merkle root from transaction hash list

    :param tx_hash_list: list of transaction hashes in bytes or HEX encoded string.
    :param return_hex:  (optional) If set to True return result in HEX format, by default is True.
    :param receive_hex:  (optional) If set to False no internal check or decode from hex to bytes, by default is True.
    :return: merkle root in bytes or HEX encoded string corresponding hex flag.
    """
    if receive_hex:
        tx_hash_list = deque([h if isinstance(h, bytes) else s2rh(h) for h in tx_hash_list])
    else:
        tx_hash_list = deque(tx_hash_list)
    if len(tx_hash_list) == 1:
        return rh2s(tx_hash_list[0]) if return_hex else tx_hash_list[0]
    while True:
        new_hash_list = deque()
        append = new_hash_list.append
        while tx_hash_list:
            h1 = tx_hash_list.popleft()
            try:
                h2 = tx_hash_list.popleft()
            except:
                h2 = h1
            append(double_sha256(b"".join((h1, h2))))
        if len(new_hash_list) > 1:
            tx_hash_list = new_hash_list
        else:
            return new_hash_list[0] if not return_hex else rh2s(new_hash_list[0])
Esempio n. 10
0
def merkle_tree(tx_hash_list, return_hex=False, receive_hex=False):
    if receive_hex:
        tx_hash_deque = deque()
        tx_hash_deque_append = tx_hash_deque.append
        for h in tx_hash_list:
            tx_hash_deque_append(h if isinstance(h, bytes) else s2rh(h))
    else:
        tx_hash_deque = deque(tx_hash_list)
    c = merkle_tree_depth(len(tx_hash_deque))
    m = {c: deque(tx_hash_deque)}

    while len(tx_hash_deque) > 1:
        new_deque = deque()
        new_deque_append = new_deque.append
        while tx_hash_deque:
            h1 = tx_hash_deque.popleft()
            try: h2 = tx_hash_deque.popleft()
            except: h2 = h1
            hs = double_sha256(b"".join((h1, h2)))
            new_deque_append(hs)
        tx_hash_deque = new_deque
        c -= 1
        m[c] = deque(tx_hash_deque)
    if return_hex:
        for i in m:
            for k in range(len(m[i])):
                m[i][k] = rh2s(m[i][k])
    return m
Esempio n. 11
0
def is_wif_valid(wif):
    """
    Check is private key in WIF format string is valid.

    :param wif: private key in WIF format string.
    :return: boolean.
    """
    if not isinstance(wif, str):
        raise TypeError("invalid wif key")
    if wif[0] not in PRIVATE_KEY_PREFIX_LIST:
        return False
    try:
        h = decode_base58(wif)
    except:
        return False
    checksum = h[-4:]
    if wif[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX,
                  TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX):
        if len(h) != 37:
            return False
    elif len(h) != 38:
        return False
    if double_sha256(h[:-4])[:4] != checksum:
        return False
    return True
Esempio n. 12
0
    def __init__(self,
                 raw_block=None,
                 format="decoded",
                 version=536870912,
                 testnet=False):
        if format not in ("decoded", "raw"):
            raise ValueError("tx_format error, raw or decoded allowed")
        self["format"] = format
        self["testnet"] = testnet
        self["header"] = None
        self["hash"] = None
        self["version"] = version
        self["versionHex"] = pack(">L", version).hex()
        self["previousBlockHash"] = None
        self["merkleRoot"] = None
        self["tx"] = dict()
        self["time"] = None
        self["bits"] = None
        self["nonce"] = None
        self["weight"] = 0
        self["size"] = 80
        self["strippedSize"] = 80
        self["amount"] = 0
        self["height"] = None
        self["difficulty"] = None
        self["targetDifficulty"] = None
        self["target"] = None
        if raw_block is None:
            return
        self["size"] = len(raw_block) if isinstance(raw_block, bytes) else int(
            len(raw_block) / 2)
        s = self.get_stream(raw_block)
        self["format"] = "raw"
        self["version"] = unpack("<L", s.read(4))[0]
        self["versionHex"] = pack(">L", self["version"]).hex()
        self["previousBlockHash"] = s.read(32)
        self["merkleRoot"] = s.read(32)
        self["time"] = unpack("<L", s.read(4))[0]
        self["bits"] = s.read(4)

        self["target"] = bits_to_target(unpack("<L", self["bits"])[0])
        self["targetDifficulty"] = target_to_difficulty(self["target"])
        self["target"] = self["target"].to_bytes(32, byteorder="little")
        self["nonce"] = unpack("<L", s.read(4))[0]
        s.seek(-80, 1)
        self["header"] = s.read(80)
        self["hash"] = double_sha256(self["header"])
        block_target = int.from_bytes(self["hash"], byteorder="little")
        self["difficulty"] = target_to_difficulty(block_target)
        tx_count = var_int_to_int(read_var_int(s))
        self["tx"] = {i: Transaction(s, format="raw") for i in range(tx_count)}
        for t in self["tx"].values():
            self["amount"] += t["amount"]
            self["strippedSize"] += t["bSize"]
        self["strippedSize"] += var_int_len(tx_count)
        self["weight"] = self["strippedSize"] * 3 + self["size"]
        if format == "decoded":
            self.decode(testnet=testnet)
Esempio n. 13
0
    def commit(self):
        if not self["vOut"] or not self["vIn"]:
            return
        if self["segwit"]:
            for i in self["vIn"]:
                if "txInWitness" not in self["vIn"][i]:
                    if self["format"] == "raw":
                        self["vIn"][i]["txInWitness"] = []
                    else:
                        self["vIn"][i]["txInWitness"] = []
        no_segwit_view = self.serialize(segwit=False, hex=False)
        self["txId"] = double_sha256(no_segwit_view)
        self["rawTx"] = self.serialize(segwit=True, hex=False)
        self["hash"] = double_sha256(self["rawTx"])

        self["size"] = len(self["rawTx"])
        self["bSize"] = len(no_segwit_view)
        self["weight"] = self["bSize"] * 3 + self["size"]
        self["vSize"] = ceil(self["weight"] / 4)

        if self["format"] != "raw":
            self["txId"] = rh2s(self["txId"])
            self["hash"] = rh2s(self["hash"])
            self["rawTx"] = self["rawTx"].hex()

        input_sum = 0
        for i in self["vIn"]:
            if "value" in self["vIn"][i]:
                input_sum += self["vIn"][i]["value"]
            else:
                input_sum = None
                break

        output_sum = 0
        for i in self["vOut"]:
            if "value" in self["vOut"][i]:
                output_sum += self["vOut"][i]["value"]
            else:
                output_sum = None
                break
        self["amount"] = output_sum
        if output_sum and input_sum:
            self["fee"] = input_sum - output_sum
        else:
            self["fee"] = None
Esempio n. 14
0
def encode_base58(b, checksum=False):
    """Encode bytes to a base58-encoded string"""
    # Convert big-endian bytes to integer
    if not b:
        return ''
    b = get_bytes(b)
    if checksum:
        return __encode_base58__(b"%s%s" % (b, double_sha256(b)[:4]))
    return __encode_base58__(b)
Esempio n. 15
0
def wif_to_private_key(h, hex=True):
    """
    Decode WIF private key to bytes string or HEX encoded string

    :param hex:  (optional) if set to True return key in HEX format, by default is True.
    :return: Private key HEX encoded string or raw bytes string.
    """
    h = decode_base58(h)
    if double_sha256(h[:-4])[:4] != h[-4:]:
        raise TypeError("invalid wif key")
    return h[1:33].hex() if hex else h[1:33]
Esempio n. 16
0
def merkleroot_from_branches(merkle_branches, coinbase_hash, hex=True):
    """
    Calculate merkle root from merkle branches and coinbase transacton hash

    :param merkle_branches: list merkle branches in bytes or HEX encoded string.
    :param coinbase_hash: list coinbase transaction hash in bytes or HEX encoded string.
    :param hex:  (optional) If set to True return result in HEX format, by default is True.
    :return: merkle root in bytes or HEX encoded string corresponding hex flag.
    """
    merkle_root = coinbase_hash if not isinstance(coinbase_hash, str) else bytes_from_hex(coinbase_hash)
    for h in merkle_branches:
        if type(h) == str:
            h = bytes_from_hex(h)
        merkle_root = double_sha256(merkle_root + h)
    return merkle_root if not hex else merkle_root.hex()
Esempio n. 17
0
def decode_base58(s, hex=False, checksum=False, verify_checksum=False):
    """Decode a base58-encoding string, returning bytes"""
    if verify_checksum:
        checksum = True
    if not s:
        return b''
    if not isinstance(s, str):
        raise ValueError("base58 string required")
    b = __decode_base58__(s)
    if checksum:
        if verify_checksum:
            if double_sha256(b[:-4])[:4] != b[-4:]:
                raise Exception("invalid checksum")
        return b[:-4].hex() if hex else b[:-4]
    return b.hex() if hex else b
Esempio n. 18
0
def xprivate_to_xpublic_key(xprivate_key, base58=True, hex=False):
    """
    Get extended public key from extended private key using ECDSA secp256k1

    :param str,bytes key: extended private key in base58, HEX or bytes string. 
    :param boolean base58: (optional) return result as base58 encoded string, by default True.
    :param boolean hex: (optional) return result as HEX encoded string, by default False.
                        In case True base58 flag value will be ignored.
    :return: extended public key  in base58, HEX or bytes string format.
    """
    if isinstance(xprivate_key, str):
        try:
            if len(xprivate_key) == 156:
                xprivate_key = bytes.fromhex(xprivate_key)
            else:
                xprivate_key = decode_base58(xprivate_key, checksum=True)
        except:
            raise ValueError("invalid extended private key")
    if not isinstance(xprivate_key, bytes):
        raise TypeError(
            "extended private key should be base58 string or bytes")
    if xprivate_key[:4] == TESTNET_XPRIVATE_KEY_PREFIX:
        prefix = TESTNET_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == MAINNET_XPRIVATE_KEY_PREFIX:
        prefix = MAINNET_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == MAINNET_M49_XPRIVATE_KEY_PREFIX:
        prefix = MAINNET_M49_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == TESTNET_M49_XPRIVATE_KEY_PREFIX:
        prefix = TESTNET_M49_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == MAINNET_M84_XPRIVATE_KEY_PREFIX:
        prefix = MAINNET_M84_XPUBLIC_KEY_PREFIX
    elif xprivate_key[:4] == TESTNET_M84_XPRIVATE_KEY_PREFIX:
        prefix = TESTNET_M84_XPUBLIC_KEY_PREFIX
    else:
        raise ValueError("invalid extended private key")

    key = b"".join([
        prefix, xprivate_key[4:45],
        private_to_public_key(xprivate_key[46:], hex=False)
    ])
    if hex:
        return key.hex()
    elif base58:
        key = b"".join([key, double_sha256(key)[:4]])
        return encode_base58(key)
    else:
        return key
Esempio n. 19
0
def merkle_root_from_proof(merkle_proof,
                           tx_id,
                           index,
                           return_hex=True,
                           receive_hex=True):
    if receive_hex:
        _merkle_proof = deque()
        _merkle_proof_append = _merkle_proof.append
        for h in merkle_proof:
            _merkle_proof_append(s2rh(h) if isinstance(h, str) else h)
        merkle_proof = _merkle_proof
        tx_id = bytes_from_hex(tx_id) if isinstance(tx_id, str) else tx_id

    root = tx_id
    for h in merkle_proof:
        root = double_sha256(b"".join((h, root) if index % 2 else (root, h)))
        index = index // 2

    if return_hex:
        return rh2s(root)
    return root
Esempio n. 20
0
def private_key_to_wif(h, compressed=True, testnet=False):
    """
    Encode private key in HEX or RAW bytes format to WIF format.

    :param h: private key 32 byte string or HEX encoded string.
    :param compressed: (optional) flag of public key compressed format, by default set to True.  
    :param testnet: (optional) flag for testnet network, by default is False.
    :return: Private key in WIF format.
    """
    # uncompressed: 0x80 + [32-byte secret] + [4 bytes of Hash() of previous 33 bytes], base58 encoded.
    # compressed: 0x80 + [32-byte secret] + 0x01 + [4 bytes of Hash() previous 34 bytes], base58 encoded.
    if isinstance(h, str):
        h = bytes_from_hex(h)
    if len(h) != 32 and isinstance(h, bytes):
        raise TypeError("private key must be a 32 bytes or hex encoded string")
    if testnet:
        h = TESTNET_PRIVATE_KEY_BYTE_PREFIX + h
    else:
        h = MAINNET_PRIVATE_KEY_BYTE_PREFIX + h
    if compressed:
        h += b'\x01'
    h += double_sha256(h)[:4]
    return encode_base58(h)
Esempio n. 21
0
def is_address_valid(address, testnet=False):
    """
    Check is address valid.

    :param address: address in base58 or bech32 format.
    :param testnet: (optional) flag for testnet network, by default is False.
    :return: boolean.
    """
    if not address or type(address) != str:
        return False
    if address[0] in (MAINNET_ADDRESS_PREFIX, MAINNET_SCRIPT_ADDRESS_PREFIX,
                      TESTNET_ADDRESS_PREFIX, TESTNET_ADDRESS_PREFIX_2,
                      TESTNET_SCRIPT_ADDRESS_PREFIX):
        if testnet:
            if address[0] not in (TESTNET_ADDRESS_PREFIX,
                                  TESTNET_ADDRESS_PREFIX_2,
                                  TESTNET_SCRIPT_ADDRESS_PREFIX):
                return False
        else:
            if address[0] not in (MAINNET_ADDRESS_PREFIX,
                                  MAINNET_SCRIPT_ADDRESS_PREFIX):
                return False
        h = decode_base58(address)
        if len(h) != 25:
            return False
        checksum = h[-4:]
        if double_sha256(h[:-4])[:4] != checksum:
            return False
        return True
    elif address[:2].lower() in (TESTNET_SEGWIT_ADDRESS_PREFIX,
                                 MAINNET_SEGWIT_ADDRESS_PREFIX):
        if len(address) not in (42, 62):
            return False
        try:
            prefix, payload = address.split('1')
        except:
            return False
        upp = True if prefix[0].isupper() else False
        for i in payload[1:]:
            if upp:
                if not i.isupper() or i not in base32charset_upcase:
                    return False
            else:
                if i.isupper() or i not in base32charset:
                    return False
        payload = payload.lower()
        prefix = prefix.lower()
        if testnet:
            if prefix != TESTNET_SEGWIT_ADDRESS_PREFIX:
                return False
            stripped_prefix = TESTNET_SEGWIT_ADDRESS_BYTE_PREFIX
        else:
            if prefix != MAINNET_SEGWIT_ADDRESS_PREFIX:
                return False
            stripped_prefix = MAINNET_SEGWIT_ADDRESS_BYTE_PREFIX
        d = rebase_32_to_5(payload)
        address_hash = d[:-6]
        checksum = d[-6:]
        checksum2 = bech32_polymod(
            b"%s%s%s" % (stripped_prefix, address_hash, b"\x00" * 6))
        checksum2 = rebase_8_to_5(checksum2.to_bytes(5, "big"))[2:]
        if checksum != checksum2:
            return False
        return True
Esempio n. 22
0
def encode_base58_with_checksum(b):
    return encode_base58(b"%s%s" % (b, double_sha256(b)[:4]))
Esempio n. 23
0
def decode_base58_with_checksum(s):
    b = decode_base58(s)
    if double_sha256(b[:-4])[:4] != b[-4:]:
        raise Exception("invalid checksum")
    return b[:-4]
Esempio n. 24
0
def bitcoin_message(msg):
    if isinstance(msg, str):
        msg = msg.encode()
    print(b"\x18Bitcoin Signed Message:\n" + int_to_var_int(len(msg)) + msg)
    return double_sha256(b"\x18Bitcoin Signed Message:\n" +
                         int_to_var_int(len(msg)) + msg)
Esempio n. 25
0
    def sig_hash_segwit(self, n, amount, script_pub_key=None, sighash_type=SIGHASH_ALL, preimage=False):
        try:
            self["vIn"][n]
        except:
            raise Exception("sig_hash error, input not exist")

        # check script_pub_key for input
        if script_pub_key is not None:
            script_code = script_pub_key
        else:
            if  "scriptPubKey" not in self["vIn"][n]:
                raise Exception("sig_hash error, scriptPubKey required")
            script_code = self["vIn"][n]["scriptPubKey"]
        if isinstance(script_code, str):
            script_code = bytes.fromhex(script_code)
        if not isinstance(script_code,bytes):
            raise Exception("sig_hash error, script_code type error")

        # remove opcode separators
        pm = bytearray()
        # 1. nVersion of the transaction (4-byte little endian)
        pm += pack('<L', self["version"])
        # 2. hashPrevouts (32-byte hash)
        # 3. hashSequence (32-byte hash)
        # 4. outpoint (32-byte hash + 4-byte little endian)
        # 5. scriptCode of the input (serialized as scripts inside CTxOuts)
        # 6. value of the output spent by this input (8-byte little endian)
        # 7. nSequence of the input (4-byte little endian)
        hp = bytearray()  # hash of out points
        hs = bytearray()  # hash of sequences
        for i in self["vIn"]:
            tx_id = self["vIn"][i]["txId"]
            if type(tx_id) == str:
                tx_id = s2rh(tx_id)
            if not (sighash_type & SIGHASH_ANYONECANPAY):
                hp += b"%s%s" % (tx_id, pack('<L', self["vIn"][i]["vOut"]))
                if (sighash_type & 31) != SIGHASH_SINGLE and (sighash_type & 31) != SIGHASH_NONE:
                    hs += pack('<L', self["vIn"][i]["sequence"])
            if i == n:
                outpoint = b"%s%s" % (tx_id, pack('<L', self["vIn"][i]["vOut"]))
                n_sequence = pack('<L', self["vIn"][i]["sequence"])
        hash_prevouts = double_sha256(hp) if hp else b'\x00' * 32
        hash_sequence = double_sha256(hs) if hs else b'\x00' * 32
        value = amount.to_bytes(8, 'little')
        # 8. hashOutputs (32-byte hash)
        ho = bytearray()
        for o in self["vOut"]:
            script_pub_key = self["vOut"][o]["scriptPubKey"]
            if type(self["vOut"][o]["scriptPubKey"]) == str:
                script_pub_key = bytes_from_hex(script_pub_key)
            if (sighash_type & 31) != SIGHASH_SINGLE and (sighash_type & 31) != SIGHASH_NONE:
                ho += b"%s%s%s" % (self["vOut"][o]["value"].to_bytes(8, 'little'),
                                 int_to_var_int(len(script_pub_key)),
                                 script_pub_key)
            elif (sighash_type & 31) == SIGHASH_SINGLE and n < len(self["vOut"]):
                if o == n:
                    ho += b"%s%s%s" % (self["vOut"][o]["value"].to_bytes(8, 'little'),
                                       int_to_var_int(len(script_pub_key)),
                                       script_pub_key)
        hash_outputs = double_sha256(ho) if ho else b'\x00' * 32
        pm += b"%s%s%s%s%s%s%s%s%s" % (hash_prevouts, hash_sequence, outpoint,
                                       script_code, value, n_sequence, hash_outputs,
                                       pack('<L', self["lockTime"]),
                                       pack('<L', sighash_type))
        if not preimage:
            pm = double_sha256(pm)
        return pm if self["format"] == "raw" else pm.hex()
Esempio n. 26
0
    def sig_hash(self, n, script_pub_key=None, sighash_type=SIGHASH_ALL, preimage=False):
        try:
            self["vIn"][n]
        except:
            raise Exception("sig_hash error, input not exist")

        # check script_pub_key for input
        if script_pub_key is not None:
            script_code = script_pub_key
        else:
            if  "scriptPubKey" not in self["vIn"][n]:
                raise Exception("sig_hash error, scriptPubKey required")
            script_code = self["vIn"][n]["scriptPubKey"]
        if isinstance(script_code, str):
            script_code = bytes.fromhex(script_code)
        if not isinstance(script_code,bytes):
            raise Exception("sig_hash error, script_code type error")

        # remove opcode separators
        if ((sighash_type & 31) == SIGHASH_SINGLE) and (n >= (len(self["vOut"]))):
            if self["format"] == "raw":
                return  b'\x01%s' % (b'\x00' * 31)
            return rh2s(b'\x01%s' % (b'\x00' * 31))

        script_code = delete_from_script(script_code, BYTE_OPCODE["OP_CODESEPARATOR"])
        pm = bytearray()
        pm += b"%s%s" % (pack('<L', self["version"]),
                         b'\x01' if sighash_type & SIGHASH_ANYONECANPAY else int_to_var_int(len(self["vIn"])))
        for i in self["vIn"]:
            # skip all other inputs for SIGHASH_ANYONECANPAY case
            if (sighash_type & SIGHASH_ANYONECANPAY) and (n != i):
                continue
            sequence = self["vIn"][i]["sequence"]
            if ((sighash_type & 31) == SIGHASH_SINGLE or (sighash_type & 31) == SIGHASH_NONE) and (n != i):
                sequence = 0
            tx_id = self["vIn"][i]["txId"]
            if isinstance(tx_id, str):
                tx_id = s2rh(tx_id)

            if n == i:
                pm += b"%s%s%s%s%s" % (tx_id, pack('<L', self["vIn"][i]["vOut"]),
                                       int_to_var_int(len(script_code)),
                                       script_code, pack('<L', sequence))
            else:
                pm += b'%s%s\x00%s' % (tx_id,
                                       pack('<L', self["vIn"][i]["vOut"]),
                                       pack('<L', sequence))
        if (sighash_type & 31) == SIGHASH_NONE:
            pm += b'\x00'
        else:
            if (sighash_type & 31) == SIGHASH_SINGLE:
                pm += int_to_var_int(n + 1)
            else:
                pm += int_to_var_int(len(self["vOut"]))

        if (sighash_type & 31) != SIGHASH_NONE:
            for i in self["vOut"]:
                script_pub_key = self["vOut"][i]["scriptPubKey"]
                if isinstance(self["vOut"][i]["scriptPubKey"], str):
                    script_pub_key = bytes_from_hex(script_pub_key)
                if i > n and (sighash_type & 31) == SIGHASH_SINGLE:
                    continue
                if (sighash_type & 31) == SIGHASH_SINGLE and (n != i):
                    pm += b"%s%s" % (b'\xff' * 8, b'\x00')
                else:
                    pm += b"%s%s%s" % (self["vOut"][i]["value"].to_bytes(8, 'little'),
                                       int_to_var_int(len(script_pub_key)),
                                       script_pub_key)
        pm += b"%s%s" % (self["lockTime"].to_bytes(4, 'little'), pack(b"<i", sighash_type))
        if not preimage:
            pm = double_sha256(pm)
        return pm if self["format"] == "raw" else rh2s(pm)
Esempio n. 27
0
    def __init__(self, raw_tx=None, format="decoded", version=1, lock_time=0, testnet=False, auto_commit=True):
        if format not in ("decoded", "raw"):
            raise ValueError("format error, raw or decoded allowed")
        self.auto_commit = auto_commit
        self["format"] = format
        self["testnet"] = testnet
        self["segwit"] = False
        self["txId"] = None
        self["hash"] = None
        self["version"] = version
        self["size"] = 0
        self["vSize"] = 0
        self["bSize"] = 0
        self["lockTime"] = lock_time
        self["vIn"] = dict()
        self["vOut"] = dict()
        self["rawTx"] = None
        self["blockHash"] = None
        self["confirmations"] = None
        self["time"] = None
        self["blockTime"] = None
        self["blockIndex"] = None
        self["coinbase"] = False
        self["fee"] = None
        self["data"] = None
        self["amount"] = None
        if raw_tx is None:
            return

        self["amount"] = 0
        sw = sw_len = 0
        stream = self.get_stream(raw_tx)
        start = stream.tell()
        read = stream.read
        tell = stream.tell
        seek = stream.seek
        # start deserialization
        self["version"] = unpack('<L', read(4))[0]
        n = read_var_int(stream)

        if n == b'\x00':
            # segwit format
            sw = 1
            self["flag"] = read(1)
            n = read_var_int(stream)

        # inputs
        ic = var_int_to_int(n)
        for k in range(ic):
            self["vIn"][k] = dict()
            self["vIn"][k]["txId"] = read(32)
            self["vIn"][k]["vOut"] = unpack('<L', read(4))[0]
            self["vIn"][k]["scriptSig"] = read(var_int_to_int(read_var_int(stream)))
            self["vIn"][k]["sequence"] = unpack('<L', read(4))[0]

        # outputs
        for k in range(var_int_to_int(read_var_int(stream))):
            self["vOut"][k] = dict()
            self["vOut"][k]["value"] = unpack('<Q', read(8))[0]
            self["amount"] += self["vOut"][k]["value"]
            self["vOut"][k]["scriptPubKey"] = read(var_int_to_int(read_var_int(stream)))
            s = parse_script(self["vOut"][k]["scriptPubKey"])
            self["vOut"][k]["nType"] = s["nType"]
            self["vOut"][k]["type"] = s["type"]
            if self["data"] is None:
                if s["nType"] == 3:
                    self["data"] = s["data"]
            if s["nType"] not in (3, 4, 7, 8):
                self["vOut"][k]["addressHash"] = s["addressHash"]
                self["vOut"][k]["reqSigs"] = s["reqSigs"]

        # witness
        if sw:
            sw = tell() - start
            for k in range(ic):
                self["vIn"][k]["txInWitness"] = [read(var_int_to_int(read_var_int(stream))) \
                                                 for c in range(var_int_to_int(read_var_int(stream)))]
            sw_len = (stream.tell() - start) - sw + 2

        self["lockTime"] = unpack('<L', read(4))[0]

        end = tell()
        seek(start)
        b = read(end - start)
        self["rawTx"] = b
        self["size"] = end - start
        self["bSize"] = end - start - sw_len
        self["weight"] = self["bSize"] * 3 + self["size"]
        self["vSize"] = ceil(self["weight"] / 4)
        if ic == 1 and \
                        self["vIn"][0]["txId"] == b'\x00' * 32 and \
                        self["vIn"][0]["vOut"] == 0xffffffff:
            self["coinbase"] = True
        else:
            self["coinbase"] = False
        if sw:
            self["segwit"] = True
            self["hash"] = double_sha256(b)
            self["txId"] = double_sha256(b"%s%s%s" % (b[:4], b[6:sw],b[-4:]))
        else:
            self["segwit"] = False
            self["txId"] = double_sha256(b)
            self["hash"] = self["txId"]
        if self["format"] == "decoded":
            self.decode()