示例#1
0
def test_create_sighash_txs(setup_tx_creation):
    #non-standard hash codes:
    for sighash in [
            bitcoin.SIGHASH_ANYONECANPAY + bitcoin.SIGHASH_SINGLE,
            bitcoin.SIGHASH_NONE, bitcoin.SIGHASH_SINGLE
    ]:
        wallet = make_wallets(1, [[2, 0, 0, 0, 1]], 3)[0]['wallet']
        sync_wallet(wallet)
        amount = 350000000
        ins_full = wallet.select_utxos(0, amount)
        print "using hashcode: " + str(sighash)
        txid = make_sign_and_push(ins_full, wallet, amount, hashcode=sighash)
        assert txid

    #Create an invalid sighash single (too many inputs)
    extra = wallet.select_utxos(4, 100000000)  #just a few more inputs
    ins_full.update(extra)
    with pytest.raises(Exception) as e_info:
        txid = make_sign_and_push(ins_full,
                                  wallet,
                                  amount,
                                  hashcode=bitcoin.SIGHASH_SINGLE)

    #trigger insufficient funds
    with pytest.raises(Exception) as e_info:
        fake_utxos = wallet.select_utxos(4, 1000000000)
示例#2
0
def test_spend_p2sh_utxos(setup_tx_creation):
    #make a multisig address from 3 privs
    privs = [chr(x) * 32 + '\x01' for x in range(1, 4)]
    pubs = [btc.privkey_to_pubkey(binascii.hexlify(priv)) for priv in privs]
    script = btc.mk_multisig_script(pubs, 2)
    msig_addr = btc.scriptaddr(script, magicbyte=196)
    #pay into it
    wallet = make_wallets(1, [[2, 0, 0, 0, 1]], 3)[0]['wallet']
    jm_single().bc_interface.sync_wallet(wallet)
    amount = 350000000
    ins_full = wallet.select_utxos(0, amount)
    txid = make_sign_and_push(ins_full, wallet, amount, output_addr=msig_addr)
    assert txid
    #wait for mining
    time.sleep(4)
    #spend out; the input can be constructed from the txid of previous
    msig_in = txid + ":0"
    ins = [msig_in]
    #random output address and change addr
    output_addr = wallet.get_new_addr(1, 1)
    amount2 = amount - 50000
    outs = [{'value': amount2, 'address': output_addr}]
    tx = btc.mktx(ins, outs)
    sigs = []
    for priv in privs[:2]:
        sigs.append(btc.multisign(tx, 0, script, binascii.hexlify(priv)))
    tx = btc.apply_multisignatures(tx, 0, script, sigs)
    txid = jm_single().bc_interface.pushtx(tx)
    assert txid
def test_spend_p2wpkh(setup_tx_creation):
    #make 3 p2wpkh outputs from 3 privs
    privs = [struct.pack(b'B', x) * 32 + b'\x01' for x in range(1, 4)]
    pubs = [bitcoin.privkey_to_pubkey(priv) for priv in privs]
    scriptPubKeys = [bitcoin.pubkey_to_p2wpkh_script(pub) for pub in pubs]
    addresses = [str(bitcoin.CCoinAddress.from_scriptPubKey(
        spk)) for spk in scriptPubKeys]
    #pay into it
    wallet_service = make_wallets(1, [[3, 0, 0, 0, 0]], 3)[0]['wallet']
    wallet_service.sync_wallet(fast=True)
    amount = 35000000
    p2wpkh_ins = []
    for i, addr in enumerate(addresses):
        ins_full = wallet_service.select_utxos(0, amount)
        txid = make_sign_and_push(ins_full, wallet_service, amount, output_addr=addr)
        assert txid
        p2wpkh_ins.append((txid, 0))
        txhex = jm_single().bc_interface.get_transaction(txid)
        #wait for mining
        jm_single().bc_interface.tick_forward_chain(1)
    #random output address
    output_addr = wallet_service.get_internal_addr(1)
    amount2 = amount*3 - 50000
    outs = [{'value': amount2, 'address': output_addr}]
    tx = bitcoin.mktx(p2wpkh_ins, outs)

    for i, priv in enumerate(privs):
        # sign each of 3 inputs; note that bitcoin.sign
        # automatically validates each signature it creates.
        sig, msg = bitcoin.sign(tx, i, priv, amount=amount, native="p2wpkh")
        if not sig:
            assert False, msg
    txid = jm_single().bc_interface.pushtx(tx.serialize())
    assert txid
