Esempio n. 1
0
    def __bytes__(self):
        """ Serializes the object into a byte stream.

        Returns:
            b (bytes): byte stream containing the serialized
            transaction output.
        """
        return pack_u64(self.value) + pack_var_str(bytes(self.script))
Esempio n. 2
0
    def __bytes__(self):
        """ Serializes the object into a byte stream.

        Returns:
            b (bytes): byte stream containing the serialized input.
        """
        return (bytes(self.outpoint) + pack_u32(self.outpoint_index) +
                pack_var_str(bytes(self.script)) + pack_u32(self.sequence_num))
Esempio n. 3
0
    def __bytes__(self):
        """ Serializes the object into a byte stream.

        Returns:
            b (bytes): byte stream containing the serialized
            transaction output.
        """
        return pack_u64(self.value) + pack_var_str(bytes(self.script))
Esempio n. 4
0
    def __bytes__(self):
        """ Serializes the object into a byte stream.

        Returns:
            b (bytes): byte stream containing the serialized input.
        """
        return (
            bytes(self.outpoint)
            + pack_u32(self.outpoint_index)
            + pack_var_str(bytes(self.script))
            + pack_u32(self.sequence_num)
        )
Esempio n. 5
0
    def from_hex(h, size_prepended=False):
        """ Deserializes a hex-encoded string into a Script.

        Args:
            h (str): hex-encoded string, starting with the length of
                the script as a compact int.
            size_prepended (bool): Should be True if the size of the
                script has already been prepended.

        Returns:
            Script: A Script object.
        """
        b = bytes.fromhex(h)
        if not size_prepended:
            b = pack_var_str(b)
        s, _ = Script.from_bytes(b)
        return s
Esempio n. 6
0
    def from_hex(h, size_prepended=False):
        """ Deserializes a hex-encoded string into a Script.

        Args:
            h (str): hex-encoded string, starting with the length of
                the script as a compact int.
            size_prepended (bool): Should be True if the size of the
                script has already been prepended.

        Returns:
            Script: A Script object.
        """
        b = bytes.fromhex(h)
        if not size_prepended:
            b = pack_var_str(b)
        s, _ = Script.from_bytes(b)
        return s
Esempio n. 7
0
    def get_utxos(self, address_list):
        """ Provides all unspent transactions associated with each address in
            the address_list.

        Args:
            address_list (list(str)): List of Base58Check encoded Bitcoin
            addresses.

        Returns:
            dict: A dict keyed by address with each value being a list of
               UnspentTransactionOutput objects.
        """
        ret = defaultdict(list)
        for addresses in self._list_chunks(address_list, 199):
            r = self._request("GET", "addresses/" + ",".join(addresses)
                              + "/unspents")
            data = r.json()

            # for each address
            # {
            #     "transaction_hash": "0bf0de38c261...",
            #     "output_index": 0,
            #     "value": 290000,
            #     "addresses": [
            #         "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb"
            #     ],
            #     "script": "OP_DUP OP_HASH160 c6296...",
            #     "script_hex": "76a914c629680b8d1...",
            #     "script_type": "pubkeyhash",
            #     "required_signatures": 1,
            #     "spent": false,
            #     "confirmations": 8758
            # },

            for d in data:
                address = d["addresses"][0]
                txn_hash = Hash(d["transaction_hash"])
                script, _ = Script.from_bytes(
                    pack_var_str(bytes.fromhex(d["script_hex"])))
                ret[address].append(UnspentTransactionOutput(txn_hash,
                                                             d["output_index"],
                                                             d["value"],
                                                             script,
                                                             d["confirmations"]))
        return ret
Esempio n. 8
0
    def build_multisig_sig(sigs, redeem_script):
        """ Builds a multisig signature script.

            This script contains the signatures in order given
            in sigs as well as the redeem script. It is not required
            to have all required signatures in sigs. However, len(sigs)
            may not be more than the max number indicated by the redeem
            script.

        Args:
            sigs (list(bytes)): A list of signatures (in DER encoding). The
                hash_type must already be appended to the byte string for each
                signature. This function will take care of the relevant data
                push operations.
            redeem_script (Script): The script used to redeem the coins.

        Returns:
            Script: A multisig signature script. Note: if len(sigs) is less
               than the minimum number required, the script will not be valid.
        """
        multisig_params = redeem_script.extract_multisig_redeem_info()

        if len(sigs) > multisig_params['n']:
            raise ValueError("Too many signatures: %d (given) > %d (max. required)." %
                             len(sigs),
                             multisig_params['n'])

        # To correct for the early bitcoin-core off-by-1 error.
        scr = bytes([0x00])

        for s in sigs:
            scr += pack_var_str(s)

        scr += Script.build_push_str(bytes(redeem_script))

        return Script(scr)
