def coinbase():
    account = Account.Account(TEST_EMAIL1)
    wallet = Wallet.Wallet.from_wallet_key(account.get_wallet_keys()[0])
    address = wallet.address()
    assert is_address_valid(address)
    tx_in = TxIn.coinbase_tx_in(script=b'')
    tx_out = TxOut(50 * 1e8, standard_tx_out_script(address))
    tx = Tx(1, [tx_in], [tx_out])
    return tx.as_hex()
Exemple #2
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()
def main():
    if len(sys.argv) != 2:
        print("usage: %s address" % sys.argv[0])
        sys.exit(-1)

    # validate the address
    address = sys.argv[1]
    assert is_address_valid(address)

    print("creating coinbase transaction to %s" % address)

    tx_in = TxIn.coinbase_tx_in(script=b'')
    tx_out = TxOut(50*1e8, script_for_address(address))
    tx = Tx(1, [tx_in], [tx_out])
    print("Here is the tx as hex:\n%s" % tx.as_hex())
Exemple #4
0
def main():
    if len(sys.argv) != 2:
        print("usage: %s address" % sys.argv[0])
        sys.exit(-1)

    # validate the address
    address = sys.argv[1]
    assert is_address_valid(address)

    print("creating coinbase transaction to %s" % address)

    tx_in = TxIn.coinbase_tx_in(script=b'')
    tx_out = TxOut(50*1e8, standard_tx_out_script(address))
    tx = Tx(1, [tx_in], [tx_out])
    print("Here is the tx as hex:\n%s" % tx.as_hex())
    def get_raw_unsigned(self, fee_satoshi):
        """Return raw transaction ready for signing

        May return a transaction with amount=0 if the input amount is not enough to cover fees
        """
        txout = self.tx.txs_out[self.vout]
        amount_satoshi = txout.coin_value

        if fee_satoshi >= amount_satoshi:
            logging.warning('Insufficient funds to cover fee')
            logging.warning('txout has value of {}, fee = {}'.format(
                amount_satoshi, fee_satoshi))

        # Calculate adjusted amount = input amount - fee
        adjusted_amount_satoshi = max(0, amount_satoshi - fee_satoshi)
        logging.debug('tx amount = amount - fee = {} - {} = {}'.format(
            amount_satoshi, fee_satoshi, adjusted_amount_satoshi))
        assert adjusted_amount_satoshi >= 0
        adjusted_amount_btc = decimal.Decimal(
            adjusted_amount_satoshi) / satoshi_per_btc

        logging.debug("Create tx: {} sat -> {}".format(adjusted_amount_satoshi,
                                                       self.dest_address))
        logging.info("Input tx id = {}, vout={}".format(
            self.tx.id().encode("ascii"), self.vout))
        txin = TxIn(self.tx.hash(),
                    self.vout,
                    sequence=MAX_BIP125_RBF_SEQUENCE)
        scriptPubKey = pycoin.ui.script_obj_from_address(self.dest_address)
        txout = TxOut(adjusted_amount_satoshi, scriptPubKey.script())

        # Set nlocktime to the current blockheight to discourage 'fee sniping', as per the core
        # wallet implementation
        nlocktime = util.get_current_blockcount() or 0

        version = 1
        tx = Tx(version, [
            txin,
        ], [
            txout,
        ], nlocktime)
        return tx.as_hex()
