Exemplo n.º 1
0
def generate_btc_addr(pk, v='test', compressed=True):
    """ Calculates Bitcoin address associated to a given elliptic curve public key and a given network.

    :param pk: ECDSA VerifyingKey object (public key to be converted into Bitcoin address).
    :type pk: VerifyingKey
    :param v: version (prefix) used to calculate the WIF, it depends on the type of network.
    :type v: str
    :param compressed: Indicates if Bitcoin address will be generated with the compressed or uncompressed key.
    :type compressed: bool
    :return: The Bitcoin address associated to the given public key and network.
    :rtype: str
    """

    # Get the hex representation of the provided DER encoded public key.
    public_key_hex = serialize_pk(pk, compressed)
    # Generate the Bitcoin address of de desired network.
    btc_addr = pk_to_btc_addr(public_key_hex, v)

    return btc_addr
Exemplo n.º 2
0
    def sign(self,
             sk,
             index,
             hashflag=SIGHASH_ALL,
             compressed=True,
             orphan=False,
             deterministic=True,
             network='test'):
        """ Signs a transaction using the provided private key(s), index(es) and hash type. If more than one key and index
        is provides, key i will sign the ith input of the transaction.
        :param sk: Private key(s) used to sign the ith transaction input (defined by index).
        :type sk: SigningKey or list of SigningKey.
        :param index: Index(es) to be signed by the provided key(s).
        :type index: int or list of int
        :param hashflag: Hash type to be used. It will define what signature format will the unsigned transaction have.
        :type hashflag: int
        :param compressed: Indicates if the public key that goes along with the signature will be compressed or not.
        :type compressed: bool
        :param orphan: Whether the inputs to be signed are orphan or not. Orphan inputs are those who are trying to
        redeem from a utxo that has not been included in the blockchain or has not been seen by other nodes.
        Orphan inputs must provide a dict with the index of the input and an OutputScript that matches the utxo to be
        redeemed.
            e.g:
              orphan_input = dict({0: OutputScript.P2PKH(btc_addr))
        :type orphan:  dict(index, InputScript)
        :param deterministic: Whether the signature is performed using a deterministic k or not. Set by default.
        :type deterministic: bool
        :param network: Network from which the previous ScripPubKey will be queried (either main or test).
        :type network: str
        :return: Transaction signature.
        :rtype: str
        """

        # Normalize all parameters
        if isinstance(sk, list) and isinstance(index, int):
            # In case a list for multisig is received as only input.
            sk = [sk]
        if isinstance(sk, SigningKey):
            sk = [sk]
        if isinstance(index, int):
            index = [index]

        for i in range(len(sk)):

            # If the input to be signed is orphan, the OutputScript of the UTXO to be redeemed will be passed to
            # the signature_format function, otherwise False is passed and the UTXO will be requested afterwards.
            o = orphan if not orphan else orphan.get(i)
            # The unsigned transaction is formatted depending on the input that is going to be signed. For input i,
            # the ScriptSig[i] will be set to the scriptPubKey of the UTXO that input i tries to redeem, while all
            # the other inputs will be set blank.
            unsigned_tx = self.signature_format(index[i], hashflag, o, network)

            # Then, depending on the format how the private keys have been passed to the signing function
            # and the content of the ScripSig field, a different final scriptSig will be created.
            if isinstance(
                    sk[i],
                    list) and unsigned_tx.scriptSig[index[i]].type is "P2MS":
                sigs = []
                for k in sk[i]:
                    sigs.append(
                        ecdsa_tx_sign(unsigned_tx.serialize(), k, hashflag,
                                      deterministic))
                iscript = InputScript.P2MS(sigs)
            elif isinstance(sk[i], SigningKey) and unsigned_tx.scriptSig[
                    index[i]].type is "P2PK":
                s = ecdsa_tx_sign(unsigned_tx.serialize(), sk[i], hashflag,
                                  deterministic)
                iscript = InputScript.P2PK(s)
            elif isinstance(sk[i], SigningKey) and unsigned_tx.scriptSig[
                    index[i]].type is "P2PKH":
                s = ecdsa_tx_sign(unsigned_tx.serialize(), sk[i], hashflag,
                                  deterministic)
                pk = serialize_pk(sk[i].get_verifying_key(), compressed)
                iscript = InputScript.P2PKH(s, pk)
            elif unsigned_tx.scriptSig[index[i]].type is "unknown":
                raise Exception(
                    "Unknown previous transaction output script type. Can't sign the transaction."
                )
            else:
                raise Exception("Can't sign input " + str(i) +
                                " with the provided data.")

            # Finally, temporal scripts are stored as final and the length of the script is computed
            self.scriptSig[i] = iscript
            self.scriptSig_len[i] = len(iscript.content) / 2

        self.hex = self.serialize()