Esempio n. 9
0
    def txn_from_json(txn_json):
        # {
        # "hash": "0bf0de38c26195919179f...",
        # "block_hash": "000000000000000...",
        # "block_height": 303404,
        # "block_time": "2014-05-30T23:54:55Z",
        # "chain_received_at": "2015-08-13T10:52:21.718Z",
        # "confirmations": 69389,
        # "lock_time": 0,
        # "inputs": [
        #   {
        #     "transaction_hash": "0bf0de38c2619...",
        #     "output_hash": "b84a66c46e24fe71f9...",
        #     "output_index": 0,
        #     "value": 300000,
        #     "addresses": [
        #       "3L7dKYQGNoZub928CJ8NC2WfrM8U8GGBjr"
        #     ],
        #     "script_signature": "03046022100de7b67b9...",
        #     "script_signature_hex": "00493046022100de7b...",
        #     "sequence": 4294967295
        #   }
        # ],
        # "outputs": [
        #   {
        #     "transaction_hash": "0bf0de38c261959...",
        #     "output_index": 0,
        #     "value": 290000,
        #     "addresses": [
        #       "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb"
        #     ],
        #     "script": "OP_DUP OP_HASH160 c629680b8d...",
        #     "script_hex": "76a914c629680b8d13...",
        #     "script_type": "pubkeyhash",
        #     "required_signatures": 1,
        #     "spent": false,
        #     "spending_transaction": null
        #   }
        # ],
        # "fees": 10000,
        # "amount": 290000
        # },
        # Transaction.DEFAULT_TRANSACTION_VERSION
        inputs = []
        outputs = []
        addr_keys = set()
        for i in txn_json["inputs"]:
            # Chain doesn't return the stuff about script length etc, so
            # we need to prepend that.
            script, _ = Script.from_bytes(
                pack_var_str(bytes.fromhex(i["script_signature_hex"])))
            inputs.append(TransactionInput(Hash(i["output_hash"]),
                                           i["output_index"],
                                           script,
                                           i["sequence"]))
            if "addresses" in i:
                addr_keys.add(i["addresses"][0])

        for i in txn_json["outputs"]:
            script, _ = Script.from_bytes(
                pack_var_str(bytes.fromhex(i["script_hex"])))
            outputs.append(TransactionOutput(i["value"],
                                             script))
            if "addresses" in i:
                addr_keys.add(i["addresses"][0])

        txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION,
                          inputs,
                          outputs,
                          txn_json["lock_time"])

        return txn, addr_keys
Esempio n. 10
0
    def txn_from_json(txn_json):
        """ Returns a new Transaction from a JSON-serialized transaction

        Args:
            txn_json: JSON with the following format:

        {
        "hash": "0bf0de38c26195919179f...",
        "block_hash": "000000000000000...",
        "block_height": 303404,
        "block_time": "2014-05-30T23:54:55Z",
        "chain_received_at": "2015-08-13T10:52:21.718Z",
        "confirmations": 69389,
        "lock_time": 0,
        "inputs": [
          {
            "transaction_hash": "0bf0de38c2619...",
            "output_hash": "b84a66c46e24fe71f9...",
            "output_index": 0,
            "value": 300000,
            "addresses": [
              "3L7dKYQGNoZub928CJ8NC2WfrM8U8GGBjr"
            ],
            "script_signature": "03046022100de7b67b9...",
            "script_signature_hex": "00493046022100de7b...",
            "sequence": 4294967295
          }
        ],
        "outputs": [
          {
            "transaction_hash": "0bf0de38c261959...",
            "output_index": 0,
            "value": 290000,
            "addresses": [
              "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb"
            ],
            "script": "OP_DUP OP_HASH160 c629680b8d...",
            "script_hex": "76a914c629680b8d13...",
            "script_type": "pubkeyhash",
            "required_signatures": 1,
            "spent": false,
            "spending_transaction": null
          }
        ],
        "fees": 10000,
        "amount": 290000
        },
        Transaction.DEFAULT_TRANSACTION_VERSION

        Returns:
            two1.lib.bitcoin.Transaction: a deserialized transaction derived
                from the provided json.

        """
        inputs = []
        outputs = []
        addr_keys = set()
        for i in txn_json["inputs"]:
            if 'coinbase' in i:
                inputs.append(
                    CoinbaseInput(height=txn_json["block_height"] or 0,
                                  raw_script=bytes.fromhex(i['coinbase']),
                                  sequence=i['sequence'],
                                  block_version=1))
            else:
                # Script length etc. are not returned so we need to
                # prepend that.
                script, _ = Script.from_bytes(
                    pack_var_str(bytes.fromhex(i["script_signature_hex"])))
                inputs.append(
                    TransactionInput(Hash(i["output_hash"]), i["output_index"],
                                     script, i["sequence"]))
            if "addresses" in i:
                addr_keys.add(i["addresses"][0])

        for i in txn_json["outputs"]:
            script, _ = Script.from_bytes(
                pack_var_str(bytes.fromhex(i["script_hex"])))
            outputs.append(TransactionOutput(i["value"], script))
            if "addresses" in i:
                addr_keys.add(i["addresses"][0])

        txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, inputs,
                          outputs, txn_json["lock_time"])

        return txn, addr_keys