示例#4
0
def test_spend_p2wsh(setup_tx_creation):
    #make 2 x 2 of 2multisig outputs; will need 4 privs
    privs = [struct.pack(b'B', x) * 32 + b'\x01' for x in range(1, 5)]
    privs = [binascii.hexlify(priv).decode('ascii') for priv in privs]
    pubs = [bitcoin.privkey_to_pubkey(priv) for priv in privs]
    redeemScripts = [
        bitcoin.mk_multisig_script(pubs[i:i + 2], 2) for i in [0, 2]
    ]
    scriptPubKeys = [
        bitcoin.pubkeys_to_p2wsh_script(pubs[i:i + 2]) for i in [0, 2]
    ]
    addresses = [
        bitcoin.pubkeys_to_p2wsh_address(pubs[i:i + 2]) for i in [0, 2]
    ]
    #pay into it
    wallet_service = make_wallets(1, [[3, 0, 0, 0, 0]], 3)[0]['wallet']
    wallet_service.sync_wallet(fast=True)
    amount = 35000000
    p2wsh_ins = []
    for addr in addresses:
        ins_full = wallet_service.select_utxos(0, amount)
        txid = make_sign_and_push(ins_full,
                                  wallet_service,
                                  amount,
                                  output_addr=addr)
        assert txid
        p2wsh_ins.append(txid + ":0")
        #wait for mining
        time.sleep(1)
    #random output address and change addr
    output_addr = wallet_service.get_internal_addr(1)
    amount2 = amount * 2 - 50000
    outs = [{'value': amount2, 'address': output_addr}]
    tx = bitcoin.mktx(p2wsh_ins, outs)
    sigs = []
    for i in range(2):
        sigs = []
        for priv in privs[i * 2:i * 2 + 2]:
            # sign input j with each of 2 keys
            sig = bitcoin.multisign(tx,
                                    i,
                                    redeemScripts[i],
                                    priv,
                                    amount=amount)
            sigs.append(sig)
            # check that verify_tx_input correctly validates;
            assert bitcoin.verify_tx_input(tx,
                                           i,
                                           scriptPubKeys[i],
                                           sig,
                                           bitcoin.privkey_to_pubkey(priv),
                                           scriptCode=redeemScripts[i],
                                           amount=amount)
        tx = bitcoin.apply_p2wsh_multisignatures(tx, i, redeemScripts[i], sigs)
    txid = jm_single().bc_interface.pushtx(tx)
    assert txid
