Пример #1
0
def get_tx(tx_hash):
    """
    Get a Tx by its hash.
    """
    # TODO: fix this
    j = get_json_for_hash(tx_hash)
    txs_in = []
    for j_in in j.get("in"):
        if j_in.get("coinbase"):
            txs_in.append(
                TxIn.coinbase_tx_in(binascii.unhexlify(j_in["coinbase"])))
        else:
            txs_in.append(
                TxIn(h2b_rev(j_in["prev_out"]["hash"]),
                     int(j_in["prev_out"]["n"]),
                     tools.compile(j_in["scriptSig"])))

    txs_out = []
    for j_out in j.get("out"):
        txs_out.append(
            TxOut(int(btc_to_satoshi(j_out["value"])),
                  tools.compile(j_out["scriptPubKey"])))

    tx = Tx(int(j["ver"]), txs_in, txs_out, int(j["lock_time"]))
    assert tx.hash() == tx_hash
    return tx
Пример #2
0
def store_nulldata(service, testnet, nulldatatxout, keys,
                   changeaddress=None, txouts=None, fee=10000,
                   locktime=0, publish=True):

    # get required satoshis
    txouts = txouts if txouts else []
    required = sum(list(map(lambda txout: txout.coin_value, txouts))) + fee

    # get txins
    addresses = list(map(lambda key: key.address(), keys))
    txins, total = find_txins(service, addresses, required)
    if total < required:
        raise exceptions.InsufficientFunds(required, total)

    # setup txouts
    changeaddress = changeaddress if changeaddress else addresses[0]
    changeout = deserialize.txout(testnet, changeaddress, total - required)
    txouts = txouts + [nulldatatxout, changeout]

    # create, sign and publish tx
    tx = Tx(1, txins, txouts, locktime)
    tx = sign_tx(service, testnet, tx, keys)
    if publish:
        service.send_tx(tx)
    return tx.hash()
Пример #3
0
    def doit(num_ins, num_outs, master_xpub, subpath="0/%d", fee=10000):
        psbt = BasicPSBT()
        txn = Tx(2, [], [])

        # we have a key; use it to provide "plausible" value inputs
        from pycoin.key.BIP32Node import BIP32Node
        mk = BIP32Node.from_wallet_key(master_xpub)
        xfp = mk.fingerprint()

        psbt.inputs = [BasicPSBTInput(idx=i) for i in range(num_ins)]
        psbt.outputs = [BasicPSBTOutput(idx=i) for i in range(num_outs)]

        for i in range(num_ins):
            # make a fake txn to supply each of the inputs
            # - each input is 1BTC

            # addr where the fake money will be stored.
            subkey = mk.subkey_for_path(subpath % i)
            sec = subkey.sec()
            assert len(sec) == 33, "expect compressed"
            assert subpath[0:2] == '0/'

            psbt.inputs[i].bip32_paths[sec] = xfp + pack('<II', 0, i)

            # UTXO that provides the funding for to-be-signed txn
            supply = Tx(2, [TxIn(pack('4Q', 0xdead, 0xbeef, 0, 0), 73)], [])

            scr = bytes([0x76, 0xa9, 0x14]) + subkey.hash160() + bytes(
                [0x88, 0xac])
            supply.txs_out.append(TxOut(1E8, scr))

            with BytesIO() as fd:
                supply.stream(fd)
                psbt.inputs[i].utxo = fd.getvalue()

            if 0:
                with BytesIO() as fd:
                    supply.stream(fd, include_witness_data=True)
                    psbt.inputs[i].witness_utxo = fd.getvalue()

            spendable = TxIn(supply.hash(), 0)
            txn.txs_in.append(spendable)

        for i in range(num_outs):
            # random P2PKH
            scr = bytes([0x76, 0xa9, 0x14]) + pack(
                'I', i + 1) + bytes(16) + bytes([0x88, 0xac])
            h = TxOut(round(((1E8 * num_ins) - fee) / num_outs, 4), scr)
            txn.txs_out.append(h)

        with BytesIO() as b:
            txn.stream(b)
            psbt.txn = b.getvalue()

        rv = BytesIO()
        psbt.serialize(rv)
        assert rv.tell() <= MAX_TXN_LEN, 'too fat'

        return rv.getvalue()