Exemple #6
0
    def do_test_tx(self, sighash, index_, flags):
        txhash, seq, script, witness_script = b'0' * 32, 0xffffffff, b'\x51', b'000000'
        out_script, spend_script, locktime = b'\x00\x00\x51', b'\x00\x51', 999999
        txs_in = [TxIn(txhash, 0, script, seq),
                  TxIn(txhash, 1, script+b'\x51', seq-1),
                  TxIn(txhash, 2, script+b'\x51\x51', seq-2),
                  TxIn(txhash, 3, script+b'\x51\x51\x51', seq-3)]
        txs_out = [TxOut(55, out_script),
                   TxOut(54, out_script+b'\x51'),
                   TxOut(53, out_script+b'\x51\x51')]
        pytx = Tx(2, txs_in, txs_out, lock_time=locktime)
        pytx.unspents = {0: TxOut(5000, spend_script), # FIXME: Make script unique
                         1: TxOut(5001, spend_script),
                         2: TxOut(5002, spend_script),
                         3: TxOut(5003, spend_script)}
        unspent = pytx.unspents[index_]
        pytx_hex = pytx.as_hex()
        if flags & USE_WITNESS:
            pytx_hash = pytx.signature_for_hash_type_segwit(unspent.script, index_, sighash)
        else:
            pytx_hash = pytx.signature_hash(spend_script, index_, sighash)
        pytx_hash = hex_from_bytes(to_bytes_32(pytx_hash))

        tx = tx_init(2, locktime, 3, 3)
        tx_add_input(tx, tx_input_init(txhash, 0, seq, script, None))
        tx_add_raw_input(tx, txhash, 1, seq-1, script+b'\x51', None)
        tx_add_raw_input(tx, txhash, 2, seq-2, script+b'\x51\x51', None)
        tx_add_raw_input(tx, txhash, 3, seq-3, script+b'\x51\x51\x51', None)
        tx_add_raw_output(tx, 55, out_script, 0)
        tx_add_raw_output(tx, 54, out_script+b'\x51', 0)
        tx_add_raw_output(tx, 53, out_script+b'\x51\x51', 0)
        tx_hex = tx_to_hex(tx, 0)
        amount = (index_ + 1) * 5000
        tx_hash = tx_get_btc_signature_hash(tx, index_,
                                            unspent.script, unspent.coin_value,
                                            sighash, flags)
        tx_hash = hex_from_bytes(tx_hash)

        self.assertEqual(pytx_hex, tx_hex)
        self.assertEqual(pytx_hash, tx_hash)
    def do_test_tx(self, sighash, index_, flags):
        txhash, seq, script, witness_script = b'0' * 32, 0xffffffff, b'\x51', b'000000'
        out_script, spend_script, locktime = b'\x00\x00\x51', b'\x00\x51', 999999
        txs_in = [TxIn(txhash, 0, script, seq),
                  TxIn(txhash, 1, script+b'\x51', seq-1),
                  TxIn(txhash, 2, script+b'\x51\x51', seq-2),
                  TxIn(txhash, 3, script+b'\x51\x51\x51', seq-3)]
        txs_out = [TxOut(55, out_script),
                   TxOut(54, out_script+b'\x51'),
                   TxOut(53, out_script+b'\x51\x51')]
        pytx = Tx(2, txs_in, txs_out, lock_time=locktime)
        pytx.unspents = {0: TxOut(5000, spend_script), # FIXME: Make script unique
                         1: TxOut(5001, spend_script),
                         2: TxOut(5002, spend_script),
                         3: TxOut(5003, spend_script)}
        unspent = pytx.unspents[index_]
        pytx_hex = pytx.as_hex()
        if flags & USE_WITNESS:
            pytx_hash = pytx.signature_for_hash_type_segwit(unspent.script, index_, sighash)
        else:
            pytx_hash = pytx.signature_hash(spend_script, index_, sighash)
        pytx_hash = hex_from_bytes(to_bytes_32(pytx_hash))

        tx = tx_init(2, locktime, 3, 3)
        tx_add_input(tx, tx_input_init(txhash, 0, seq, script, None))
        tx_add_raw_input(tx, txhash, 1, seq-1, script+b'\x51', None, 0)
        tx_add_raw_input(tx, txhash, 2, seq-2, script+b'\x51\x51', None, 0)
        tx_add_raw_input(tx, txhash, 3, seq-3, script+b'\x51\x51\x51', None, 0)
        tx_add_raw_output(tx, 55, out_script, 0)
        tx_add_raw_output(tx, 54, out_script+b'\x51', 0)
        tx_add_raw_output(tx, 53, out_script+b'\x51\x51', 0)
        tx_hex = tx_to_hex(tx, 0)
        amount = (index_ + 1) * 5000
        tx_hash = tx_get_btc_signature_hash(tx, index_,
                                            unspent.script, unspent.coin_value,
                                            sighash, flags)
        tx_hash = hex_from_bytes(tx_hash)

        self.assertEqual(pytx_hex, tx_hex)
        self.assertEqual(pytx_hash, tx_hash)
