Example #1
1
    def test_build_spends(self):
        # first, here is the tx database
        TX_DB = {}

        # create a coinbase Tx where we know the public & private key

        exponent = wif_to_secret_exponent("5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y")
        compressed = False

        public_key_sec = public_pair_to_sec(
            ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent), compressed=compressed
        )

        the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971)
        TX_DB[the_coinbase_tx.hash()] = the_coinbase_tx

        # now create a Tx that spends the coinbase

        compressed = False

        exponent_2 = int("137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16)
        bitcoin_address_2 = public_pair_to_bitcoin_address(
            ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_2), compressed=compressed
        )

        self.assertEqual("12WivmEn8AUth6x6U8HuJuXHaJzDw3gHNZ", bitcoin_address_2)

        coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])]
        coins_to = [(int(50 * 1e8), bitcoin_address_2)]
        unsigned_coinbase_spend_tx = standard_tx(coins_from, coins_to)
        solver = build_hash160_lookup([exponent])

        coinbase_spend_tx = unsigned_coinbase_spend_tx.sign(solver)

        # now check that it validates
        self.assertEqual(coinbase_spend_tx.bad_signature_count(), 0)

        TX_DB[coinbase_spend_tx.hash()] = coinbase_spend_tx

        ## now try to respend from priv_key_2 to priv_key_3

        compressed = True

        exponent_3 = int("f8d39b8ecd0e1b6fee5a340519f239097569d7a403a50bb14fb2f04eff8db0ff", 16)
        bitcoin_address_3 = public_pair_to_bitcoin_address(
            ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_3), compressed=compressed
        )

        self.assertEqual("13zzEHPCH2WUZJzANymow3ZrxcZ8iFBrY5", bitcoin_address_3)

        coins_from = [(coinbase_spend_tx.hash(), 0, coinbase_spend_tx.txs_out[0])]
        unsigned_spend_tx = standard_tx(coins_from, [(int(50 * 1e8), bitcoin_address_3)])
        solver.update(build_hash160_lookup([exponent_2]))
        spend_tx = unsigned_spend_tx.sign(solver)

        # now check that it validates
        self.assertEqual(spend_tx.bad_signature_count(), 0)
def sign_tx(certificate_metadata, last_input, allowable_wif_prefixes=None):
    """sign the transaction with private key"""
    with open(certificate_metadata.unsigned_tx_file_name, 'rb') as in_file:
        hextx = str(in_file.read(), 'utf-8')

        logging.info(
            'Signing tx with private key for recipient id: %s ...', certificate_metadata.uid)

        tx = Tx.from_hex(hextx)
        if allowable_wif_prefixes:
            wif = wif_to_secret_exponent(
                helpers.import_key(), allowable_wif_prefixes)
        else:
            wif = wif_to_secret_exponent(helpers.import_key())

        lookup = build_hash160_lookup([wif])

        tx.set_unspents(
            [TxOut(coin_value=last_input.amount, script=last_input.script_pub_key)])

        signed_tx = tx.sign(lookup)
        signed_hextx = signed_tx.as_hex()
        with open(certificate_metadata.unsent_tx_file_name, 'wb') as out_file:
            out_file.write(bytes(signed_hextx, 'utf-8'))

    logging.info('Finished signing transaction for certificate uid=%s',
                 certificate_metadata.uid)
Example #3
0
 def test_sign_bitcoind_partially_signed_2_of_2(self):
     # Finish signing a 2 of 2 transaction, that already has one signature signed by bitcoind
     # This tx can be found on testnet3 blockchain
     # txid: 9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2
     raw_script = (
         "522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e42cb29fde059c168851165521"
         "02b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff50511830328c1b479986452ae"
     )
     p2sh_lookup = build_p2sh_lookup([h2b(raw_script)])
     partially_signed_raw_tx = (
         "010000000196238f11a5fd3ceef4efd5a186a7e6b9217d900418e72aca917cd6a6e634"
         "e74100000000910047304402201b41b471d9dd93cf97eed7cfc39a5767a546f6bfbf3e"
         "0c91ff9ad23ab9770f1f02205ce565666271d055be1f25a7e52e34cbf659f6c70770ff"
         "59bd783a6fcd1be3dd0147522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e4"
         "2cb29fde059c16885116552102b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff5"
         "0511830328c1b479986452aeffffffff01a0bb0d00000000001976a9143b3beefd6f78"
         "02fa8706983a76a51467bfa36f8b88ac00000000")
     tx = Tx.from_hex(partially_signed_raw_tx)
     tx_out = TxOut(1000000,
                    h2b("a914a10dfa21ee8c33b028b92562f6fe04e60563d3c087"))
     tx.set_unspents([tx_out])
     key = Key.from_text(
         "cThRBRu2jAeshWL3sH3qbqdq9f4jDiDbd1SVz4qjTZD2xL1pdbsx")
     hash160_lookup = build_hash160_lookup([key.secret_exponent()])
     self.assertEqual(tx.bad_signature_count(), 1)
     tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)
     self.assertEqual(tx.bad_signature_count(), 0)
     self.assertEqual(
         tx.id(),
         "9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2")
Example #4
0
 def test_sign(self):
     sv = 33143560198659167577410026742586567991638126035902913554051654024377193788946
     tx_out_script = b'v\xa9\x14\x91\xb2K\xf9\xf5(\x852\x96\n\xc6\x87\xab\xb05\x12{\x1d(\xa5\x88\xac'
     st = script_obj_from_script(tx_out_script)
     hl = build_hash160_lookup([1])
     solution = st.solve(hash160_lookup=hl, sign_value=sv, signature_type=SIGHASH_ALL)
     self.assertEqual(solution, b'G0D\x02 ^=\xf5\xb5[\xe6!@\x04,"\x0b\x1f\xdf\x10\\\xc8Q\x13\xafV*!\\\x1f\xc5\xb5\xc5"\xd1\xb3\xd3\x02 8\xc9YK\x15o\xae\xd7\xf3|0\x07z\xff\xbfj\xcfB\xbf\x17\xb1\xe69\xa1\xfc\xc6\xc5\x1ag\xab\xa2\x16\x01A\x04y\xbef~\xf9\xdc\xbb\xacU\xa0b\x95\xce\x87\x0b\x07\x02\x9b\xfc\xdb-\xce(\xd9Y\xf2\x81[\x16\xf8\x17\x98H:\xdaw&\xa3\xc4e]\xa4\xfb\xfc\x0e\x11\x08\xa8\xfd\x17\xb4H\xa6\x85T\x19\x9cG\xd0\x8f\xfb\x10\xd4\xb8')
