Esempio n. 1
0
    def __init__(self,
                 key=None,
                 address_type="P2WPKH",
                 testnet=False,
                 compressed=True):
        if key is None:
            #: instance of ``PrivateKey`` class
            self.private_key = PrivateKey(testnet=testnet,
                                          compressed=compressed)
            #: instance of ``PublicKey`` class
            self.public_key = PublicKey(self.private_key)
            #: flag for testnet network address  (boolean)
            self.testnet = testnet
        if isinstance(key, str) or isinstance(key, bytes):
            key = PrivateKey(key, testnet=testnet, compressed=compressed)
        if isinstance(key, PrivateKey):
            self.private_key = key
            self.testnet = key.testnet
            compressed = key.compressed
            self.public_key = PublicKey(self.private_key)
        elif isinstance(key, PublicKey):
            self.public_key = key
            self.testnet = testnet
            compressed = key.compressed
        if address_type not in ("P2PKH", "PUBKEY", "P2WPKH", "P2SH_P2WPKH"):
            raise TypeError("address type invalid")
        if not compressed:
            if address_type not in ("P2PKH", "PUBKEY", "P2SH"):
                raise TypeError("compressed public key invalid")
        #: flag for testnet network address  (boolean)
        self.type = address_type

        if address_type == "PUBKEY":
            self.pubkey_script = b"%s%s" % (op_push_data(
                self.public_key.key), OP_CHECKSIG)
            self.pubkey_script_hex = self.pubkey_script.hex()
            #: version of witness program for SEGWIT address (string)
        self.witness_version = 0 if address_type == "P2WPKH" else None
        self.compressed = compressed
        if address_type == "P2SH_P2WPKH":
            #: flag for script hash address (boolean)
            self.script_hash = True
            #: redeeem script, only for P2SH_P2WPKH (bytes)
            self.redeem_script = public_key_to_p2sh_p2wpkh_script(
                self.public_key.key)
            #: redeeem script HEX, only for P2SH_P2WPKH (string)
            self.redeem_script_hex = self.redeem_script.hex()
            #: address hash
            self.hash = hash160(self.redeem_script)
            self.witness_version = None
        else:
            self.script_hash = False
            self.hash = hash160(self.public_key.key)
        #: address hash HEX (string)
        self.hash_hex = self.hash.hex()
        #: address in base58 or bech32 encoding (string)
        self.address = hash_to_address(self.hash,
                                       script_hash=self.script_hash,
                                       witness_version=self.witness_version,
                                       testnet=self.testnet)
Esempio n. 2
0
    def add_output(self, amount, address=None, script_pub_key=None):
        if address is None and script_pub_key is None:
            raise Exception("unable to add output, address or script required")
        if type(amount) != int:
            raise TypeError("unable to add output, amount type error")
        if amount < 0 or amount > MAX_AMOUNT:
            raise Exception("unable to add output, amount value error")
        if script_pub_key:
            if isinstance(script_pub_key, str):
                script_pub_key = bytes_from_hex(script_pub_key)
            if not isinstance(script_pub_key, bytes):
                raise TypeError("unable to add output, script_pub_key type error")
        else:
            if type(address) == Address:
                address = address.address
            script_pub_key = address_to_script(address)

        k = len(self["vOut"])
        self["vOut"][k] = dict()
        self["vOut"][k]["value"] = amount
        segwit = True if "segwit" in self else False
        s = parse_script(script_pub_key, segwit)
        self["vOut"][k]["nType"] = s["nType"]
        self["vOut"][k]["type"] = s["type"]

        if self["format"] == "raw":
            self["vOut"][k]["scriptPubKey"] = script_pub_key
            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"]
        else:
            self["vOut"][k]["scriptPubKey"] = script_pub_key.hex()
            if self["data"] is None:
                if s["nType"] == 3:
                    self["data"] = s["data"].hex()
            if s["nType"] not in (3, 4, 7, 8):
                self["vOut"][k]["addressHash"] = s["addressHash"].hex()
                self["vOut"][k]["reqSigs"] = s["reqSigs"]
            self["vOut"][k]["scriptPubKeyOpcodes"] = decode_script(script_pub_key)
            self["vOut"][k]["scriptPubKeyAsm"] = decode_script(script_pub_key, 1)
            sh = True if self["vOut"][k]["nType"] in (1, 5) else False
            witness_version = None if self["vOut"][k]["nType"] < 5 else 0
            if "addressHash" in self["vOut"][k]:
                self["vOut"][k]["address"] = hash_to_address(self["vOut"][k]["addressHash"],
                                                             self["testnet"],
                                                             sh,
                                                             witness_version)
        if self.auto_commit:
            self.commit()
        return self