Exemple #8
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()
Exemple #9
0
def main():
    parser = create_parser()
    args = parser.parse_args()

    (txs, spendables, payables, key_iters, p2sh_lookup, tx_db,
     warning_tx_cache, warning_tx_for_tx_hash,
     warning_spendables) = parse_context(args, parser)

    txs_in = []
    txs_out = []
    unspents = []

    # we use a clever trick here to keep each tx_in corresponding with its tx_out
    for tx in txs:
        smaller = min(len(tx.txs_in), len(tx.txs_out))
        txs_in.extend(tx.txs_in[:smaller])
        txs_out.extend(tx.txs_out[:smaller])
        unspents.extend(tx.unspents[:smaller])
    for tx in txs:
        smaller = min(len(tx.txs_in), len(tx.txs_out))
        txs_in.extend(tx.txs_in[smaller:])
        txs_out.extend(tx.txs_out[smaller:])
        unspents.extend(tx.unspents[smaller:])
    for spendable in spendables:
        txs_in.append(spendable.tx_in())
        unspents.append(spendable)
    for address, coin_value in payables:
        script = standard_tx_out_script(address)
        txs_out.append(TxOut(coin_value, script))

    lock_time = args.lock_time
    version = args.transaction_version

    # if no lock_time is explicitly set, inherit from the first tx or use default
    if lock_time is None:
        if txs:
            lock_time = txs[0].lock_time
        else:
            lock_time = DEFAULT_LOCK_TIME

    # if no version is explicitly set, inherit from the first tx or use default
    if version is None:
        if txs:
            version = txs[0].version
        else:
            version = DEFAULT_VERSION

    if args.remove_tx_in:
        s = set(args.remove_tx_in)
        txs_in = [tx_in for idx, tx_in in enumerate(txs_in) if idx not in s]

    if args.remove_tx_out:
        s = set(args.remove_tx_out)
        txs_out = [
            tx_out for idx, tx_out in enumerate(txs_out) if idx not in s
        ]

    tx = Tx(txs_in=txs_in,
            txs_out=txs_out,
            lock_time=lock_time,
            version=version,
            unspents=unspents)

    fee = args.fee
    try:
        if len(payables) > 0:
            distribute_from_split_pool(tx, fee)
    except ValueError as ex:
        print("warning: %s" % ex.args[0], file=sys.stderr)

    unsigned_before = tx.bad_signature_count()
    unsigned_after = unsigned_before
    if unsigned_before > 0 and key_iters:

        def wif_iter(iters):
            while len(iters) > 0:
                for idx, iter in enumerate(iters):
                    try:
                        wif = next(iter)
                        yield wif
                    except StopIteration:
                        iters = iters[:idx] + iters[idx + 1:]
                        break

        print("signing...", file=sys.stderr)
        sign_tx(tx, wif_iter(key_iters), p2sh_lookup=p2sh_lookup)

        unsigned_after = tx.bad_signature_count()
        if unsigned_after > 0:
            print("warning: %d TxIn items still unsigned" % unsigned_after,
                  file=sys.stderr)

    if len(tx.txs_in) == 0:
        print("warning: transaction has no inputs", file=sys.stderr)

    if len(tx.txs_out) == 0:
        print("warning: transaction has no outputs", file=sys.stderr)

    include_unspents = (unsigned_after > 0)
    tx_as_hex = tx.as_hex(include_unspents=include_unspents)

    if args.output_file:
        f = args.output_file
        if f.name.endswith(".hex"):
            f.write(tx_as_hex.encode("utf8"))
        else:
            tx.stream(f)
            if include_unspents:
                tx.stream_unspents(f)
        f.close()
    elif args.show_unspents:
        for spendable in tx.tx_outs_as_spendable():
            print(spendable.as_text())
    else:
        if not tx.missing_unspents():
            check_fees(tx)
        dump_tx(tx, args.network, args.verbose_signature, args.disassemble,
                args.trace, args.pdb)
        if include_unspents:
            print(
                "including unspents in hex dump since transaction not fully signed"
            )
        print(tx_as_hex)

    if args.cache:
        if tx_db is None:
            warning_tx_cache = message_about_tx_cache_env()
            warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(
                args.network)
            tx_db = get_tx_db(args.network)
        tx_db.put(tx)

    if args.bitcoind_url:
        if tx_db is None:
            warning_tx_cache = message_about_tx_cache_env()
            warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(
                args.network)
            tx_db = get_tx_db(args.network)
        validate_bitcoind(tx, tx_db, args.bitcoind_url)

    if tx.missing_unspents():
        print("\n** can't validate transaction as source transactions missing",
              file=sys.stderr)
    else:
        try:
            if tx_db is None:
                warning_tx_cache = message_about_tx_cache_env()
                warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(
                    args.network)
                tx_db = get_tx_db(args.network)
            tx.validate_unspents(tx_db)
            print('all incoming transaction values validated')
        except BadSpendableError as ex:
            print("\n**** ERROR: FEES INCORRECTLY STATED: %s" % ex.args[0],
                  file=sys.stderr)
        except Exception as ex:
            print(
                "\n*** can't validate source transactions as untampered: %s" %
                ex.args[0],
                file=sys.stderr)

    # print warnings
    for m in [warning_tx_cache, warning_tx_for_tx_hash, warning_spendables]:
        if m:
            print("warning: %s" % m, file=sys.stderr)