示例#5
0
def test_spend_p2wpkh(setup_tx_creation):
    #make 3 p2wpkh outputs from 3 privs
    privs = [struct.pack(b'B', x) * 32 + b'\x01' for x in range(1, 4)]
    pubs = [
        bitcoin.privkey_to_pubkey(binascii.hexlify(priv).decode('ascii'))
        for priv in privs
    ]
    scriptPubKeys = [bitcoin.pubkey_to_p2wpkh_script(pub) for pub in pubs]
    addresses = [bitcoin.pubkey_to_p2wpkh_address(pub) for pub in pubs]
    #pay into it
    wallet_service = make_wallets(1, [[3, 0, 0, 0, 0]], 3)[0]['wallet']
    wallet_service.sync_wallet(fast=True)
    amount = 35000000
    p2wpkh_ins = []
    for addr in addresses:
        ins_full = wallet_service.select_utxos(0, amount)
        txid = make_sign_and_push(ins_full,
                                  wallet_service,
                                  amount,
                                  output_addr=addr)
        assert txid
        p2wpkh_ins.append(txid + ":0")
        #wait for mining
        time.sleep(1)
    #random output address
    output_addr = wallet_service.get_internal_addr(1)
    amount2 = amount * 3 - 50000
    outs = [{'value': amount2, 'address': output_addr}]
    tx = bitcoin.mktx(p2wpkh_ins, outs)
    sigs = []
    for i, priv in enumerate(privs):
        # sign each of 3 inputs
        tx = bitcoin.p2wpkh_sign(tx,
                                 i,
                                 binascii.hexlify(priv),
                                 amount,
                                 native=True)
        # check that verify_tx_input correctly validates;
        # to do this, we need to extract the signature and get the scriptCode
        # of this pubkey
        scriptCode = bitcoin.pubkey_to_p2pkh_script(pubs[i])
        witness = bitcoin.deserialize(tx)['ins'][i]['txinwitness']
        assert len(witness) == 2
        assert witness[1] == pubs[i]
        sig = witness[0]
        assert bitcoin.verify_tx_input(tx,
                                       i,
                                       scriptPubKeys[i],
                                       sig,
                                       pubs[i],
                                       scriptCode=scriptCode,
                                       amount=amount)
    txid = jm_single().bc_interface.pushtx(tx)
    assert txid
示例#6
0
def do_tx(wallet, amount):
    ins_full = wallet.select_utxos(0, amount)
    cj_addr = wallet.get_internal_addr(1)
    change_addr = wallet.get_internal_addr(0)
    wallet.update_cache_index()
    txid = make_sign_and_push(ins_full, wallet, amount,
                              output_addr=cj_addr,
                              change_addr=change_addr,
                              estimate_fee=True)
    assert txid
    time.sleep(2) #blocks
    jm_single().bc_interface.sync_unspent(wallet)
示例#7
0
def test_absurd_fees(setup_tx_creation):
    """Test triggering of ValueError exception
    if the transaction fees calculated from the blockchain
    interface exceed the limit set in the config.
    """
    jm_single().bc_interface.absurd_fees = True
    #pay into it
    wallet = make_wallets(1, [[2, 0, 0, 0, 1]], 3)[0]['wallet']
    jm_single().bc_interface.sync_wallet(wallet)
    amount = 350000000
    ins_full = wallet.select_utxos(0, amount)
    with pytest.raises(ValueError) as e_info:
        txid = make_sign_and_push(ins_full, wallet, amount, estimate_fee=True)
示例#8
0
def do_tx(wallet, amount):
    ins_full = wallet.select_utxos(0, amount)
    cj_addr = wallet.get_internal_addr(1)
    change_addr = wallet.get_internal_addr(0)
    wallet.update_cache_index()
    txid = make_sign_and_push(ins_full,
                              wallet,
                              amount,
                              output_addr=cj_addr,
                              change_addr=change_addr,
                              estimate_fee=True)
    assert txid
    time.sleep(2)  #blocks
    jm_single().bc_interface.sync_unspent(wallet)
def test_create_sighash_txs(setup_tx_creation):
    #non-standard hash codes:
    for sighash in [bitcoin.SIGHASH_ANYONECANPAY + bitcoin.SIGHASH_SINGLE,
                    bitcoin.SIGHASH_NONE, bitcoin.SIGHASH_SINGLE]:
        wallet_service = make_wallets(1, [[2, 0, 0, 0, 1]], 3)[0]['wallet']
        wallet_service.sync_wallet(fast=True)
        amount = 350000000
        ins_full = wallet_service.select_utxos(0, amount)
        txid = make_sign_and_push(ins_full, wallet_service, amount, hashcode=sighash)
        assert txid

    #trigger insufficient funds
    with pytest.raises(Exception) as e_info:
        fake_utxos = wallet_service.select_utxos(4, 1000000000)