Example #5
0
 def test_multisig_one_at_a_time(self):
     N = 3
     M = 3
     keys = [Key(secret_exponent=i) for i in range(1, M + 2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     script = ScriptMultisig(n=N, sec_keys=[key.sec()
                                            for key in keys[:M]]).script()
     tx_out = TxOut(1000000, script)
     tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
     tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(),
                              [keys[-1].address()])
     ids = [
         "403e5bfc59e097bb197bf77a692d158dd3a4f7affb4a1fa41072dafe7bec7058",
         "5931d9995e83721243dca24772d7012afcd4378996a8b953c458175f15a544db",
         "9bb4421088190bbbb5b42a9eaa9baed7ec7574a407c25f71992ba56ca43d9c44",
         "03a1dc2a63f93a5cf5a7cb668658eb3fc2eda88c06dc287b85ba3e6aff751771"
     ]
     for i in range(1, M + 1):
         self.assertEqual(tx2.bad_signature_count(), 1)
         self.assertEqual(tx2.id(), ids[i - 1])
         hash160_lookup = build_hash160_lookup(key.secret_exponent()
                                               for key in keys[i - 1:i])
         tx2.sign(hash160_lookup=hash160_lookup)
         self.assertEqual(tx2.id(), ids[i])
     self.assertEqual(tx2.bad_signature_count(), 0)
Example #6
0
 def test_sign(self):
     sv = 33143560198659167577410026742586567991638126035902913554051654024377193788946
     tx_out_script = b'v\xa9\x14\x91\xb2K\xf9\xf5(\x852\x96\n\xc6\x87\xab\xb05\x12{\x1d(\xa5\x88\xac'
     st = script_obj_from_script(tx_out_script)
     hl = build_hash160_lookup([1])
     solution = st.solve(hash160_lookup=hl, sign_value=sv, signature_type=SIGHASH_ALL)
     self.assertEqual(solution, b'G0D\x02 ^=\xf5\xb5[\xe6!@\x04,"\x0b\x1f\xdf\x10\\\xc8Q\x13\xafV*!\\\x1f\xc5\xb5\xc5"\xd1\xb3\xd3\x02 8\xc9YK\x15o\xae\xd7\xf3|0\x07z\xff\xbfj\xcfB\xbf\x17\xb1\xe69\xa1\xfc\xc6\xc5\x1ag\xab\xa2\x16\x01A\x04y\xbef~\xf9\xdc\xbb\xacU\xa0b\x95\xce\x87\x0b\x07\x02\x9b\xfc\xdb-\xce(\xd9Y\xf2\x81[\x16\xf8\x17\x98H:\xdaw&\xa3\xc4e]\xa4\xfb\xfc\x0e\x11\x08\xa8\xfd\x17\xb4H\xa6\x85T\x19\x9cG\xd0\x8f\xfb\x10\xd4\xb8')
Example #7
0
def sign_tx(hextx, tx_input, allowable_wif_prefixes=None):
    """
    Sign the transaction with private key
    :param hextx:
    :param tx_input:
    :param allowable_wif_prefixes:
    :return:
    """

    logging.info('Signing tx with private key')

    tx = Tx.from_hex(hextx)
    if allowable_wif_prefixes:
        wif = wif_to_secret_exponent(
            helpers.import_key(), allowable_wif_prefixes)
    else:
        wif = wif_to_secret_exponent(helpers.import_key())

    lookup = build_hash160_lookup([wif])

    tx.set_unspents(
        [TxOut(coin_value=tx_input.amount, script=tx_input.script_pub_key)])

    signed_tx = tx.sign(lookup)
    signed_hextx = signed_tx.as_hex()

    logging.info('Finished signing transaction')
    return signed_hextx
def sign_tx(certificate_metadata, last_input, allowable_wif_prefixes=None):
    """sign the transaction with private key"""
    with open(certificate_metadata.unsigned_tx_file_name, 'rb') as in_file:
        hextx = str(in_file.read(), 'utf-8')

        logging.info('Signing tx with private key for recipient id: %s ...',
                     certificate_metadata.uid)

        tx = Tx.from_hex(hextx)
        if allowable_wif_prefixes:
            wif = wif_to_secret_exponent(helpers.import_key(),
                                         allowable_wif_prefixes)
        else:
            wif = wif_to_secret_exponent(helpers.import_key())

        lookup = build_hash160_lookup([wif])

        tx.set_unspents([
            TxOut(coin_value=last_input.amount,
                  script=last_input.script_pub_key)
        ])

        signed_tx = tx.sign(lookup)
        signed_hextx = signed_tx.as_hex()
        with open(certificate_metadata.unsent_tx_file_name, 'wb') as out_file:
            out_file.write(bytes(signed_hextx, 'utf-8'))

    logging.info('Finished signing transaction for certificate uid=%s',
                 certificate_metadata.uid)
Example #9
0
 def sign_transaction(self, wif, transaction_to_sign):
     secret_exponent = wif_to_secret_exponent(wif, self.allowable_wif_prefixes)
     lookup = build_hash160_lookup([secret_exponent])
     signed_transaction = transaction_to_sign.sign(lookup)
     # Because signing failures silently continue, first check that the inputs are signed
     for input in signed_transaction.txs_in:
         if len(input.script) == 0:
             logging.error('Unable to sign transaction. hextx=%s', signed_transaction.as_hex())
             raise UnableToSignTxError('Unable to sign transaction')
     return signed_transaction
Example #10
0
def sign_tx(service, testnet, tx, keys):
    netcode = 'XTN' if testnet else 'BTC'
    secretexponents = list(map(lambda key: key.secret_exponent(), keys))
    lookup = build_hash160_lookup(secretexponents)
    for txin_idx in range(len(tx.txs_in)):
        txin = tx.txs_in[txin_idx]
        utxo_tx = service.get_tx(txin.previous_hash)
        script = utxo_tx.txs_out[txin.previous_index].script
        tx.sign_tx_in(lookup, txin_idx, script, SIGHASH_ALL, netcode=netcode)
    return tx
Example #11
0
def sign_tx(service, testnet, tx, keys):
    netcode = 'XTN' if testnet else 'BTC'
    secretexponents = list(map(lambda key: key.secret_exponent(), keys))
    lookup = build_hash160_lookup(secretexponents)
    for txin_idx in range(len(tx.txs_in)):
        txin = tx.txs_in[txin_idx]
        utxo_tx = service.get_tx(txin.previous_hash)
        script = utxo_tx.txs_out[txin.previous_index].script
        tx.sign_tx_in(lookup, txin_idx, script, SIGHASH_ALL, netcode=netcode)
    return tx
Example #12
0
 def get(self, v):
     if v in self.secret_exponent_db_cache:
         return self.secret_exponent_db_cache[v]
     for wif in self.wif_iterable:
         secret_exponent = wif_to_secret_exponent(wif, self.wif_prefix)
         d = build_hash160_lookup([secret_exponent])
         self.secret_exponent_db_cache.update(d)
         if v in self.secret_exponent_db_cache:
             return self.secret_exponent_db_cache[v]
     self.wif_iterable = []
     return None
Example #13
0
 def test_sign(self):
     sv = 33143560198659167577410026742586567991638126035902913554051654024377193788946
     tx_out_script = b'v\xa9\x14\x91\xb2K\xf9\xf5(\x852\x96\n\xc6\x87\xab\xb05\x12{\x1d(\xa5\x88\xac'
     st = script_obj_from_script(tx_out_script)
     hl = build_hash160_lookup([1])
     solution = st.solve(hash160_lookup=hl, signature_for_hash_type_f=const_f(sv), signature_type=SIGHASH_ALL)
     self.assertEqual(
         solution, h2b(
             "47304402205e3df5b55be62140042c220b1fdf105cc85113af562a215c1fc5b5c522d1"
             "b3d3022038c9594b156faed7f37c30077affbf6acf42bf17b1e639a1fcc6c51a67aba2"
             "1601410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817"
             "98483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"))
Example #14
0
def spend_sh_fund(tx_ins, wif_keys, tx_outs):
    """
    spend script hash fund
    the key point of an input comes from multisig address is that,
    its sign script is combined with several individual signs
    :param tx_ins: list with tuple(tx_id, idx, balance, address, redeem_script)
    :param wif_keys: private keys in wif format,
        technical should be the same order with the pubkey in redeem script,
        but pycoin has inner control, so here order is not mandatory
    :param tx_outs: balance, receiver_address
    :return: raw hex and tx id
    """
    _txs_in = []
    _un_spent = []
    for tx_id, idx, balance, address, _ in tx_ins:
        # must h2b_rev NOT h2b
        tx_id_b = h2b_rev(tx_id)
        _txs_in.append(TxIn(tx_id_b, idx))

        _un_spent.append(
            Spendable(
                balance,
                script_obj_from_address(address, netcodes=[NET_CODE]).script(),
                tx_id_b, idx))

    _txs_out = []
    for balance, receiver_address in tx_outs:
        _txs_out.append(
            TxOut(
                balance,
                script_obj_from_address(receiver_address,
                                        netcodes=[NET_CODE]).script()))

    version, lock_time = 1, 0
    tx = Tx(version, _txs_in, _txs_out, lock_time)
    tx.set_unspents(_un_spent)

    # construct hash160_lookup[hash160] = (secret_exponent, public_pair, compressed) for each individual key
    hash160_lookup = build_hash160_lookup(
        [Key.from_text(wif_key).secret_exponent() for wif_key in wif_keys])

    for i in range(0, len(tx_ins)):
        # you can add some conditions that if the input script is not p2sh type, not provide p2sh_lookup,
        # so that all kinds of inputs can work together
        p2sh_lookup = build_p2sh_lookup([binascii.unhexlify(tx_ins[i][-1])])
        tx.sign_tx_in(hash160_lookup,
                      i,
                      tx.unspents[i].script,
                      hash_type=SIGHASH_ALL,
                      p2sh_lookup=p2sh_lookup)

    return tx.as_hex(), tx.id()
Example #15
0
 def multisig_N_of_M(self, N, M, unsigned_id, signed_id):
     keys = [Key(secret_exponent=i) for i in range(1, M+2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     script = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script()
     tx_out = TxOut(1000000, script)
     tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
     tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()])
     self.assertEqual(tx2.id(), unsigned_id)
     self.assertEqual(tx2.bad_signature_count(), 1)
     hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys)
     tx2.sign(hash160_lookup=hash160_lookup)
     self.assertEqual(tx2.id(), signed_id)
     self.assertEqual(tx2.bad_signature_count(), 0)
Example #16
0
 def multisig_M_of_N(self, M, N, unsigned_id, signed_id):
     keys = [Key(secret_exponent=i) for i in range(1, N+2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script()
     tx_out = TxOut(1000000, script)
     tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
     tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()])
     self.assertEqual(tx2.id(), unsigned_id)
     self.assertEqual(tx2.bad_signature_count(), 1)
     hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys)
     tx2.sign(hash160_lookup=hash160_lookup)
     self.assertEqual(tx2.id(), signed_id)
     self.assertEqual(tx2.bad_signature_count(), 0)
Example #17
0
 def test_solve_pay_to_public_pair(self):
     for se in range(1, 10):
         key = Key(secret_exponent=se)
         for b in [True, False]:
             addr = key.address(use_uncompressed=b)
             st = ScriptPayToPublicKey.from_key(key, use_uncompressed=b)
             self.assertEqual(st.address(), addr)
             hl = build_hash160_lookup([se])
             sv = 100
             solution = st.solve(hash160_lookup=hl, sign_value=sv, signature_type=SIGHASH_ALL)
             sc = st.script()
             st = script_obj_from_script(sc)
             self.assertEqual(st.address(), addr)