Esempio n. 3
0
def script_to_address(script, testnet=False):
    """
    Decode script to address (base58/bech32 format).

    :param script: script in bytes string or HEX encoded string format.
    :param testnet: (optional) flag for testnet network, by default is False.
    :return: address in base58/bech32 format or None.
    """
    d = parse_script(script)
    if "addressHash" in d:
        witness_version = 0 if d["nType"] in (5, 6) else None
        script_hash = True if d["nType"] in (1, 6) else False
        return hash_to_address(d["addressHash"], testnet=testnet,
                               script_hash=script_hash, witness_version=witness_version)
    return None
Esempio n. 4
0
 def __init__(self, script, testnet=False, witness_version=0):
     self.witness_version = witness_version
     self.testnet = testnet
     if isinstance(script, str):
         script = bytes.fromhex(script)
     self.script = script
     self.script_hex = self.script.hex()
     if witness_version is None:
         self.hash = hash160(self.script)
     else:
         self.hash = sha256(self.script)
     self.script_opcodes = decode_script(self.script)
     self.script_opcodes_asm = decode_script(self.script, 1)
     self.address = hash_to_address(self.hash,
                                    script_hash=True,
                                    witness_version=self.witness_version,
                                    testnet=self.testnet)
Esempio n. 5
0
    def decode(self, testnet=None):
        """
        change Transaction object representation to "decoded" human readable format

        :param bool testnet: (optional) address type for "decoded" transaction representation, by default None.
                            if None used type from transaction property "format".
        """
        if self["format"] == "decoded":
            self.encode()
        self["format"] = "decoded"
        if testnet is not None:
            self["testnet"] = testnet
        if type(self["txId"]) == bytes:
            self["txId"] = rh2s(self["txId"])
        if "flag" in self:
            if type(self["flag"]) == bytes:
                self["flag"] = rh2s(self["flag"])
        if type(self["hash"]) == bytes:
            self["hash"] = rh2s(self["hash"])
        if type(self["rawTx"]) == bytes:
            self["rawTx"] = self["rawTx"].hex()
        for i in self["vIn"]:
            if type(self["vIn"][i]["txId"]) == bytes:
                self["vIn"][i]["txId"] = rh2s(self["vIn"][i]["txId"])
            if type(self["vIn"][i]["scriptSig"]) == bytes:
                self["vIn"][i]["scriptSig"] = self["vIn"][i]["scriptSig"].hex()
            try:
                t = list()
                append = t.append
                for w in self["vIn"][i]["txInWitness"]:
                    if type(w) == bytes:
                        w = w.hex()
                    append(w)
                self["vIn"][i]["txInWitness"] = t

            except:
                pass
            try:
                if type(self["vIn"][i]["addressHash"]) == bytes:
                    self["vIn"][i]["addressHash"] = self["vIn"][i]["addressHash"].hex()
                sh = True if self["vIn"][i]["nType"] in (1, 5) else False
                witness_version = None if self["vIn"][i]["nType"] < 5 else 0
                self["vIn"][i]["address"] = hash_to_address(self["vIn"][i]["addressHash"],
                                                            self["testnet"],
                                                            sh,
                                                            witness_version)
            except:
                pass
            if "scriptPubKey" in self["vIn"][i]:
                if type(self["vIn"][i]["scriptPubKey"]) == bytes:
                    self["vIn"][i]["scriptPubKey"] = self["vIn"][i]["scriptPubKey"].hex()
                self["vIn"][i]["scriptPubKeyOpcodes"] = decode_script(self["vIn"][i]["scriptPubKey"])
                self["vIn"][i]["scriptPubKeyAsm"] = decode_script(self["vIn"][i]["scriptPubKey"], 1)
            if "redeemScript" in self["vIn"][i]:
                if type(self["vIn"][i]["redeemScript"]) == bytes:
                    self["vIn"][i]["redeemScript"] = self["vIn"][i]["redeemScript"].hex()
                self["vIn"][i]["redeemScriptOpcodes"] = decode_script(self["vIn"][i]["redeemScript"])
                self["vIn"][i]["redeemScriptAsm"] = decode_script(self["vIn"][i]["redeemScript"], 1)
            if not self["coinbase"]:
                if type(self["vIn"][i]["scriptSig"]) == bytes:
                    self["vIn"][i]["scriptSig"] = self["vIn"][i]["scriptSig"].hex()
                self["vIn"][i]["scriptSigOpcodes"] = decode_script(self["vIn"][i]["scriptSig"])
                self["vIn"][i]["scriptSigAsm"] = decode_script(self["vIn"][i]["scriptSig"], 1)

        for i in self["vOut"]:
            if type(self["vOut"][i]["scriptPubKey"]) == bytes:
                self["vOut"][i]["scriptPubKey"] = self["vOut"][i]["scriptPubKey"].hex()
            try:
                if type(self["vOut"][i]["addressHash"]) == bytes:
                    self["vOut"][i]["addressHash"] = self["vOut"][i]["addressHash"].hex()
                sh = True if self["vOut"][i]["nType"] in (1, 5) else False
                witness_version = None if self["vOut"][i]["nType"] < 5 else 0
                self["vOut"][i]["address"] = hash_to_address(self["vOut"][i]["addressHash"],
                                                             self["testnet"],
                                                             sh,
                                                             witness_version)
            except:
                pass
            self["vOut"][i]["scriptPubKeyOpcodes"] = decode_script(self["vOut"][i]["scriptPubKey"])
            self["vOut"][i]["scriptPubKeyAsm"] = decode_script(self["vOut"][i]["scriptPubKey"], 1)
        if "data" in self:
            if type(self["data"]) == bytes:
                self["data"] = self["data"].hex()
        return self