Exemplo n.º 3
0
    sks.append(sk)
    pks.append(pk)

for i in range(3):
    if i is 0:
        print "\n#############\n# FROM P2PK #\n#############"
        sk = sks[i]
    elif i is 1:
        print "##############\n# FROM P2PKH #\n##############"
        sk = sks[i]
    elif i is 2:
        print "#############\n# FROM P2MS #\n#############"
        sk = sks[:i]
    for j in range(3):
        if j is 0:
            print "\nTO: P2PK\n"
            dest = serialize_pk(pks[j])
        elif j is 1:
            print "\nTO: P2PKH\n"
            dest = btc_addrs[j]
        elif j is 2:
            print "\nTO: P2MS\n"
            dest = [2, serialize_pk(pks[0]), serialize_pk(pks[1])]

        tx = TX.build_from_io(prev_tx_ids[i], prev_out_index[i], value, dest)
        tx.sign(sk, 0)
        print tx.serialize()
        tx.display()

    print "\n---------------------------------------------------------------------------------------------\n"
Exemplo n.º 4
0
keys = map(load_keys, source_btc_addrs)
sks = [k[0] for k in keys]
pks = [k[1] for k in keys]

# Amount to be spent, in Satoshi, and the fee to be deduced (should be calculated).
value = utxo.get('value')
fee = 230 * 240

# Now we can build the transaction from inputs/outputs.
# We will create a 2-3 P2MS from a 1-3 P2MS, so we need to include 1 signature to redeem the previous utxo, and include
# a 2-3 script to create the new one.

# To create the destination script, we need to include first the number of required signatures (2), and then, the
# all the public keys.
destination = [
    2, serialize_pk(pks[0]),
    serialize_pk(pks[1]),
    serialize_pk(pks[2])
]
# Using map will also do the trick.
# destination = [2] + map(serialize_pk, pks)

# Now we can create the transaction. Since we owe all the keys, we can choose any one of the tree to sign it.
tx = TX.build_from_io(prev_tx_id, prev_out_index, value - fee, destination)
tx.sign(sks[0], 0)

# Once created we can display the serialized transaction. Transaction is now ready to be broadcast.
print "hex: " + tx.serialize()

# Finally, we can analyze each field of the transaction.
tx.display()
Exemplo n.º 5
0
source_btc_addrs = utxo.get('btc_addr')
keys = map(load_keys, source_btc_addrs)
sks = [k[0] for k in keys]
pks = [k[1] for k in keys]

# Amount to be spent, in Satoshi, and the fee to be deduced (should be calculated).
value = utxo.get('value')
fee = 230 * 240

# Now we can build the transaction from inputs/outputs.
# We will create a 2-3 P2MS from a 1-3 P2MS, so we need to include 1 signature to redeem the previous utxo, and include
# a 2-3 script to create the new one.

# To create the destination script, we need to include first the number of required signatures (2), and then, the
# all the public keys.
destination = [2, serialize_pk(pks[0]), serialize_pk(pks[1]),  serialize_pk(pks[2])]
# Using map will also do the trick.
# destination = [2] + map(serialize_pk, pks)

# Now we can create the transaction. Since we owe all the keys, we can choose any one of the tree to sign it.
tx = TX.build_from_io(prev_tx_id, prev_out_index, value - fee, destination)
tx.sign(sks[0], 0)

# Once created we can display the serialized transaction. Transaction is now ready to be broadcast.
print "hex: " + tx.serialize()

# Finally, we can analyze each field of the transaction.
tx.display()