Example #18
0
 def multisig_M_of_N_individually(self, M, N):
     keys = [Key(secret_exponent=i) for i in range(1, N+2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     script = ScriptMultisig(n=M, sec_keys=[key.sec() for key in keys[:N]]).script()
     tx_out = TxOut(1000000, script)
     tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
     for partial_key_list in itertools.permutations(keys[:N], M):
         tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()])
         for key in partial_key_list:
             self.assertEqual(tx2.bad_signature_count(), 1)
             hash160_lookup = build_hash160_lookup([key.secret_exponent()])
             tx2.sign(hash160_lookup=hash160_lookup)
         self.assertEqual(tx2.bad_signature_count(), 0)
Example #19
0
 def test_solve_pay_to_public_pair(self):
     for se in range(1, 10):
         key = Key(secret_exponent=se)
         for b in [True, False]:
             addr = key.address(use_uncompressed=b)
             st = ScriptPayToPublicKey.from_key(key, use_uncompressed=b)
             self.assertEqual(st.address(), addr)
             hl = build_hash160_lookup([se])
             sv = 100
             solution = st.solve(hash160_lookup=hl, sign_value=sv, signature_type=SIGHASH_ALL)
             sc = st.script()
             st = script_obj_from_script(sc)
             self.assertEqual(st.address(), addr)
Example #20
0
 def test_solve_pay_to_address(self):
     for se in range(1, 10):
         key = Key(secret_exponent=se)
         for b in [True, False]:
             addr = key.address(use_uncompressed=b)
             st = script_obj_from_address(addr)
             self.assertEqual(st.address(), addr)
             hl = build_hash160_lookup([se])
             sv = 100
             solution = st.solve(hash160_lookup=hl, signature_for_hash_type_f=const_f(sv), signature_type=SIGHASH_ALL)
             sc = st.script()
             st = script_obj_from_script(sc)
             self.assertEqual(st.address(), addr)
Example #21
0
 def test_solve_pay_to_address(self):
     for se in range(1, 10):
         key = Key(secret_exponent=se)
         for b in [True, False]:
             addr = key.address(use_uncompressed=b)
             st = script_obj_from_address(addr)
             self.assertEqual(st.address(), addr)
             hl = build_hash160_lookup([se])
             sv = 100
             solution = st.solve(hash160_lookup=hl, signature_for_hash_type_f=const_f(sv), signature_type=SIGHASH_ALL)
             sc = st.script()
             st = script_obj_from_script(sc)
             self.assertEqual(st.address(), addr)
Example #22
0
 def multisig_M_of_N_individually(self, M, N):
     keys = [Key(secret_exponent=i) for i in range(1, N + 2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     script = ScriptMultisig(m=M, sec_keys=[key.sec()
                                            for key in keys[:N]]).script()
     tx_out = TxOut(1000000, script)
     tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
     for partial_key_list in itertools.permutations(keys[:N], M):
         tx2 = create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()])
         for key in partial_key_list:
             self.assertEqual(tx2.bad_signature_count(), 1)
             hash160_lookup = build_hash160_lookup([key.secret_exponent()])
             tx2.sign(hash160_lookup=hash160_lookup)
         self.assertEqual(tx2.bad_signature_count(), 0)
Example #23
0
 def test_sign_pay_to_script_multisig(self):
     M, N = 3, 3
     keys = [Key(secret_exponent=i) for i in range(1, N+2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     underlying_script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script()
     address = address_for_pay_to_script(underlying_script)
     self.assertEqual(address, "39qEwuwyb2cAX38MFtrNzvq3KV9hSNov3q")
     script = standard_tx_out_script(address)
     tx_out = TxOut(1000000, script)
     tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
     tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [address])
     hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[:N])
     p2sh_lookup = build_p2sh_lookup([underlying_script])
     tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)
     self.assertEqual(tx2.bad_signature_count(), 0)
Example #24
0
def sign_tx(hex_tx, tx_input):
    """
    Sign the transaction with private key
    :param hex_tx:
    :param tx_input:
    :return:
    """
    logging.info('Signing tx with private key')
    transaction = Tx.from_hex(hex_tx)
    wif = wif_to_secret_exponent(helpers.import_key(), ALLOWABLE_WIF_PREFIXES)
    lookup = build_hash160_lookup([wif])
    transaction.set_unspents([TxOut(coin_value=tx_input.coin_value, script=tx_input.script)])
    signed_tx = transaction.sign(lookup)
    logging.info('Finished signing transaction')
    return signed_tx
Example #25
0
 def test_sign_pay_to_script_multisig(self):
     N, M = 3, 3
     keys = [Key(secret_exponent=i) for i in range(1, M+2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     underlying_script = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script()
     address = address_for_pay_to_script(underlying_script)
     self.assertEqual(address, "39qEwuwyb2cAX38MFtrNzvq3KV9hSNov3q")
     script = standard_tx_out_script(address)
     tx_out = TxOut(1000000, script)
     tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
     tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [address])
     hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[:M])
     p2sh_lookup = build_p2sh_lookup([underlying_script])
     tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)
     self.assertEqual(tx2.bad_signature_count(), 0)
Example #26
0
 def test_sign_bitcoind_partially_signed_2_of_2(self):
     # Finish signing a 2 of 2 transaction, that already has one signature signed by bitcoind
     # This tx can be found on testnet3 blockchain, txid: 9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2
     raw_script = "522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e42cb29fde059c16885116552102b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff50511830328c1b479986452ae"
     p2sh_lookup = build_p2sh_lookup([h2b(raw_script)])
     partially_signed_raw_tx = "010000000196238f11a5fd3ceef4efd5a186a7e6b9217d900418e72aca917cd6a6e634e74100000000910047304402201b41b471d9dd93cf97eed7cfc39a5767a546f6bfbf3e0c91ff9ad23ab9770f1f02205ce565666271d055be1f25a7e52e34cbf659f6c70770ff59bd783a6fcd1be3dd0147522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e42cb29fde059c16885116552102b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff50511830328c1b479986452aeffffffff01a0bb0d00000000001976a9143b3beefd6f7802fa8706983a76a51467bfa36f8b88ac00000000"
     tx = Tx.from_hex(partially_signed_raw_tx)
     tx_out = TxOut(1000000, h2b("a914a10dfa21ee8c33b028b92562f6fe04e60563d3c087"))
     tx.set_unspents([tx_out])
     key = Key.from_text("cThRBRu2jAeshWL3sH3qbqdq9f4jDiDbd1SVz4qjTZD2xL1pdbsx")
     hash160_lookup = build_hash160_lookup([key.secret_exponent()])
     self.assertEqual(tx.bad_signature_count(), 1)
     tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)
     self.assertEqual(tx.bad_signature_count(), 0)
     self.assertEqual(tx.id(), "9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2")
Example #27
0
 def test_sign(self):
     sv = 33143560198659167577410026742586567991638126035902913554051654024377193788946
     tx_out_script = b'v\xa9\x14\x91\xb2K\xf9\xf5(\x852\x96\n\xc6\x87\xab\xb05\x12{\x1d(\xa5\x88\xac'
     st = script_obj_from_script(tx_out_script)
     hl = build_hash160_lookup([1])
     solution = st.solve(hash160_lookup=hl,
                         signature_for_hash_type_f=const_f(sv),
                         signature_type=SIGHASH_ALL)
     self.assertEqual(
         solution,
         h2b("47304402205e3df5b55be62140042c220b1fdf105cc85113af562a215c1fc5b5c522d1"
             "b3d3022038c9594b156faed7f37c30077affbf6acf42bf17b1e639a1fcc6c51a67aba2"
             "1601410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817"
             "98483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"
             ))
Example #28
0
    def post(self):
        logging.info("transaction coming in")
        hextx = self.get_argument('hextx', None)
        subkeys = self.get_argument('subkeys', None)
        payoutaddress = self.get_argument('payoutaddress', None)
        fees = self.get_argument('fees', None)

        print subkeys

        if not hextx or not subkeys or not payoutaddress or not fees:
            logging.error("Did not receive trans or tree argument")
            return

        fees = tornado.escape.json_decode(fees)
        subkeys = tornado.escape.json_decode(subkeys)
        seed = mnemonic.Mnemonic.to_seed(PHRASE)
        wallet = BIP32Node.from_master_secret(seed)

        wifs = []
        keys = []
        for subkey in subkeys:
            key = wallet.subkey_for_path(subkey)
            keys.append(key)
            wifs.append(key.wif())

        underlying_script = ScriptMultisig(
            n=N, sec_keys=[key.sec() for key in keys[:M]]).script()
        address = address_for_pay_to_script(underlying_script)

        tx2 = Tx.tx_from_hex(hextx)

        # first tx out, need another for the 1% to our wallet
        script = standard_tx_out_script(payoutaddress)
        tx_out = TxOut(fees['seller'], script)
        # TODO: figure out final wallet. This is sending to my phone
        script = standard_tx_out_script("1LhkvTTxFXam672vjwbABtkp9td7dxCwyB")
        tx2_out = TxOut(fees['bestcrow'], script)

        txs_out = [tx_out, tx2_out]
        tx2.txs_out = txs_out

        hash160_lookup = build_hash160_lookup(key.secret_exponent()
                                              for key in keys)
        p2sh_lookup = build_p2sh_lookup([underlying_script])
        tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)

        print tx2.as_hex()
        self.write(tx2.as_hex())