Esempio n. 11
0
    def txn_from_json(txn_json):
        """
        Args:
            txn_json: Json with the following format:
        {
        "block_hash": "0000000000000000af64802c79...",
        "block_height": 292586,
        "hash": "b4735a0690dab16b8789fceaf81c511f...",
        "addresses": [
            "18KXZzuC3xvz6upUMQpsZzXrBwNPWZjdSa",
            "1AAuRETEcHDqL4VM3R97aZHP8DSUHxpkFV",
            "1DEP8i3QJCsomS4BSMY2RpU1upv62aGvhD",
            "1VxsEDjo6ZLMT99dpcLu4RQonMDVEQQTG"
        ],
        "total": 3537488,
        "fees": 20000,
        "size": 438,
        "preference": "medium",
        "relayed_by": "",
        "confirmed": "2014-03-26T17:08:04Z",
        "received": "2014-03-26T17:08:04Z",
        "ver": 1,
        "lock_time": 0,
        "double_spend": false,
        "vin_sz": 2,
        "vout_sz": 2,
        "confirmations": 64492,
        "confidence": 1,
        "inputs": [
        {
            "prev_hash": "729f6469b59fea5da7...",
            "output_index": 0,
            "script": "483045022100d06cdad1a...",
            "output_value": 3500000,
            "sequence": 4294967295,
            "addresses": [
                "1VxsEDjo6ZLMT99dpcLu4RQonMDVEQQTG"
            ],
            "script_type": "pay-to-pubkey-hash"
        },
        ...
        ],
        "outputs": [
        {
             "value": 3500000,
             "script": "76a9148629647bd642a237...",
             "addresses": [
                 "1DEP8i3QJCsomS4BSMY2RpU1upv62aGvhD"
             ],
             "script_type": "pay-to-pubkey-hash"
        }
        ]...

        Returns: An Object of type Transaction

        """

        inputs = []
        outputs = []
        addr_keys = set()
        for i in txn_json["inputs"]:
            # Chain doesn't return the stuff about script length etc, so
            # we need to prepend that.
            script, _ = Script.from_bytes(
                pack_var_str(bytes.fromhex(i["script"])))
            inputs.append(
                TransactionInput(Hash(i["prev_hash"]), i["output_index"],
                                 script, i["sequence"]))
            if "addresses" in i and i["addresses"]:
                addr_keys.add(i["addresses"][0])

        for i in txn_json["outputs"]:
            script, _ = Script.from_bytes(
                pack_var_str(bytes.fromhex(i["script"])))
            outputs.append(TransactionOutput(i["value"], script))
            if "addresses" in i and i["addresses"]:
                addr_keys.add(i["addresses"][0])

        txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, inputs,
                          outputs, txn_json["lock_time"])

        return txn, addr_keys