Пример #4
0
def get_tx(tx_hash):
    """
    Get a Tx by its hash.
    """
    # TODO: fix this
    j = get_json_for_hash(tx_hash)
    txs_in = []
    for j_in in j.get("in"):
        if j_in.get("coinbase"):
            txs_in.append(TxIn.coinbase_tx_in(binascii.unhexlify(j_in["coinbase"])))
        else:
            txs_in.append(TxIn(
                h2b_rev(j_in["prev_out"]["hash"]),
                int(j_in["prev_out"]["n"]),
                tools.compile(j_in["scriptSig"])))

    txs_out = []
    for j_out in j.get("out"):
        txs_out.append(TxOut(int(btc_to_satoshi(j_out["value"])), tools.compile(j_out["scriptPubKey"])))

    tx = Tx(int(j["ver"]), txs_in, txs_out, int(j["lock_time"]))
    assert tx.hash() == tx_hash
    return tx
Пример #5
0
    def _test_sighash_single(self, netcode):
        k0 = Key(secret_exponent=PRIV_KEYS[0],
                 is_compressed=True,
                 netcode=netcode)
        k1 = Key(secret_exponent=PRIV_KEYS[1],
                 is_compressed=True,
                 netcode=netcode)
        k2 = Key(secret_exponent=PRIV_KEYS[2],
                 is_compressed=True,
                 netcode=netcode)
        k3 = Key(secret_exponent=PRIV_KEYS[3],
                 is_compressed=True,
                 netcode=netcode)
        k4 = Key(secret_exponent=PRIV_KEYS[4],
                 is_compressed=True,
                 netcode=netcode)
        k5 = Key(secret_exponent=PRIV_KEYS[5],
                 is_compressed=True,
                 netcode=netcode)

        # Fake a coinbase transaction
        coinbase_tx = Tx.coinbase_tx(k0.sec(), 500000000)
        coinbase_tx.txs_out.append(
            TxOut(1000000000,
                  pycoin_compile('%s OP_CHECKSIG' % b2h(k1.sec()))))
        coinbase_tx.txs_out.append(
            TxOut(1000000000,
                  pycoin_compile('%s OP_CHECKSIG' % b2h(k2.sec()))))

        self.assertEqual(
            '2acbe1006f7168bad538b477f7844e53de3a31ffddfcfc4c6625276dd714155a',
            b2h_rev(coinbase_tx.hash()))

        # Make the test transaction
        txs_in = [
            TxIn(coinbase_tx.hash(), 0),
            TxIn(coinbase_tx.hash(), 1),
            TxIn(coinbase_tx.hash(), 2),
        ]
        txs_out = [
            TxOut(900000000, standard_tx_out_script(k3.address())),
            TxOut(800000000, standard_tx_out_script(k4.address())),
            TxOut(800000000, standard_tx_out_script(k5.address())),
        ]
        tx = Tx(1, txs_in, txs_out)
        tx.set_unspents(coinbase_tx.txs_out)

        self.assertEqual(
            '791b98ef0a3ac87584fe273bc65abd89821569fd7c83538ac0625a8ca85ba587',
            b2h_rev(tx.hash()))

        sig_type = SIGHASH_SINGLE

        sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0,
                                     sig_type)
        self.assertEqual(
            'cc52d785a3b4133504d1af9e60cd71ca422609cb41df3a08bbb466b2a98a885e',
            b2h(to_bytes_32(sig_hash)))

        sig = sigmake(k0, sig_hash, sig_type)
        self.assertTrue(sigcheck(k0, sig_hash, sig[:-1]))

        tx.txs_in[0].script = pycoin_compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(0))

        sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1,
                                     sig_type)
        self.assertEqual(
            '93bb883d70fccfba9b8aa2028567aca8357937c65af7f6f5ccc6993fd7735fb7',
            b2h(to_bytes_32(sig_hash)))

        sig = sigmake(k1, sig_hash, sig_type)
        self.assertTrue(sigcheck(k1, sig_hash, sig[:-1]))

        tx.txs_in[1].script = pycoin_compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(1))

        sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2,
                                     sig_type)
        self.assertEqual(
            '53ef7f67c3541bffcf4e0d06c003c6014e2aa1fb38ff33240b3e1c1f3f8e2a35',
            b2h(to_bytes_32(sig_hash)))

        sig = sigmake(k2, sig_hash, sig_type)
        self.assertTrue(sigcheck(k2, sig_hash, sig[:-1]))

        tx.txs_in[2].script = pycoin_compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(2))

        sig_type = SIGHASH_SINGLE | SIGHASH_ANYONECANPAY

        sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0,
                                     sig_type)
        self.assertEqual(
            '2003393d246a7f136692ce7ab819c6eadc54ffea38eb4377ac75d7d461144e75',
            b2h(to_bytes_32(sig_hash)))

        sig = sigmake(k0, sig_hash, sig_type)
        self.assertTrue(sigcheck(k0, sig_hash, sig[:-1]))

        tx.txs_in[0].script = pycoin_compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(0))

        sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1,
                                     sig_type)
        self.assertEqual(
            'e3f469ac88e9f35e8eff0bd8ad4ad3bf899c80eb7645947d60860de4a08a35df',
            b2h(to_bytes_32(sig_hash)))

        sig = sigmake(k1, sig_hash, sig_type)
        self.assertTrue(sigcheck(k1, sig_hash, sig[:-1]))

        tx.txs_in[1].script = pycoin_compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(1))

        sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2,
                                     sig_type)
        self.assertEqual(
            'bacd7c3ab79cad71807312677c1788ad9565bf3c00ab9a153d206494fb8b7e6a',
            b2h(to_bytes_32(sig_hash)))

        sig = sigmake(k2, sig_hash, sig_type)
        self.assertTrue(sigcheck(k2, sig_hash, sig[:-1]))

        tx.txs_in[2].script = pycoin_compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(2))