Example #29
0
def sign_deposit(get_txs_func, payer_wif, rawtx):
    """ Sign deposit transaction.

    Args:
        get_txs_func (function): txid list -> matching raw transactions.
        payer_wif (str): Payer wif used for signing.
        rawtx (str): Deposit raw transaction to be signed.

    Return:
        Signed deposit raw transaction.
    """
    tx = load_tx(get_txs_func, rawtx)
    key = Key.from_text(payer_wif)
    with xxx_capture_out():
        tx.sign(build_hash160_lookup([key.secret_exponent()]))
    return tx.as_hex()
Example #30
0
def sign_tx(tx, utxo_list, is_test):
    secret_exponents = [utxo.address_rec.rawPrivKey
                        for utxo in utxo_list if utxo.address_rec]
    hash160_lookup = build_hash160_lookup(secret_exponents)
    txins = tx.txs_in[:]
    for txin_idx in xrange(len(txins)):
        blank_txin = txins[txin_idx]
        utxo = None
        for utxo_candidate in utxo_list:
            if utxo_candidate.get_txhash() == blank_txin.previous_hash \
                    and utxo_candidate.outindex == blank_txin.previous_index:
                utxo = utxo_candidate
                break
        if not (utxo and utxo.address_rec):
            continue
        txout_script = utxo.script.decode('hex')
        tx.sign_tx_in(hash160_lookup, txin_idx, txout_script, SIGHASH_ALL)
Example #31
0
    def createTransaction(self,
                          address,
                          amount,
                          keychain,
                          fee="standard",
                          confirms=0):
        unspents_result = yield self.unspents()
        spendables = []
        p2sh = []
        chain_paths = []
        # Strip leading /
        keychain_path = keychain['path'][1:]
        for unspent in unspents_result["unspents"]:
            if unspent["confirmations"] < confirms:
                continue
            p2sh.append(h2b(unspent["redeemScript"]))
            spendable = Spendable(unspent["value"], h2b(unspent["script"]),
                                  h2b_rev(unspent["tx_hash"]),
                                  unspent["tx_output_n"])
            spendables.append(spendable)
            chain_paths.append(keychain_path + unspent['chainPath'])
        p2sh_lookup = build_p2sh_lookup(p2sh)
        address_result = yield self.createAddress(1)
        change = address_result["address"]
        tx = tx_utils.create_tx(spendables, [(address, amount), change], fee)

        # address_keys = [BIP32Node.from_hwif(keychain["xprv"]).subkey_for_path("0/0/0/0"),
        #                 BIP32Node.from_hwif(keychain["xprv"]).subkey_for_path(address_result['path'])]

        spendable_keys = [
            BIP32Node.from_hwif(keychain["xprv"]).subkey_for_path(path)
            for path in chain_paths
        ]
        # all_keys = address_keys + spendable_keys

        hash160_lookup = build_hash160_lookup(
            [key.secret_exponent() for key in spendable_keys])

        pprint(tx)

        tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)

        pprint(tx)

        returnValue({'tx': tx.as_hex(), 'fee': tx.fee()})
Example #32
0
def sign_tx(tx, utxo_list, is_test):
    secret_exponents = [
        utxo.address_rec.rawPrivKey for utxo in utxo_list if utxo.address_rec
    ]
    hash160_lookup = build_hash160_lookup(secret_exponents)
    txins = tx.txs_in[:]
    for txin_idx in xrange(len(txins)):
        blank_txin = txins[txin_idx]
        utxo = None
        for utxo_candidate in utxo_list:
            if utxo_candidate.get_txhash() == blank_txin.previous_hash \
                    and utxo_candidate.outindex == blank_txin.previous_index:
                utxo = utxo_candidate
                break
        if not (utxo and utxo.address_rec):
            continue
        txout_script = utxo.script.decode('hex')
        tx.sign_tx_in(hash160_lookup, txin_idx, txout_script, SIGHASH_ALL)
Example #33
0
def signTxSegwit(txHex, wif_key):
    tx = Tx.from_hex(txHex)

    my_key = Key.from_text(wif_key)
    script = ScriptPayToAddressWit(b'\0', my_key.hash160()).script()
    redeem = binascii.hexlify(script).decode()

    in_keys = [wif_key]
    hash160_lookup = build_hash160_lookup(
        [Key.from_text(wif).secret_exponent() for wif in in_keys])
    for i in range(0, len(tx.txs_in)):
        p2sh_lookup = build_p2sh_lookup([binascii.unhexlify(redeem)])
        tx.sign_tx_in(hash160_lookup,
                      i,
                      tx.unspents[i].script,
                      hash_type=SIGHASH_ALL,
                      p2sh_lookup=p2sh_lookup)
    return tx.as_hex()
Example #34
0
def tether_tx(tx_ins, private_key, send_amount, receiver):
    """
    simple usdt transaction
    here assume utxo comes from the sender and is used for mine fee
    bitcoin change will be sent back to sender address

    of course different address's utxo can be used for mine fee,
    but should be aware sender is determined by the first input in the tx
    bitcoin change can also be sent back to different address,
    but should be aware receiver is indicated by the last output address that is not the sender

    for full customization, use btc sample p2pkh_tx
    :param tx_ins: utxo from the sender
    :param private_key: private key of the same sender
    :param send_amount: (display amount) * (10 ** 8)
    :param receiver: address to receive usdt
    """
    _txs_in = []
    _un_spent = []
    total_bal = 0

    for tx_id, idx, balance, address in tx_ins:
        total_bal += balance

        # must h2b_rev NOT h2b
        tx_id_b = h2b_rev(tx_id)
        _txs_in.append(TxIn(tx_id_b, idx))

        _un_spent.append(Spendable(balance, standard_tx_out_script(address), tx_id_b, idx))

    txn_fee = estimate_p2pkh_tx_bytes(len(tx_ins), 3) * recommend_satoshi_per_byte()

    _txs_out = [TxOut(total_bal - txn_fee - 546, standard_tx_out_script(tx_ins[0][3])),
                TxOut(0, binascii.unhexlify(omni_tether_script(send_amount))),
                TxOut(546, standard_tx_out_script(receiver))]

    version, lock_time = 1, 0
    tx = Tx(version, _txs_in, _txs_out, lock_time)
    tx.set_unspents(_un_spent)

    solver = build_hash160_lookup([int(private_key, 16)] * len(tx_ins))
    signed_tx = tx.sign(solver, hash_type=SIGHASH_ALL)

    return signed_tx.as_hex(), signed_tx.id()
Example #35
0
 def test_multisig_one_at_a_time(self):
     N = 3
     M = 3
     keys = [Key(secret_exponent=i) for i in range(1, M+2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     script = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script()
     tx_out = TxOut(1000000, script)
     tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
     tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()])
     ids = ["403e5bfc59e097bb197bf77a692d158dd3a4f7affb4a1fa41072dafe7bec7058",
            "5931d9995e83721243dca24772d7012afcd4378996a8b953c458175f15a544db",
            "9bb4421088190bbbb5b42a9eaa9baed7ec7574a407c25f71992ba56ca43d9c44",
            "03a1dc2a63f93a5cf5a7cb668658eb3fc2eda88c06dc287b85ba3e6aff751771"]
     for i in range(1, M+1):
         self.assertEqual(tx2.bad_signature_count(), 1)
         self.assertEqual(tx2.id(), ids[i-1])
         hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[i-1:i])
         tx2.sign(hash160_lookup=hash160_lookup)
         self.assertEqual(tx2.id(), ids[i])
     self.assertEqual(tx2.bad_signature_count(), 0)
Example #36
0
	def createTransaction (self, outs, fee):
		# Create the signed transaction
		spendables = self._spendables (int (fee))

		#print (spendables)
		if len (spendables) == 0:
			logger.error ('No spendables available')
			return None

		t = create_tx(spendables, [self.address], fee=int (fee))

		for o in outs:
			t.txs_out.append (TxOut (0.0, tools.compile (o)))

		secret_exponent = wif_to_secret_exponent(self.wif, allowable_wif_prefixes=[wif_prefix_for_netcode (self.chain)])
		d = {}
		d.update (build_hash160_lookup([secret_exponent]))

		t.sign (d)
		txhash = (t.as_hex ())
		return txhash
Example #37
0
    def createTransaction(self, address, amount, keychain, fee="standard",
                          confirms=0):
        unspents_result = yield self.unspents()
        spendables = []
        p2sh = []
        chain_paths = []
        # Strip leading /
        keychain_path = keychain['path'][1:]
        for unspent in unspents_result["unspents"]:
            if unspent["confirmations"] < confirms:
                continue
            p2sh.append(h2b(unspent["redeemScript"]))
            spendable = Spendable(unspent["value"],
                                  h2b(unspent["script"]),
                                  h2b_rev(unspent["tx_hash"]),
                                  unspent["tx_output_n"])
            spendables.append(spendable)
            chain_paths.append(keychain_path + unspent['chainPath'])
        p2sh_lookup = build_p2sh_lookup(p2sh)
        address_result = yield self.createAddress(1)
        change = address_result["address"]
        tx = tx_utils.create_tx(spendables, [(address, amount), change], fee)

        # address_keys = [BIP32Node.from_hwif(keychain["xprv"]).subkey_for_path("0/0/0/0"),
        #                 BIP32Node.from_hwif(keychain["xprv"]).subkey_for_path(address_result['path'])]

        spendable_keys = [BIP32Node.from_hwif(keychain["xprv"]).subkey_for_path(path) for path in chain_paths]
        # all_keys = address_keys + spendable_keys

        hash160_lookup = build_hash160_lookup([key.secret_exponent() for key in spendable_keys])

        pprint(tx)

        tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)

        pprint(tx)

        returnValue({'tx': tx.as_hex(),
                     'fee': tx.fee()})