示例#10
0
def do_tx(wallet_service, amount):
    ins_full = wallet_service.select_utxos(0, amount)
    cj_addr = wallet_service.get_internal_addr(1)
    change_addr = wallet_service.get_internal_addr(0)
    wallet_service.save_wallet()
    txid = make_sign_and_push(ins_full,
                              wallet_service,
                              amount,
                              output_addr=cj_addr,
                              change_addr=change_addr,
                              estimate_fee=True)
    assert txid
    time.sleep(2)  #blocks
    wallet_service.sync_unspent()
    return txid
示例#11
0
def test_create_sighash_txs(setup_tx_creation):
    #non-standard hash codes:
    for sighash in [btc.SIGHASH_ANYONECANPAY + btc.SIGHASH_SINGLE,
                    btc.SIGHASH_NONE, btc.SIGHASH_SINGLE]:
        wallet = make_wallets(1, [[2, 0, 0, 0, 1]], 3)[0]['wallet']
        jm_single().bc_interface.sync_wallet(wallet)
        amount = 350000000
        ins_full = wallet.select_utxos(0, amount)
        print "using hashcode: " + str(sighash)
        txid = make_sign_and_push(ins_full, wallet, amount, hashcode=sighash)
        assert txid

    #Create an invalid sighash single (too many inputs)
    extra = wallet.select_utxos(4, 100000000)  #just a few more inputs
    ins_full.update(extra)
    with pytest.raises(Exception) as e_info:
        txid = make_sign_and_push(ins_full,
                                  wallet,
                                  amount,
                                  hashcode=btc.SIGHASH_SINGLE)

    #trigger insufficient funds
    with pytest.raises(Exception) as e_info:
        fake_utxos = wallet.select_utxos(4, 1000000000)
def test_create_p2sh_output_tx(setup_tx_creation, nw, wallet_structures,
                               mean_amt, sdev_amt, amount, pubs, k):
    wallets = make_wallets(nw, wallet_structures, mean_amt, sdev_amt)
    for w in wallets.values():
        sync_wallet(w['wallet'], fast=True)
    for k, w in enumerate(wallets.values()):
        wallet = w['wallet']
        ins_full = wallet.select_utxos(0, amount)
        script = bitcoin.mk_multisig_script(pubs, k)
        output_addr = bitcoin.script_to_address(script, vbyte=196)
        txid = make_sign_and_push(ins_full,
                                  wallet,
                                  amount,
                                  output_addr=output_addr)
        assert txid
示例#13
0
def test_create_p2sh_output_tx(setup_tx_creation, nw, wallet_structures,
                               mean_amt, sdev_amt, amount, pubs, k):
    wallets = make_wallets(nw, wallet_structures, mean_amt, sdev_amt)
    for w in wallets.values():
        w['wallet'].sync_wallet(fast=True)
    for k, w in enumerate(wallets.values()):
        wallet_service = w['wallet']
        ins_full = wallet_service.select_utxos(0, amount)
        script = bitcoin.mk_multisig_script(pubs, k)
        output_addr = bitcoin.p2sh_scriptaddr(bitcoin.safe_from_hex(script),
                                              magicbyte=196)
        txid = make_sign_and_push(ins_full,
                                  wallet_service,
                                  amount,
                                  output_addr=output_addr)
        assert txid