Пример #6
0
    def doit(num_ins,
             num_outs,
             master_xpub,
             subpath="0/%d",
             fee=10000,
             outvals=None,
             segwit_in=False,
             outstyles=['p2pkh'],
             change_outputs=[]):
        psbt = BasicPSBT()
        txn = Tx(2, [], [])

        # we have a key; use it to provide "plausible" value inputs
        mk = BIP32Node.from_wallet_key(master_xpub)
        xfp = mk.fingerprint()

        psbt.inputs = [BasicPSBTInput(idx=i) for i in range(num_ins)]
        psbt.outputs = [BasicPSBTOutput(idx=i) for i in range(num_outs)]

        for i in range(num_ins):
            # make a fake txn to supply each of the inputs
            # - each input is 1BTC

            # addr where the fake money will be stored.
            subkey = mk.subkey_for_path(subpath % i)
            sec = subkey.sec()
            assert len(sec) == 33, "expect compressed"
            assert subpath[0:2] == '0/'

            psbt.inputs[i].bip32_paths[sec] = xfp + pack('<II', 0, i)

            # UTXO that provides the funding for to-be-signed txn
            supply = Tx(2, [TxIn(pack('4Q', 0xdead, 0xbeef, 0, 0), 73)], [])

            scr = bytes([0x76, 0xa9, 0x14]) + subkey.hash160() + bytes(
                [0x88, 0xac])

            supply.txs_out.append(TxOut(1E8, scr))

            with BytesIO() as fd:
                if not segwit_in:
                    supply.stream(fd)
                    psbt.inputs[i].utxo = fd.getvalue()
                else:
                    supply.txs_out[-1].stream(fd)
                    psbt.inputs[i].witness_utxo = fd.getvalue()

            spendable = TxIn(supply.hash(), 0)
            txn.txs_in.append(spendable)

        for i in range(num_outs):
            # random P2PKH
            if not outstyles:
                style = ADDR_STYLES[i % len(ADDR_STYLES)]
            else:
                style = outstyles[i % len(outstyles)]

            if i in change_outputs:
                scr, act_scr, isw, pubkey, sp = make_change_addr(mk, style)
                psbt.outputs[i].bip32_paths[pubkey] = sp
            else:
                scr = act_scr = fake_dest_addr(style)
                isw = ('w' in style)
                #if style.endswith('sh'):

            assert scr
            act_scr = act_scr or scr

            if isw:
                psbt.outputs[i].witness_script = scr
            elif style.endswith('sh'):
                psbt.outputs[i].redeem_script = scr

            if not outvals:
                h = TxOut(round(((1E8 * num_ins) - fee) / num_outs, 4),
                          act_scr)
            else:
                h = TxOut(outvals[i], act_scr)

            txn.txs_out.append(h)

        with BytesIO() as b:
            txn.stream(b)
            psbt.txn = b.getvalue()

        rv = BytesIO()
        psbt.serialize(rv)
        assert rv.tell() <= MAX_TXN_LEN, 'too fat'

        return rv.getvalue()