Example #38
0
    def sign_tx(self, hex_tx, tx_input, netcode):
        """
        Sign the transaction with private key
        :param hex_tx:
        :param tx_input:
        :param netcode:
        :return:
        """
        logging.info('Signing tx with private key')

        self.secret_manager.start()
        wif = self.secret_manager.get_wif()

        transaction = Tx.from_hex(hex_tx)
        allowable_wif_prefixes = wif_prefix_for_netcode(netcode)

        se = wif_to_secret_exponent(wif, allowable_wif_prefixes)
        lookup = build_hash160_lookup([se])
        transaction.set_unspents([TxOut(coin_value=tx_input.coin_value, script=tx_input.script)])
        signed_tx = transaction.sign(lookup)
        self.secret_manager.stop()
        logging.info('Finished signing transaction')
        return signed_tx
Example #39
0
def spend_pkh_fund(tx_ins, in_keys, tx_outs):
    """
    p2pkh address send to p2pkh p2sh transaction
    :param tx_ins: list with tuple(tx_id, idx, balance, address)
    :param in_keys: list of private keys in hex format corresponding to each input
    :param tx_outs: balance, receiver_address
    :return: raw hex and tx id
    """
    _txs_in = []
    _un_spent = []
    for tx_id, idx, balance, address in tx_ins:
        # must h2b_rev NOT h2b
        tx_id_b = h2b_rev(tx_id)
        _txs_in.append(TxIn(tx_id_b, idx))

        _un_spent.append(
            Spendable(
                balance,
                script_obj_from_address(address, netcodes=[NET_CODE]).script(),
                tx_id_b, idx))

    _txs_out = []
    for balance, receiver_address in tx_outs:
        _txs_out.append(
            TxOut(
                balance,
                script_obj_from_address(receiver_address,
                                        netcodes=[NET_CODE]).script()))

    version, lock_time = 1, 0
    tx = Tx(version, _txs_in, _txs_out, lock_time)
    tx.set_unspents(_un_spent)

    solver = build_hash160_lookup([int(pri_hex, 16) for pri_hex in in_keys])
    tx.sign(solver, hash_type=SIGHASH_ALL)

    return tx.as_hex(), tx.id()
Example #40
0
def publish_data(data, unused_utxo):
    data = POE_MARKER_BYTES + data
    if len(data) > OP_RETURN_MAX_DATA:
        msg = 'data too long for OP_RETURN: %s' % (data.encode('hex'))
        ErrorNotification.new(msg)
        return None, msg

    _from = unused_utxo.address
    _private_key = PAYMENT_OBJ[_from][0]
    secret_exponent = wif_to_secret_exponent(_private_key)  #mainnet

    unsigned_tx = construct_data_tx(data, _from, unused_utxo)

    if type(unsigned_tx) == str:  # error
        msg = 'ERROR: type(unsigned_tx) == str'
        ErrorNotification.new(msg)
        return (None, unsigned_tx)

    solver = build_hash160_lookup([secret_exponent])
    signed_tx = unsigned_tx.sign(solver)
    raw_tx = tx2hex(signed_tx)

    txid, message = pushtxn(raw_tx)
    return txid, message
Example #41
0
def publish_data(data, unused_utxo):
  data = POE_MARKER_BYTES + data
  if len(data) > OP_RETURN_MAX_DATA:
    msg='data too long for OP_RETURN: %s' % (data.encode('hex'))
    ErrorNotification.new(msg)  
    return None, msg

  _from = unused_utxo.address
  _private_key=PAYMENT_OBJ[_from][0]
  secret_exponent = wif_to_secret_exponent(_private_key) #mainnet
  
  unsigned_tx = construct_data_tx(data, _from, unused_utxo)
  
  if type(unsigned_tx) == str: # error
    msg='ERROR: type(unsigned_tx) == str'
    ErrorNotification.new(msg) 
    return (None, unsigned_tx)

  solver = build_hash160_lookup([secret_exponent])  
  signed_tx = unsigned_tx.sign(solver) 
  raw_tx = tx2hex(signed_tx)
  
  txid, message = pushtxn(raw_tx)
  return txid, message
Example #42
0
for i in subBip32PrivateNodes:
    print(i)

print("")

"""
# beginning part totally signed
hash160_lookup = build_hash160_lookup([subBip32PrivateNodes[i].secret_exponent() for i in range(len(subBip32PrivateNodes))])
# >>> [subBip32PrivateNodes[i].secret_exponent() for i in range(len(subBip32PrivateNodes))]
# [110380562092968897127842430006032843930864261596730345665503170493711194530512, 73231854494958203118397405284330291107828238186602400029170683163884922382627]
p2sh_lookup = build_p2sh_lookup([script_encoded])
p2sh_lookup = build_p2sh_lookup([script_encoded])
tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)
tx.bad_signature_count() # checking if the signature process has worked
tx.as_hex() # is the raw hex correctly signed transaction
# 01000000020076ae0b7d8b4b7b44ac0b2fe2d5dc67aabbf0898291f190c7f9004f3923744301000000fc0047304402206fa07cce3d3c76dfb837c06bea796cb5b15e9075be6f20c708175662b3439c840220110fdc96c589ccaaf019e0678efd9aa2770661fb9f61227fb34b283a433b29110147304402207fb7f368d9458dd4d5afdf2ba89f42e5420634418759cdc8438f6ece60494b9d02203efe6428ec53bd08665300470f5e21f80f37fdb131281810f3b539d8268371e7014c695221033cb2f8b318f4c14e42cbe20cb365b2017d28bc557b0dde9eca2fbe8d3c9ed1982102e680e729a24923c09db6f958363b0416bc13970008ab7b925b2f2aa410e6b0a72102208fa0a00d6b9ae56f7cc137a021d03ae294d39242d64322f69bdc785853ba6453aeffffffffbbedb48aacb4dcea45687631cf592035843e754f603f7615b590d2b2f12e858d00000000fdfe0000483045022100f3a6e2cac3ffd51c85bfa0162d60ab125d669bb31b735563b8b4f47cf9fd7495022019f9a668d4c984e1da7f9ff16321bed57df66f7a80a953cc798682204b91e4f301483045022100c6d9226dccee03fcd9539db6780e0c9af1e096b260e4b60852c4ba1c2d1c9810022061bfa26cb8984aac054d6525cb7aeb9ce2d77021233e15928c2668de60848704014c695221033cb2f8b318f4c14e42cbe20cb365b2017d28bc557b0dde9eca2fbe8d3c9ed1982102e680e729a24923c09db6f958363b0416bc13970008ab7b925b2f2aa410e6b0a72102208fa0a00d6b9ae56f7cc137a021d03ae294d39242d64322f69bdc785853ba6453aeffffffff01803801000000000017a914b2f5e0dfcfa103a0fb4208c3393c30ff3204b5d78700000000

# end part totally signed
"""
# To sign the transaction for cryptocorp I will sign with just one of the two private keys required let's choose the first.

hash160_lookup = build_hash160_lookup([subBip32PrivateNodes[0].secret_exponent()])
p2sh_lookup = build_p2sh_lookup([script_encoded])
tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)
tx2.bad_signature_count()
tx2.as_hex() # is the raw hex of the totally signed transaction
print(tx.as_hex())
print("")
print("N. bad signatures: %s" % tx.bad_signature_count() )

Example #43
0
    def test_build_spends(self):
        # first, here is the tx database
        TX_DB = {}

        # create a coinbase Tx where we know the public & private key

        exponent = wif_to_secret_exponent(
            "5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y")
        compressed = False

        public_key_sec = public_pair_to_sec(
            ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1,
                                                  exponent),
            compressed=compressed)

        the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8),
                                         COINBASE_BYTES_FROM_80971)
        TX_DB[the_coinbase_tx.hash()] = the_coinbase_tx

        # now create a Tx that spends the coinbase

        compressed = False

        exponent_2 = int(
            "137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1",
            16)
        bitcoin_address_2 = public_pair_to_bitcoin_address(
            ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1,
                                                  exponent_2),
            compressed=compressed)

        self.assertEqual("12WivmEn8AUth6x6U8HuJuXHaJzDw3gHNZ",
                         bitcoin_address_2)

        coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])]
        coins_to = [(int(50 * 1e8), bitcoin_address_2)]
        unsigned_coinbase_spend_tx = standard_tx(coins_from, coins_to)
        solver = build_hash160_lookup([exponent])

        coinbase_spend_tx = unsigned_coinbase_spend_tx.sign(solver)

        # now check that it validates
        self.assertEqual(coinbase_spend_tx.bad_signature_count(), 0)

        TX_DB[coinbase_spend_tx.hash()] = coinbase_spend_tx

        ## now try to respend from priv_key_2 to priv_key_3

        compressed = True

        exponent_3 = int(
            "f8d39b8ecd0e1b6fee5a340519f239097569d7a403a50bb14fb2f04eff8db0ff",
            16)
        bitcoin_address_3 = public_pair_to_bitcoin_address(
            ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1,
                                                  exponent_3),
            compressed=compressed)

        self.assertEqual("13zzEHPCH2WUZJzANymow3ZrxcZ8iFBrY5",
                         bitcoin_address_3)

        coins_from = [(coinbase_spend_tx.hash(), 0,
                       coinbase_spend_tx.txs_out[0])]
        unsigned_spend_tx = standard_tx(coins_from,
                                        [(int(50 * 1e8), bitcoin_address_3)])
        solver.update(build_hash160_lookup([exponent_2]))
        spend_tx = unsigned_spend_tx.sign(solver)

        # now check that it validates
        self.assertEqual(spend_tx.bad_signature_count(), 0)