Esempio n. 12
0
    def txn_from_json(txn_json):
        """ Returns a new Transaction from a JSON-serialized transaction

        Args:
            txn_json: JSON with the following format:

        {
        "hash": "0bf0de38c26195919179f...",
        "block_hash": "000000000000000...",
        "block_height": 303404,
        "block_time": "2014-05-30T23:54:55Z",
        "chain_received_at": "2015-08-13T10:52:21.718Z",
        "confirmations": 69389,
        "lock_time": 0,
        "inputs": [
          {
            "transaction_hash": "0bf0de38c2619...",
            "output_hash": "b84a66c46e24fe71f9...",
            "output_index": 0,
            "value": 300000,
            "addresses": [
              "3L7dKYQGNoZub928CJ8NC2WfrM8U8GGBjr"
            ],
            "script_signature": "03046022100de7b67b9...",
            "script_signature_hex": "00493046022100de7b...",
            "sequence": 4294967295
          }
        ],
        "outputs": [
          {
            "transaction_hash": "0bf0de38c261959...",
            "output_index": 0,
            "value": 290000,
            "addresses": [
              "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb"
            ],
            "script": "OP_DUP OP_HASH160 c629680b8d...",
            "script_hex": "76a914c629680b8d13...",
            "script_type": "pubkeyhash",
            "required_signatures": 1,
            "spent": false,
            "spending_transaction": null
          }
        ],
        "fees": 10000,
        "amount": 290000
        },
        Transaction.DEFAULT_TRANSACTION_VERSION

        Returns:
            two1.lib.bitcoin.Transaction: a deserialized transaction derived
                from the provided json.

        """
        inputs = []
        outputs = []
        addr_keys = set()
        for i in txn_json["inputs"]:
            if 'coinbase' in i:
                inputs.append(
                    CoinbaseInput(
                        height=txn_json["block_height"] or 0,
                        raw_script=bytes.fromhex(i['coinbase']),
                        sequence=i['sequence'],
                        block_version=1))
            else:
                # Script length etc. are not returned so we need to
                # prepend that.
                script, _ = Script.from_bytes(
                    pack_var_str(bytes.fromhex(i["script_signature_hex"])))
                inputs.append(TransactionInput(Hash(i["output_hash"]),
                                               i["output_index"],
                                               script,
                                               i["sequence"]))
            if "addresses" in i:
                addr_keys.add(i["addresses"][0])

        for i in txn_json["outputs"]:
            script, _ = Script.from_bytes(
                pack_var_str(bytes.fromhex(i["script_hex"])))
            outputs.append(TransactionOutput(i["value"],
                                             script))
            if "addresses" in i:
                addr_keys.add(i["addresses"][0])

        txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION,
                          inputs,
                          outputs,
                          txn_json["lock_time"])

        return txn, addr_keys
Esempio n. 13
0
    def txn_from_json(txn_json):
        """
        Args:
            txn_json: Json with the following format:
        {
        "block_hash": "0000000000000000af64802c79...",
        "block_height": 292586,
        "hash": "b4735a0690dab16b8789fceaf81c511f...",
        "addresses": [
            "18KXZzuC3xvz6upUMQpsZzXrBwNPWZjdSa",
            "1AAuRETEcHDqL4VM3R97aZHP8DSUHxpkFV",
            "1DEP8i3QJCsomS4BSMY2RpU1upv62aGvhD",
            "1VxsEDjo6ZLMT99dpcLu4RQonMDVEQQTG"
        ],
        "total": 3537488,
        "fees": 20000,
        "size": 438,
        "preference": "medium",
        "relayed_by": "",
        "confirmed": "2014-03-26T17:08:04Z",
        "received": "2014-03-26T17:08:04Z",
        "ver": 1,
        "lock_time": 0,
        "double_spend": false,
        "vin_sz": 2,
        "vout_sz": 2,
        "confirmations": 64492,
        "confidence": 1,
        "inputs": [
        {
            "prev_hash": "729f6469b59fea5da7...",
            "output_index": 0,
            "script": "483045022100d06cdad1a...",
            "output_value": 3500000,
            "sequence": 4294967295,
            "addresses": [
                "1VxsEDjo6ZLMT99dpcLu4RQonMDVEQQTG"
            ],
            "script_type": "pay-to-pubkey-hash"
        },
        ...
        ],
        "outputs": [
        {
             "value": 3500000,
             "script": "76a9148629647bd642a237...",
             "addresses": [
                 "1DEP8i3QJCsomS4BSMY2RpU1upv62aGvhD"
             ],
             "script_type": "pay-to-pubkey-hash"
        }
        ]...

        Returns: An Object of type Transaction

        """

        inputs = []
        outputs = []
        addr_keys = set()
        for i in txn_json["inputs"]:
            # Chain doesn't return the stuff about script length etc, so
            # we need to prepend that.
            script, _ = Script.from_bytes(
                pack_var_str(bytes.fromhex(i["script"])))
            inputs.append(TransactionInput(Hash(i["prev_hash"]),
                                           i["output_index"],
                                           script,
                                           i["sequence"]))
            if "addresses" in i and i["addresses"]:
                addr_keys.add(i["addresses"][0])

        for i in txn_json["outputs"]:
            script, _ = Script.from_bytes(
                pack_var_str(bytes.fromhex(i["script"])))
            outputs.append(TransactionOutput(i["value"],
                                             script))
            if "addresses" in i and i["addresses"]:
                addr_keys.add(i["addresses"][0])

        txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION,
                          inputs,
                          outputs,
                          txn_json["lock_time"])

        return txn, addr_keys