Пример #7
0
    def doit(num_ins, num_outs, M, keys, fee=10000,
                outvals=None, segwit_in=False, outstyles=['p2pkh'], change_outputs=[],
                incl_xpubs=False):
        psbt = BasicPSBT()
        txn = Tx(2,[],[])

        if incl_xpubs:
            # add global header with XPUB's
            # - assumes BIP45
            for xfp, m, sk in keys:
                kk = pack('<II', xfp, 45|0x80000000)
                psbt.xpubs.append( (sk.serialize(as_private=False), kk) )

        psbt.inputs = [BasicPSBTInput(idx=i) for i in range(num_ins)]
        psbt.outputs = [BasicPSBTOutput(idx=i) for i in range(num_outs)]

        for i in range(num_ins):
            # make a fake txn to supply each of the inputs
            # - each input is 1BTC

            # addr where the fake money will be stored.
            addr, scriptPubKey, script, details = make_ms_address(M, keys, idx=i)

            # lots of supporting details needed for p2sh inputs
            if segwit_in:
                psbt.inputs[i].witness_script = script
            else:
                psbt.inputs[i].redeem_script = script

            for pubkey, xfp_path in details:
                psbt.inputs[i].bip32_paths[pubkey] = b''.join(pack('<I', j) for j in xfp_path)

            # UTXO that provides the funding for to-be-signed txn
            supply = Tx(2,[TxIn(pack('4Q', 0xdead, 0xbeef, 0, 0), 73)],[])

            supply.txs_out.append(TxOut(1E8, scriptPubKey))

            with BytesIO() as fd:
                if not segwit_in:
                    supply.stream(fd)
                    psbt.inputs[i].utxo = fd.getvalue()
                else:
                    supply.txs_out[-1].stream(fd)
                    psbt.inputs[i].witness_utxo = fd.getvalue()

            spendable = TxIn(supply.hash(), 0)
            txn.txs_in.append(spendable)


        for i in range(num_outs):
            # random P2PKH
            if not outstyles:
                style = ADDR_STYLES[i % len(ADDR_STYLES)]
            else:
                style = outstyles[i % len(outstyles)]

            if i in change_outputs:
                addr, scriptPubKey, scr, details = \
                    make_ms_address(M, keys, idx=i, addr_fmt=unmap_addr_fmt[style])

                for pubkey, xfp_path in details:
                    psbt.outputs[i].bip32_paths[pubkey] = b''.join(pack('<I', j) for j in xfp_path)

                if 'w' in style:
                    psbt.outputs[i].witness_script = scr
                    if style.endswith('p2sh'):
                        psbt.outputs[i].redeem_script = b'\0\x20' + sha256(scr).digest()
                elif style.endswith('sh'):
                    psbt.outputs[i].redeem_script = scr
            else:
                scr = fake_dest_addr(style)

            assert scr

            if not outvals:
                h = TxOut(round(((1E8*num_ins)-fee) / num_outs, 4), scriptPubKey)
            else:
                h = TxOut(outvals[i], scriptPubKey)

            txn.txs_out.append(h)

        with BytesIO() as b:
            txn.stream(b)
            psbt.txn = b.getvalue()

        rv = BytesIO()
        psbt.serialize(rv)
        assert rv.tell() <= MAX_TXN_LEN, 'too fat'

        return rv.getvalue()