Esempio n. 6
0
def test_hash_to_address():
    pc = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
    h = hash160(pc)
    s = bytes([len(bytes_from_hex(pc))
               ]) + bytes_from_hex(pc) + BYTE_OPCODE["OP_CHECKSIG"]
    assert hash_to_address(h) == "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"
    assert hash_to_address(
        h, testnet=True) == "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"
    h = script_to_hash(s, witness=True, hex=hex)
    assert hash_to_address(
        h) == "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"
    assert hash_to_address(
        h, testnet=True
    ) == "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7"

    pk = "03b635dbdc16dbdf4bb9cf5b55e7d03e514fb04dcef34208155c7d3ec88e9045f4"
    h = hash160(pk)
    assert hash_to_address(
        h, witness_version=None) == "1Fs2Xqrk4P2XADaJeZWykaGXJ4HEb6RyT1"
    assert hash_to_address(
        h, witness_version=None,
        testnet=True) == "mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c"

    # p2wpkh inside p2sh
    p = "L32a8Mo1LgvjrVDbzcc3NkuUfkpoLsf2Y2oEWkV4t1KpQdFzuyff"
    pk = private_to_public_key(p)
    script = b'\x00\x14' + hash160(pk)
    script_hash = hash160(script)
    assert hash_to_address(
        script_hash, script_hash=1,
        witness_version=None) == "33am12q3Bncnn3BfvLYHczyv23Sq2Wbwjw"
    assert hash_to_address(script_hash,
                           script_hash=1,
                           witness_version=None,
                           testnet=1) == "2Mu8y4mm4oF88yppDbUAAEwyBEPezrx7CLh"

    with pytest.raises(ValueError):
        hash_to_address(29023)
    with pytest.raises(ValueError):
        hash_to_address(h + b"33", witness_version=None)
    with pytest.raises(ValueError):
        hash_to_address(h + b"33", witness_version=0)