Example #44
0
print("script:")
print(b2h(script))
address = address_for_pay_to_script(script)
print(address)
# Everything's ok until here
"""
tx_in = TxIn.coinbase_tx_in(script=b'')
tx_out = TxOut(10000, script) # 0.1 mBits


tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
"""

spendables = blockr_io.spendables_for_address(address) #grab the spendables from an address
tx = tx_utils.create_tx(spendables, [spk1.address()], fee="standard") # tx with the amount to the destination address. I take one key of which I have the secret key.
hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[0:2]) # only the first two are private keys

# build_hash160_lookup(key.secret_exponent() for key in keys[0:1]) # I sign only with the first one.
# also build_hash160_lookup(Key.secret_exponent(keys[0]))
tx2.sign(hash160_lookup=hash160_lookup)
tx2.as_hex() #to be tested
"""
	tx = create_tx(
        spendables_for_address("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH"),
        [("1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP", 100)],
        fee=0)
     tx.sign_tx(wifs=["KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"])

     oppure tuuto d'un colpo:
         tx = create_signed_tx(
        spendables_for_address("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH"),
Example #45
0
 def sign_transaction(self, transaction_to_sign):
     secret_exponent = wif_to_secret_exponent(self.wif,
                                              self.allowable_wif_prefixes)
     lookup = build_hash160_lookup([secret_exponent])
     signed_transaction = transaction_to_sign.sign(lookup)
     return signed_transaction
Example #46
0
def _make_lookups(wif, script_hex):
    script_bin = h2b(script_hex)
    key = Key.from_text(wif)
    hash160_lookup = build_hash160_lookup([key.secret_exponent()])
    p2sh_lookup = build_p2sh_lookup([script_bin])
    return hash160_lookup, p2sh_lookup
Example #47
0
    def send(self, wallet_id, passcode, address, amount, message='', fee=10000):
        """
        Send bitcoins to address

        :param wallet_id: bitgo wallet id
        :param address: bitcoin address
        :param amount: btc amount in satoshis
        :return: boolean
        """
        wallet = self.get_wallet(wallet_id)
        if not wallet['spendingAccount']:
            raise NotSpendableWallet()

        if not wallet['isActive']:
            raise NotActiveWallet()

        if amount < 10000:
            raise Exception('amount to small')

        if wallet['confirmedBalance'] < amount:
            raise NotEnoughFunds('Not enough funds: balance %s amount %s' %
                                 (wallet['confirmedBalance'], amount)
            )

        change_address = self.create_address(wallet_id, chain=1)
        usableKeychain = False
        spendables = []
        chain_paths = []
        p2sh = []
        payables = [(address, amount)]
        keychain_path = ""

        for keychain in wallet['private']['keychains']:
            keychain_path = keychain['path'][1:]
            keychain = self.get_keychain(keychain['xpub'])
            if 'encryptedXprv' not in keychain:
                continue
            usableKeychain = True
            break

        if not usableKeychain:
            raise BitGoError("didn't found a spendable keychain")

        data = json.loads(keychain['encryptedXprv'])
        #add base64 paddings
        for k in ['iv', 'salt', 'ct']:
            data[k] = data[k] + "=="
        cipher = sjcl.SJCL()
        xprv = cipher.decrypt(data, passcode)

        unspents = self.get_unspents(wallet_id)
        total_value = 0
        for d in unspents['unspents'][::-1]:
            path = keychain_path + d['chainPath']
            chain_paths.append(path)
            p2sh.append(h2b(d["redeemScript"]))
            spendables.append(Spendable(d["value"],
                                  h2b(d["script"]),
                                  h2b_rev(d["tx_hash"]),
                                  d["tx_output_n"]))

            total_value += d['value']
            if total_value > amount:
                break

        if total_value > (amount + fee):
            #add a change address
            #TODO: create address
            payables.append(change_address)

        p2sh_lookup = build_p2sh_lookup(p2sh)

        spendable_keys = []

        priv_key = BIP32Node.from_hwif(xprv)

        spendable_keys = [priv_key.subkey_for_path(path) for path in chain_paths]

        hash160_lookup = build_hash160_lookup([key.secret_exponent() for key in spendable_keys])

        tx = create_tx(spendables, payables)

        tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)

        r = requests.post(self.url + '/tx/send', {
                'tx': tx.as_hex(),
                'message': message
            }, headers={
                'Authorization': 'Bearer %s' % self.access_token,
            })

        return r.json()
Example #48
0
    def send(self, wallet_id, passcode, address, amount, message='', fee=None, fan_unspend=10):
        """
        Send bitcoins to address

        :param wallet_id: bitgo wallet id
        :param address: bitcoin address
        :param amount: btc amount in satoshis
        :param split: create new outputs if needed
        :return: boolean
        """
        MINIMAL_FEE = 20000
        MINIMAL_SPLIT = 10000000
        MIN_UNSPENTS_FAN = 5

        wallet = self.get_wallet(wallet_id)
        if not wallet['spendingAccount']:
            raise NotSpendableWallet()

        if not wallet['isActive']:
            raise NotActiveWallet()

        if amount < 10000:
            raise Exception('amount to small')

        if wallet['confirmedBalance'] < amount:
            raise NotEnoughFunds('Not enough funds: balance %s amount %s' %
                                 (wallet['confirmedBalance'], amount)
            )

        change_address = self.create_address(wallet_id, chain=1)
        usableKeychain = False
        spendables = []
        chain_paths = []
        p2sh = []
        payables = [(address, amount)]
        keychain_path = ""

        for keychain in wallet['private']['keychains']:
            keychain_path = keychain['path'][1:]
            keychain = self.get_keychain(keychain['xpub'])
            if 'encryptedXprv' not in keychain:
                continue
            usableKeychain = True
            break

        if not usableKeychain:
            raise BitGoError("didn't found a spendable keychain")

        data = json.loads(keychain['encryptedXprv'])
        #add base64 paddings
        for k in ['iv', 'salt', 'ct']:
            data[k] = data[k] + "=="
        cipher = sjcl.SJCL()
        xprv = cipher.decrypt(data, passcode)

        unspents = self.get_unspents(wallet_id)['unspents']
        order_unspents = sorted(unspents, key=lambda k: k['confirmations'], reverse=True)

        total_value = 0
        for d in order_unspents:
            path = keychain_path + d['chainPath']
            chain_paths.append(path)
            p2sh.append(h2b(d["redeemScript"]))
            spendables.append(Spendable(d["value"],
                                  h2b(d["script"]),
                                  h2b_rev(d["tx_hash"]),
                                  d["tx_output_n"]))

            total_value += d['value']
            if total_value > amount:
                break

        # make many outputs?
        if len(order_unspents) < MIN_UNSPENTS_FAN and (total_value > (amount + MINIMAL_SPLIT)) and fan_unspend > 0:
            fee = self.calculate_fee(len(spendables), fan_unspend)
            value = (total_value - amount - fee) / fan_unspend
            for i in range(fan_unspend):
                payables.append((change_address, value))
        elif total_value > (amount + MINIMAL_FEE):
            # add a change address
            if fee is None:
                fee = self.calculate_fee(len(spendables), 2)
            value = total_value - amount - fee
            if value > 10000: #avoid dust
                payables.append((change_address, value))

        p2sh_lookup = build_p2sh_lookup(p2sh)

        spendable_keys = []

        priv_key = BIP32Node.from_hwif(xprv)

        spendable_keys = [priv_key.subkey_for_path(path) for path in chain_paths]

        hash160_lookup = build_hash160_lookup([key.secret_exponent() for key in spendable_keys])

        tx = create_tx(spendables, payables)

        tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)

        r = requests.post(self.url + '/tx/send', {
                'tx': tx.as_hex(),
                'message': message
            }, headers={
                'Authorization': 'Bearer %s' % self.access_token,
            })

        return r.json()
Example #49
0
    def test_bip143_txs(self):
        # these five examples are from BIP 143 at
        # https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki

        tx_u1, tx_s1 = self.check_bip143_tx(
            '0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f0000000000eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000',
            '01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000',
            [(6.25,
              "2103c9f4836b9a4f77fc0d81f7bcb01b7f1b35916864b9476c241ce9fc198bd25432ac"
              ),
             (6, "00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1")], 2, 2, 1, 17)

        self.assertEqual(
            b2h(tx_s1.hash_prevouts(SIGHASH_ALL)),
            "96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37")
        self.assertEqual(
            b2h(tx_s1.hash_sequence(SIGHASH_ALL)),
            "52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b")
        self.assertEqual(
            b2h(tx_s1.hash_outputs(SIGHASH_ALL, 0)),
            "863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5")

        script = tools.compile(
            "OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG" %
            b2h(tx_s1.unspents[1].script[2:]))
        self.assertEqual(
            b2h(
                tx_s1.segwit_signature_preimage(script=script,
                                                tx_in_idx=1,
                                                hash_type=SIGHASH_ALL)),
            "0100000096b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd3752b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3bef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a010000001976a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac0046c32300000000ffffffff863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e51100000001000000"
        )

        self.assertEqual(
            b2h(to_bytes_32(tx_s1.signature_for_hash_type_segwit(script, 1,
                                                                 1))),
            "c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670")
        self.check_tx_can_be_signed(tx_u1, tx_s1, [
            0xbbc27228ddcb9209d7fd6f36b02f7dfa6252af40bb2f1cbc7a557da8027ff866,
            0x619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9
        ])

        tx_u2, tx_s2 = self.check_bip143_tx(
            "0100000001db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a54770100000000feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac92040000",
            "01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001716001479091972186c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000",
            [(10, "a9144733f37cf4db86fbc2efed2500b4f4e49f31202387")], 1, 2, 1,
            1170)
        self.check_tx_can_be_signed(tx_u2, tx_s2, [
            0xeb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf
        ], ["001479091972186c449eb1ded22b78e40d009bdf0089"])

        tx_u3, tx_s3 = self.check_bip143_tx(
            "0100000002fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e0000000000ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac00000000",
            "01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000",
            [(1.5625,
              "21036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8ac"
              ),
             (49,
              "00205d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0"
              )], 2, 1, 1, 0)

        tx_u4, tx_s4 = self.check_bip143_tx(
            "0100000002e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac00000000",
            "01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000",
            [
                (0.16777215,
                 "0020ba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d"
                 ),
                (0.16777215,
                 "0020d9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537"
                 ),
            ], 2, 2, 1, 0)

        tx_u5, tx_s5 = self.check_bip143_tx(
            "010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000",
            "0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000",
            [(9.87654321, "a9149993a429037b5d912407a71c252019287b8d27a587")],
            1, 2, 1, 0)

        tx_u5prime = self.unsigned_copy(tx_s5)
        tx_s_hex = tx_s5.as_hex()
        tx_u5prime.set_unspents(tx_s5.unspents)

        ss = [
            "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae",
            "0020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54"
        ]
        p2sh_lookup = build_p2sh_lookup([h2b(x) for x in ss])
        for se, sighash_type in [
            (0x730fff80e1413068a05b57d6a58261f07551163369787f349438ea38ca80fac6,
             SIGHASH_ALL),
            (0x11fa3d25a17cbc22b29c44a484ba552b5a53149d106d3d853e22fdd05a2d8bb3,
             SIGHASH_NONE),
            (0x77bf4141a87d55bdd7f3cd0bdccf6e9e642935fec45f2f30047be7b799120661,
             SIGHASH_SINGLE),
            (0x14af36970f5025ea3e8b5542c0f8ebe7763e674838d08808896b63c3351ffe49,
             SIGHASH_ANYONECANPAY | SIGHASH_ALL),
            (0xfe9a95c19eef81dde2b95c1284ef39be497d128e2aa46916fb02d552485e0323,
             SIGHASH_ANYONECANPAY | SIGHASH_NONE),
            (0x428a7aee9f0c2af0cd19af3cf1c78149951ea528726989b2e83e4778d2c3f890,
             SIGHASH_ANYONECANPAY | SIGHASH_SINGLE),
        ]:
            tx_u5prime.sign(hash_type=sighash_type,
                            hash160_lookup=build_hash160_lookup([se]),
                            p2sh_lookup=p2sh_lookup)

        self.check_signed(tx_u5prime)
        tx_hex = tx_u5prime.as_hex()
        self.assertEqual(tx_hex, tx_s_hex)

        self.assertEqual(
            b2h(tx_s5.hash_prevouts(SIGHASH_ALL)),
            "74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0")
        self.assertEqual(
            b2h(tx_s5.hash_sequence(SIGHASH_ALL)),
            "3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044")
        self.assertEqual(
            b2h(tx_s5.hash_outputs(SIGHASH_ALL, 0)),
            "bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc")
        self.assertEqual(
            b2h(tx_s5.hash_outputs(SIGHASH_SINGLE, 0)),
            "9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f708")
        script = tx_s5.txs_in[0].witness[-1]
        self.assertEqual(
            b2h(
                tx_s5.segwit_signature_preimage(script=script,
                                                tx_in_idx=0,
                                                hash_type=SIGHASH_ALL)),
            "0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa03bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e7066504436641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc0000000001000000"
        )

        self.assertEqual(
            b2h(
                tx_s5.segwit_signature_preimage(script=script,
                                                tx_in_idx=0,
                                                hash_type=SIGHASH_NONE)),
            "0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000002000000"
        )

        self.assertEqual(
            b2h(
                tx_s5.segwit_signature_preimage(script=script,
                                                tx_in_idx=0,
                                                hash_type=SIGHASH_SINGLE)),
            "0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f7080000000003000000"
        )

        self.assertEqual(
            b2h(
                tx_s5.segwit_signature_preimage(script=script,
                                                tx_in_idx=0,
                                                hash_type=SIGHASH_ALL
                                                | SIGHASH_ANYONECANPAY)),
            "010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc0000000081000000"
        )

        self.assertEqual(
            b2h(
                tx_s5.segwit_signature_preimage(script=script,
                                                tx_in_idx=0,
                                                hash_type=SIGHASH_NONE
                                                | SIGHASH_ANYONECANPAY)),
            "010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000082000000"
        )

        self.assertEqual(
            b2h(
                tx_s5.segwit_signature_preimage(script=script,
                                                tx_in_idx=0,
                                                hash_type=SIGHASH_SINGLE
                                                | SIGHASH_ANYONECANPAY)),
            "010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f7080000000083000000"
        )

        tx = Tx.from_hex(
            "010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff0101000000000000000000000000"
        )
        tx.set_witness(0, [
            h2b(x) for x in [
                "30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01",
                "02a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c",
                "ad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01"
            ]
        ])
        tx = Tx.from_hex(
            "0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000"
        )
        tx_hex = tx.as_hex()
        print(tx)
        print(tx_hex)
        tx = Tx.from_hex(
            "010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff0101000000000000000000000000"
        )
        self.assertEqual(
            tx_hex,
            "0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000"
        )

        tx_u6, tx_s6 = self.check_bip143_tx(
            "010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff0101000000000000000000000000",
            "0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000",
            [(0.002,
              "00209e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19"
              )], 1, 1, 1, 0)

        tx_u7, tx_s7 = self.check_bip143_tx(
            "01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000000000000",
            "010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000",
            [(0.002,
              "00209b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52"
              )], 1, 1, 1, 0)
        print(tx_s7.txs_in[0])
Example #50
0
    def send(self,
             wallet_id,
             passcode,
             address,
             amount,
             message='',
             fee=10000):
        """
        Send bitcoins to address

        :param wallet_id: bitgo wallet id
        :param address: bitcoin address
        :param amount: btc amount in satoshis
        :return: boolean
        """
        wallet = self.get_wallet(wallet_id)
        if not wallet['spendingAccount']:
            raise NotSpendableWallet()

        if not wallet['isActive']:
            raise NotActiveWallet()

        if amount < 10000:
            raise Exception('amount to small')

        if wallet['confirmedBalance'] < amount:
            raise NotEnoughFunds('Not enough funds: balance %s amount %s' %
                                 (wallet['confirmedBalance'], amount))

        change_address = self.create_address(wallet_id, chain=1)
        usableKeychain = False
        spendables = []
        chain_paths = []
        p2sh = []
        payables = [(address, amount)]
        keychain_path = ""

        for keychain in wallet['private']['keychains']:
            keychain_path = keychain['path'][1:]
            keychain = self.get_keychain(keychain['xpub'])
            if 'encryptedXprv' not in keychain:
                continue
            usableKeychain = True
            break

        if not usableKeychain:
            raise BitGoError("didn't found a spendable keychain")

        data = json.loads(keychain['encryptedXprv'])
        #add base64 paddings
        for k in ['iv', 'salt', 'ct']:
            data[k] = data[k] + "=="
        cipher = sjcl.SJCL()
        xprv = cipher.decrypt(data, passcode)

        unspents = self.get_unspents(wallet_id)
        total_value = 0
        for d in unspents['unspents'][::-1]:
            path = keychain_path + d['chainPath']
            chain_paths.append(path)
            p2sh.append(h2b(d["redeemScript"]))
            spendables.append(
                Spendable(d["value"], h2b(d["script"]), h2b_rev(d["tx_hash"]),
                          d["tx_output_n"]))

            total_value += d['value']
            if total_value > amount:
                break

        if total_value > (amount + fee):
            #add a change address
            #TODO: create address
            payables.append(change_address)

        p2sh_lookup = build_p2sh_lookup(p2sh)

        spendable_keys = []

        priv_key = BIP32Node.from_hwif(xprv)

        spendable_keys = [
            priv_key.subkey_for_path(path) for path in chain_paths
        ]

        hash160_lookup = build_hash160_lookup(
            [key.secret_exponent() for key in spendable_keys])

        tx = create_tx(spendables, payables)

        tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)

        r = requests.post(self.url + '/tx/send', {
            'tx': tx.as_hex(),
            'message': message
        },
                          headers={
                              'Authorization': 'Bearer %s' % self.access_token,
                          })

        return r.json()
Example #51
0
    def test_bip143_txs(self):
        # these five examples are from BIP 143 at
        # https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki

        tx_u1, tx_s1 = self.check_bip143_tx(
            '0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f0000000000eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000',
            '01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000',
            [
                (6.25, "2103c9f4836b9a4f77fc0d81f7bcb01b7f1b35916864b9476c241ce9fc198bd25432ac"),
                (6, "00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1")
            ],
            2,
            2,
            1,
            17
        )

        self.assertEqual(b2h(tx_s1.hash_prevouts(SIGHASH_ALL)),
                         "96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37")
        self.assertEqual(b2h(tx_s1.hash_sequence(SIGHASH_ALL)),
                         "52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b")
        self.assertEqual(b2h(tx_s1.hash_outputs(SIGHASH_ALL, 0)),
                         "863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5")

        script = tools.compile("OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG" % b2h(tx_s1.unspents[1].script[2:]))
        self.assertEqual(b2h(tx_s1.segwit_signature_preimage(script=script, tx_in_idx=1, hash_type=SIGHASH_ALL)),
                         "0100000096b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd3752b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3bef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a010000001976a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac0046c32300000000ffffffff863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e51100000001000000")

        self.assertEqual(b2h(to_bytes_32(tx_s1.signature_for_hash_type_segwit(script, 1, 1))),
                         "c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670")
        self.check_tx_can_be_signed(tx_u1, tx_s1, [
            0xbbc27228ddcb9209d7fd6f36b02f7dfa6252af40bb2f1cbc7a557da8027ff866,
            0x619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9
        ])

        tx_u2, tx_s2 = self.check_bip143_tx(
            "0100000001db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a54770100000000feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac92040000",
            "01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001716001479091972186c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000",
            [(10, "a9144733f37cf4db86fbc2efed2500b4f4e49f31202387")],
            1,
            2,
            1,
            1170
        )
        self.check_tx_can_be_signed(
            tx_u2, tx_s2, [0xeb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf],
            ["001479091972186c449eb1ded22b78e40d009bdf0089"])

        tx_u3, tx_s3 = self.check_bip143_tx(
            "0100000002fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e0000000000ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac00000000",
            "01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000",
            [
                (1.5625, "21036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8ac"),
                (49, "00205d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0")
            ],
            2,
            1,
            1,
            0
        )

        tx_u4, tx_s4 = self.check_bip143_tx(
            "0100000002e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac00000000",
            "01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000",
            [
                (0.16777215, "0020ba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d"),
                (0.16777215, "0020d9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537"),
            ],
            2,
            2,
            1,
            0
        )

        tx_u5, tx_s5 = self.check_bip143_tx(
            "010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000",
            "0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000",
            [(9.87654321, "a9149993a429037b5d912407a71c252019287b8d27a587")],
            1,
            2,
            1,
            0
        )

        tx_u5prime = self.unsigned_copy(tx_s5)
        tx_s_hex = tx_s5.as_hex()
        tx_u5prime.set_unspents(tx_s5.unspents)

        ss = ["56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae", "0020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54"]
        p2sh_lookup = build_p2sh_lookup([h2b(x) for x in ss])
        for se, sighash_type in [
            (0x730fff80e1413068a05b57d6a58261f07551163369787f349438ea38ca80fac6, SIGHASH_ALL),
            (0x11fa3d25a17cbc22b29c44a484ba552b5a53149d106d3d853e22fdd05a2d8bb3, SIGHASH_NONE),
            (0x77bf4141a87d55bdd7f3cd0bdccf6e9e642935fec45f2f30047be7b799120661, SIGHASH_SINGLE),
            (0x14af36970f5025ea3e8b5542c0f8ebe7763e674838d08808896b63c3351ffe49, SIGHASH_ANYONECANPAY|SIGHASH_ALL),
            (0xfe9a95c19eef81dde2b95c1284ef39be497d128e2aa46916fb02d552485e0323, SIGHASH_ANYONECANPAY|SIGHASH_NONE),
            (0x428a7aee9f0c2af0cd19af3cf1c78149951ea528726989b2e83e4778d2c3f890, SIGHASH_ANYONECANPAY|SIGHASH_SINGLE),
        ]:
            tx_u5prime.sign(hash_type=sighash_type, hash160_lookup=build_hash160_lookup([se]), p2sh_lookup=p2sh_lookup)

        self.check_signed(tx_u5prime)
        tx_hex = tx_u5prime.as_hex()
        self.assertEqual(tx_hex, tx_s_hex)

        self.assertEqual(b2h(tx_s5.hash_prevouts(SIGHASH_ALL)),
                         "74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0")
        self.assertEqual(b2h(tx_s5.hash_sequence(SIGHASH_ALL)),
                         "3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044")
        self.assertEqual(b2h(tx_s5.hash_outputs(SIGHASH_ALL, 0)),
                         "bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc")
        self.assertEqual(b2h(tx_s5.hash_outputs(SIGHASH_SINGLE, 0)),
                         "9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f708")
        script = tx_s5.txs_in[0].witness[-1]
        self.assertEqual(b2h(tx_s5.segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_ALL)),
                         "0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa03bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e7066504436641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc0000000001000000")

        self.assertEqual(b2h(tx_s5.segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_NONE)),
                         "0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000002000000")

        self.assertEqual(b2h(tx_s5.segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_SINGLE)),
                         "0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f7080000000003000000")

        self.assertEqual(b2h(tx_s5.segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_ALL | SIGHASH_ANYONECANPAY)),
                         "010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc0000000081000000")

        self.assertEqual(b2h(tx_s5.segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_NONE | SIGHASH_ANYONECANPAY)),
                         "010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000082000000")

        self.assertEqual(b2h(tx_s5.segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_SINGLE | SIGHASH_ANYONECANPAY)),
                         "010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f7080000000083000000")

        tx = Tx.from_hex("010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff0101000000000000000000000000")
        tx.set_witness(0, [h2b(x) for x in [
            "30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01",
            "02a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c",
            "ad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01"
        ]])
        tx = Tx.from_hex("0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000")
        tx_hex = tx.as_hex()
        print(tx)
        print(tx_hex)
        tx = Tx.from_hex("010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff0101000000000000000000000000")
        self.assertEqual(tx_hex, "0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000")

        tx_u6, tx_s6 = self.check_bip143_tx(
            "010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff0101000000000000000000000000",
            "0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000",
            [(0.002, "00209e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19")],
            1,
            1,
            1,
            0
        )

        tx_u7, tx_s7 = self.check_bip143_tx(
            "01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000000000000",
            "010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000",
            [(0.002, "00209b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52")],
            1,
            1,
            1,
            0
        )
        print(tx_s7.txs_in[0])
Example #52
0
# Very important part. When you move funds to a p2sh address you write a special scriptPubKey:
# Instead of: OP_DUP OP_HASH160 <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG
# your p2sh scriptPubKey will be:
# OP_HASH160 <hash(redeemScript)> OP_EQUAL
# standard_tx_out_script(address) gives the scriptPubKey for a given multisig address
script = standard_tx_out_script(address)
# Fake coinbase transaction to fill our p2sh address
# It it is a coinbase transaction we put in a newly constructed block.
tx_in = TxIn.coinbase_tx_in(script=b'')
print("TxIn: %s" %  tx_in.__str__())
tx_out = TxOut(1000000, script)
print("TxOut: %s" %  tx_out.__str__())
tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
tx1.as_hex()
# we now have an UTXO redeemable by supplying the script and the required sigs.
# tx_utils.create_tx() allows to spend all the UTXO from the preavious tx to an arbitrary address.
tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()])
# to split the input in each of the generated addresses
# tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[i].address() for i in range(len(keys))])
print("unsigned transaction:")
print("bad signatures: %s" % tx2.bad_signature_count())
print(tx2.as_hex())
for i in range(1, N+1):
    print("signining with key number: %s" % i)
    hash160_lookup = build_hash160_lookup([keys[i].secret_exponent()])
    p2sh_lookup = build_p2sh_lookup([underlying_script])
    tx2.sign(hash160_lookup=hash160_lookup,p2sh_lookup=p2sh_lookup)
    print(tx2.as_hex())
    print("This transactions have now : %s signature of %t necessary" % (i, N)) 
    print("bad signatures: %s" % tx2.bad_signature_count())