示例#14
0
def test_spend_freeze_script(setup_tx_creation):
    ensure_bip65_activated()

    wallet_service = make_wallets(1, [[3, 0, 0, 0, 0]], 3)[0]['wallet']
    wallet_service.sync_wallet(fast=True)

    mediantime = jm_single().bc_interface.rpc("getblockchaininfo",
                                              [])["mediantime"]

    timeoffset_success_tests = [(2, False), (-60 * 60 * 24 * 30, True),
                                (60 * 60 * 24 * 30, False)]

    for timeoffset, required_success in timeoffset_success_tests:
        #generate keypair
        priv = b"\xaa" * 32 + b"\x01"
        pub = bitcoin.privkey_to_pubkey(priv)
        addr_locktime = mediantime + timeoffset
        redeem_script = bitcoin.mk_freeze_script(pub, addr_locktime)
        script_pub_key = bitcoin.redeem_script_to_p2wsh_script(redeem_script)
        # cannot convert to address within wallet service, as not known
        # to wallet; use engine directly:
        addr = wallet_service._ENGINE.script_to_address(script_pub_key)

        #fund frozen funds address
        amount = 100000000
        funding_ins_full = wallet_service.select_utxos(0, amount)
        funding_txid = make_sign_and_push(funding_ins_full,
                                          wallet_service,
                                          amount,
                                          output_addr=addr)
        assert funding_txid

        #spend frozen funds
        frozen_in = (funding_txid, 0)
        output_addr = wallet_service.get_internal_addr(1)
        miner_fee = 5000
        outs = [{'value': amount - miner_fee, 'address': output_addr}]
        tx = bitcoin.mktx([frozen_in], outs, locktime=addr_locktime + 1)
        i = 0
        sig, success = bitcoin.sign(tx,
                                    i,
                                    priv,
                                    amount=amount,
                                    native=redeem_script)
        assert success
        push_success = jm_single().bc_interface.pushtx(tx.serialize())
        assert push_success == required_success
示例#15
0
def test_create_p2sh_output_tx(setup_tx_creation, nw, wallet_structures,
                               mean_amt, sdev_amt, amount, pubs, k):
    wallets = make_wallets(nw, wallet_structures, mean_amt, sdev_amt)
    for w in wallets.values():
        jm_single().bc_interface.sync_wallet(w['wallet'])
    for k, w in enumerate(wallets.values()):
        wallet = w['wallet']
        ins_full = wallet.select_utxos(0, amount)
        script = btc.mk_multisig_script(pubs, k)
        #try the alternative argument passing
        pubs.append(k)
        script2 = btc.mk_multisig_script(*pubs)
        assert script2 == script
        output_addr = btc.scriptaddr(script, magicbyte=196)
        txid = make_sign_and_push(ins_full,
                                  wallet,
                                  amount,
                                  output_addr=output_addr)
        assert txid
示例#16
0
def test_spend_freeze_script(setup_tx_creation):
    ensure_bip65_activated()

    wallet_service = make_wallets(1, [[3, 0, 0, 0, 0]], 3)[0]['wallet']
    wallet_service.sync_wallet(fast=True)

    mediantime = jm_single().bc_interface.rpc("getblockchaininfo", [])["mediantime"]

    timeoffset_success_tests = [(2, False), (-60*60*24*30, True), (60*60*24*30, False)]

    for timeoffset, required_success in timeoffset_success_tests:
        #generate keypair
        priv = "aa"*32 + "01"
        pub = unhexlify(bitcoin.privkey_to_pubkey(priv))
        addr_locktime = mediantime + timeoffset
        redeem_script = bitcoin.mk_freeze_script(pub, addr_locktime)
        script_pub_key = bitcoin.redeem_script_to_p2wsh_script(redeem_script)
        regtest_vbyte = 100
        addr = bitcoin.script_to_address(script_pub_key, vbyte=regtest_vbyte)

        #fund frozen funds address
        amount = 100000000
        funding_ins_full = wallet_service.select_utxos(0, amount)
        funding_txid = make_sign_and_push(funding_ins_full, wallet_service, amount, output_addr=addr)
        assert funding_txid

        #spend frozen funds
        frozen_in = funding_txid + ":0"
        output_addr = wallet_service.get_internal_addr(1)
        miner_fee = 5000
        outs = [{'value': amount - miner_fee, 'address': output_addr}]
        tx = bitcoin.mktx([frozen_in], outs, locktime=addr_locktime+1)
        i = 0
        sig = bitcoin.get_p2sh_signature(tx, i, redeem_script, priv, amount)

        assert bitcoin.verify_tx_input(tx, i, script_pub_key, sig, pub,
            scriptCode=redeem_script, amount=amount)
        tx = bitcoin.apply_freeze_signature(tx, i, redeem_script, sig)
        push_success = jm_single().bc_interface.pushtx(tx)

        assert push_success == required_success