Пример #8
0
def fake_txn(num_ins,
             num_outs,
             master_xpub=None,
             subpath="0/%d",
             fee=10000,
             outvals=None,
             segwit_in=False,
             outstyles=['p2pkh'],
             is_testnet=False,
             change_style='p2pkh',
             partial=False,
             change_outputs=[]):

    # make various size txn's ... completely fake and pointless values
    # - but has UTXO's to match needs
    # - input total = num_inputs * 1BTC
    from pycoin.tx.Tx import Tx
    from pycoin.tx.TxIn import TxIn
    from pycoin.tx.TxOut import TxOut
    from pycoin.serialize import h2b_rev
    from struct import pack

    psbt = BasicPSBT()
    txn = Tx(2, [], [])

    # we have a key; use it to provide "plausible" value inputs
    mk = BIP32Node.from_wallet_key(master_xpub)
    xfp = mk.fingerprint()

    psbt.inputs = [BasicPSBTInput(idx=i) for i in range(num_ins)]
    psbt.outputs = [BasicPSBTOutput(idx=i) for i in range(num_outs)]

    outputs = []

    for i in range(num_ins):
        # make a fake txn to supply each of the inputs
        # - each input is 1BTC

        # addr where the fake money will be stored.
        subkey = mk.subkey_for_path(subpath % i)
        sec = subkey.sec()
        assert len(sec) == 33, "expect compressed"
        assert subpath[0:2] == '0/'

        if partial and (i == 0):
            psbt.inputs[i].bip32_paths[sec] = b'Nope' + pack('<II', 0, i)
        else:
            psbt.inputs[i].bip32_paths[sec] = xfp + pack('<II', 0, i)

        # UTXO that provides the funding for to-be-signed txn
        supply = Tx(2, [TxIn(pack('4Q', 0xdead, 0xbeef, 0, 0), 73)], [])

        scr = bytes([0x76, 0xa9, 0x14]) + subkey.hash160() + bytes(
            [0x88, 0xac])

        supply.txs_out.append(TxOut(1E8, scr))

        with BytesIO() as fd:
            if not segwit_in:
                supply.stream(fd)
                psbt.inputs[i].utxo = fd.getvalue()
            else:
                supply.txs_out[-1].stream(fd)
                psbt.inputs[i].witness_utxo = fd.getvalue()

        spendable = TxIn(supply.hash(), 0)
        txn.txs_in.append(spendable)

    for i in range(num_outs):
        is_change = False

        # random P2PKH
        if not outstyles:
            style = ADDR_STYLES[i % len(ADDR_STYLES)]
        else:
            style = outstyles[i % len(outstyles)]

        if i in change_outputs:
            scr, act_scr, isw, pubkey, sp = make_change_addr(mk, change_style)
            psbt.outputs[i].bip32_paths[pubkey] = sp
            is_change = True
        else:
            scr = act_scr = fake_dest_addr(style)
            isw = ('w' in style)

        assert scr
        act_scr = act_scr or scr

        if isw:
            psbt.outputs[i].witness_script = scr
        elif style.endswith('sh'):
            psbt.outputs[i].redeem_script = scr

        if not outvals:
            h = TxOut(round(((1E8 * num_ins) - fee) / num_outs, 4), act_scr)
        else:
            h = TxOut(outvals[i], act_scr)

        outputs.append(
            (Decimal(h.coin_value) / Decimal(1E8), act_scr, is_change))

        txn.txs_out.append(h)

    with BytesIO() as b:
        txn.stream(b)
        psbt.txn = b.getvalue()

    rv = BytesIO()
    psbt.serialize(rv)

    return rv.getvalue(), [(n, render_address(s, is_testnet), ic)
                           for n, s, ic in outputs]