Esempio n. 14
0
    def sign_input(self, input_index, hash_type, private_key, sub_script):
        """ Signs an input.

        Args:
            input_index (int): The index of the input to sign.
            hash_type (int): What kind of signature hash to do.
            private_key (crypto.PrivateKey): private key with which
                to sign the transaction.
            sub_script (Script): the scriptPubKey of the corresponding
                utxo being spent if the outpoint is P2PKH or the redeem
                script if the outpoint is P2SH.
        """
        if input_index < 0 or input_index >= len(self.inputs):
            raise ValueError("Invalid input index.")

        inp = self.inputs[input_index]

        curr_script_sig = inp.script
        multisig = False
        multisig_params = None
        multisig_key_index = -1
        if sub_script.is_multisig_redeem():
            multisig = True
            multisig_params = sub_script.extract_multisig_redeem_info()
        elif not sub_script.is_p2pkh():
            raise TypeError("Signing arbitrary redeem scripts is not currently supported.")

        tmp_script = sub_script.remove_op("OP_CODESEPARATOR")

        compressed = False
        if hash_type & 0x1f == self.SIG_HASH_SINGLE and len(self.inputs) > len(self.outputs):
            # This is to deal with the bug where specifying an index
            # that is out of range (wrt outputs) results in a
            # signature hash of 0x1 (little-endian)
            msg_to_sign = 0x1.to_bytes(32, 'little')
        else:
            txn_copy = self._copy_for_sig(input_index, hash_type, tmp_script)

            if multisig:
                # Determine which of the public keys this private key
                # corresponds to.
                public_keys = multisig_params['public_keys']
                pub_key_full = self._get_public_key_bytes(private_key, False)
                pub_key_comp = self._get_public_key_bytes(private_key, True)

                for i, p in enumerate(public_keys):
                    if pub_key_full == p or pub_key_comp == p:
                        multisig_key_index = i
                        break

                if multisig_key_index == -1:
                    raise ValueError(
                        "Public key derived from private key does not match any of the public keys in redeem script.")
            else:
                # Before signing we should verify that the address in the
                # sub_script corresponds to that of the private key
                script_pub_key_h160_hex = tmp_script.get_hash160()
                if script_pub_key_h160_hex is None:
                    raise ValueError("Couldn't find public key hash in sub_script!")

                # first try uncompressed key
                h160 = None
                for compressed in [True, False]:
                    h160 = private_key.public_key.hash160(compressed)
                    if h160 != bytes.fromhex(script_pub_key_h160_hex[2:]):
                        h160 = None
                    else:
                        break

                if h160 is None:
                    raise ValueError("Address derived from private key does not match sub_script!")

            msg_to_sign = bytes(Hash.dhash(bytes(txn_copy) +
                                           pack_u32(hash_type)))

        sig = private_key.sign(msg_to_sign, False)

        if multisig:
            # For multisig, we need to determine if there are already
            # signatures and if so, where we insert this signature
            inp.script = self._do_multisig_script([dict(index=multisig_key_index,
                                                        signature=sig)],
                                                  msg_to_sign,
                                                  curr_script_sig,
                                                  tmp_script,
                                                  hash_type)
        else:
            pub_key_bytes = self._get_public_key_bytes(private_key, compressed)
            pub_key_str = pack_var_str(pub_key_bytes)
            script_sig = pack_var_str(
                sig.to_der() + pack_compact_int(hash_type)) + pub_key_str
            inp.script = Script(script_sig)

        return True