Пример #1
0
    def test_wif(self):
        """WIF keys"""
        select_params('mainnet')
        # https://en.bitcoin.it/wiki/Wallet_import_format
        prv = h2b('0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d')
        # note that '(un)compressed' refers to the correspoding pubkey, not the
        # wif format, which suggests the opposite
        expected_wif_uncompressed = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
        expected_wif_compressed = 'KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617'

        privkey = PrivateKey(prv)

        wif_uncompressed = privkey.to_wif(is_compressed=False)
        self.assertFalse(wif_is_compressed(wif_uncompressed))
        self.assertEqual(wif_uncompressed, expected_wif_uncompressed)
        self.assertRaises(InvalidWIFKey, privkey.from_wif, wif_uncompressed, is_compressed=True)
        prv_from_wif = privkey.from_wif(wif_uncompressed, is_compressed=False).prv
        self.assertEqual(prv_from_wif, prv)

        wif_compressed = privkey.to_wif(is_compressed=True)
        self.assertTrue(wif_is_compressed(wif_compressed))
        self.assertEqual(wif_compressed, expected_wif_compressed)
        self.assertRaises(InvalidWIFKey, privkey.from_wif, wif_compressed, is_compressed=False)
        prv_from_wif = privkey.from_wif(wif_compressed, is_compressed=True).prv
        self.assertEqual(prv_from_wif, prv)

        self.assertRaises(InvalidWIFKey, wif_is_compressed, '')
        select_params('testnet')
Пример #2
0
    def test_from_mnemonic(self):
        """Xprv from mnemonic"""
        select_params('mainnet')
        # https://github.com/trezor/python-mnemonic/blob/master/vectors.json
        mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
        passphrase = 'TREZOR'
        m = 'xprv9s21ZrQH143K3h3fDYiay8mocZ3afhfULfb5GX8kCBdno77K4HiA15Tg23wpbeF1pLfs1c5SPmYHrEpTuuRhxMwvKDwqdKiGJS9XFKzUsAF'

        xprv = Xprv.from_mnemonic(mnemonic, passphrase)
        self.assertEqual(xprv.to_b58(), m)
        select_params('testnet')
Пример #3
0
    def test_e2e_p2sh_p2wpkh(self):
        """Simulated End-To-End P2SH-P2WPKH spending"""

        select_params('regtest')
        # keys
        prv = b'\x00' * 31 + b'\x01'
        privkey = PrivateKey(prv)
        pubkey = privkey.pubkey()

        # address
        output = P2SHP2WPKH(pubkey)
        self.assertEqual(output.address(),
                         '2NAUYAHhujozruyzpsFRP63mbrdaU5wnEpN')

        # obtain utxo data from node (these were obtained from a regtest)
        txid = h2b_rev(
            'b25cce9848fa30123e253759b7e667efb6c093d520ef8957b0bafa7e12d62485')
        vout = 0
        height = 150
        amount = 100000000
        scriptpubkey = h2b('a914bcfeb728b584253d5f3f70bcb780e9ef218a68f487')

        self.assertEqual(scriptpubkey, output.scriptpubkey())
        utxo = Utxo(txid, vout, height, amount, scriptpubkey)
        self.assertEqual(output.address(), utxo.address())

        # create the signer
        signer = SignerP2SHP2WPKH(PrivateKey(prv), amount)
        self.assertEqual(signer.address(), output.address())
        self.assertEqual(signer.scriptpubkey(), scriptpubkey)
        self.assertEqual(signer.address(), utxo.address())

        # create a transaction spending utxo to the same address
        fee = 1000
        amount_send = amount - fee
        scriptpubkey_send = signer.scriptpubkey()

        tx = Transaction()
        tx.add_input(utxo.txid, utxo.vout, 0xffffffff)
        tx.add_output(scriptpubkey_send, amount_send)
        expected_unsigned_tx = \
            '02000000018524d6127efabab05789ef20d593c0b6ef67e6b75937253e1230fa4898ce5cb20000000000ffffffff0118ddf5050000000017a914bcfeb72' \
            '8b584253d5f3f70bcb780e9ef218a68f48700000000'
        self.assertEqual(expected_unsigned_tx, tx.to_hex())

        # sign transaction
        tx.sign(0, signer)
        expected_signed_tx = \
            '020000000001018524d6127efabab05789ef20d593c0b6ef67e6b75937253e1230fa4898ce5cb20000000017160014751e76e8199196d454941c45d1b3a' \
            '323f1433bd6ffffffff0118ddf5050000000017a914bcfeb728b584253d5f3f70bcb780e9ef218a68f4870247304402201ddc9c9b627e5da2bd81228751' \
            '34f46dff2713d5d310850f468f6b98ead3ee2902206b2ea4e50d17c803eb0b6edb79de8b4a0e1c0c1a5c4f9feabefe2ab9b6dfd26401210279be667ef9d' \
            'cbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000'
        self.assertEqual(expected_signed_tx, tx.to_hex(use_witness=True))
        select_params('testnet')
Пример #4
0
    def test_e2e_p2wpkh(self):
        """Simulated End-To-End P2WPKH spending"""

        select_params('regtest')
        # keys
        prv = b'\x00' * 31 + b'\x01'
        privkey = PrivateKey(prv)
        pubkey = privkey.pubkey()

        # address
        output = P2WPKH(pubkey)
        self.assertEqual(output.address(),
                         'bcrt1qw508d6qejxtdg4y5r3zarvary0c5xw7kygt080')

        # obtain utxo data from node (these were obtained from a regtest)
        txid = h2b_rev(
            '3bceceb578aa8134a7e687e75e1aadaac68e8e3f9a2b9e11bff2637eb22cc0ee')
        vout = 1
        height = 150
        amount = 100000000
        scriptpubkey = h2b('0014751e76e8199196d454941c45d1b3a323f1433bd6')

        self.assertEqual(scriptpubkey, output.scriptpubkey())
        utxo = Utxo(txid, vout, height, amount, scriptpubkey)
        self.assertEqual(output.address(), utxo.address())

        # create the signer
        signer = SignerP2WPKH(PrivateKey(prv), amount)
        self.assertEqual(signer.address(), output.address())
        self.assertEqual(signer.scriptpubkey(), scriptpubkey)
        self.assertEqual(signer.address(), utxo.address())

        # create a transaction spending utxo to the same address
        fee = 1000
        amount_send = amount - fee
        scriptpubkey_send = signer.scriptpubkey()

        tx = Transaction()
        tx.add_input(utxo.txid, utxo.vout, 0xffffffff)
        tx.add_output(scriptpubkey_send, amount_send)
        expected_unsigned_tx = \
            '0200000001eec02cb27e63f2bf119e2b9a3f8e8ec6aaad1a5ee787e6a73481aa78b5cece3b0100000000ffffffff0118ddf50500000000160014751e76e' \
            '8199196d454941c45d1b3a323f1433bd600000000'
        self.assertEqual(expected_unsigned_tx, tx.to_hex())

        # sign transaction
        tx.sign(0, signer)
        expected_signed_tx = \
            '02000000000101eec02cb27e63f2bf119e2b9a3f8e8ec6aaad1a5ee787e6a73481aa78b5cece3b0100000000ffffffff0118ddf50500000000160014751' \
            'e76e8199196d454941c45d1b3a323f1433bd60247304402200c83fde88be21526dd3504cbc091e39a8e20c61f8c8660e9aa4b164c68c7f6d002207e6376' \
            '51e95eba9efcddc9419bc80815cf188a3800cea12e4cdc14bb8139158801210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f' \
            '8179800000000'
        self.assertEqual(expected_signed_tx, tx.to_hex(use_witness=True))
        select_params('testnet')
Пример #5
0
    def test_bip32(self):
        """BIP32 test vector"""
        select_params('mainnet')
        # https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#test-vector-1
        seed = h2b('000102030405060708090a0b0c0d0e0f')
        M = 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8'
        m = 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi'
        M_0H = 'xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw'
        m_0H = 'xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7'
        M_0H_1 = 'xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ'
        m_0H_1 = 'xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs'

        xprv = Xprv.from_seed(seed)
        self.assertEqual(xprv.to_b58(), m)

        xprv = Xprv.from_b58(m)
        xpub = Xpub.from_b58(M)

        self.assertEqual(xprv.to_b58(), m)
        self.assertEqual(xpub.to_b58(), M)

        # byte serialization
        self.assertEqual(Xprv.from_bytes(xprv.to_bytes()).to_b58(), m)
        self.assertEqual(Xpub.from_bytes(xpub.to_bytes()).to_b58(), M)

        # hardened derivation
        path = [harden(0)]
        xprv_0H = xprv.derive(path)
        self.assertRaises(InvalidBip32Path, xpub.derive, path)
        xpub_0H = xprv_0H.to_xpub()

        # note: test vector match only if hash computation is not skipped
        self.assertEqual(xprv_0H.to_b58(), m_0H)
        self.assertEqual(xpub_0H.to_b58(), M_0H)

        # non-hardened derivation
        path = [1]
        xprv_0H_1 = xprv_0H.derive(path)
        xpub_0H_1 = xpub_0H.derive(path)

        self.assertEqual(xprv_0H_1.to_b58(), m_0H_1)
        self.assertEqual(xpub_0H_1.to_b58(), M_0H_1)

        # mixed derivation
        path = [harden(0), 1]
        xprv_0H_1_mixed = xprv.derive(path)
        self.assertRaises(InvalidBip32Path, xpub.derive, path)

        self.assertEqual(xprv_0H_1.to_b58(), m_0H_1)
        select_params('testnet')
Пример #6
0
    def test_utxo(self):
        """Common UTXO types"""
        select_params('mainnet')
        # https://blockstream.info/tx/f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16
        # P2PK
        txid = h2b_rev('f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16')
        vout = 0
        height = 170
        amount = 1000000000
        scriptpubkey = h2b('4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414'
                           'e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac')

        utxo = Utxo(txid, vout, height, amount, scriptpubkey)
        # No address for P2PKH
        self.assertRaises(UnknownAddressForScriptpubkey, utxo.address)

        # https://blockstream.info/tx/6f7cf9580f1c2dfb3c4d5d043cdbb128c640e3f20161245aa7372e9666168516
        # P2PKH
        txid = h2b_rev('6f7cf9580f1c2dfb3c4d5d043cdbb128c640e3f20161245aa7372e9666168516')
        vout = 0
        height = 728
        amount = 10000000000
        scriptpubkey = h2b('76a91412ab8dc588ca9d5787dde7eb29569da63c3a238c88ac')
        expected_address = '12higDjoCCNXSA95xZMWUdPvXNmkAduhWv'

        utxo = Utxo(txid, vout, height, amount, scriptpubkey)
        self.assertEqual(utxo.address(), expected_address)

        # https://blockstream.info/tx/40eee3ae1760e3a8532263678cdf64569e6ad06abc133af64f735e52562bccc8
        # P2SH
        txid = h2b_rev('40eee3ae1760e3a8532263678cdf64569e6ad06abc133af64f735e52562bccc8')
        vout = 0
        height = 272295
        amount = 990000
        scriptpubkey = h2b('a914e9c3dd0c07aac76179ebc76a6c78d4d67c6c160a87')
        expected_address = '3P14159f73E4gFr7JterCCQh9QjiTjiZrG'

        utxo = Utxo(txid, vout, height, amount, scriptpubkey)
        self.assertEqual(utxo.address(), expected_address)
        select_params('testnet')
Пример #7
0
#!/usr/bin/env python3

import os

from pywally import select_params
from pywally.key import PrivateKey
from pywally.util import b2h

# Generate a random keypair

select_params('testnet')

prv = os.urandom(32)
privkey = PrivateKey(prv)
pubkey = privkey.pubkey()

print('Private key')
print(' HEX: {}'.format(b2h(prv)))
print(' WIF: {}'.format(privkey.to_wif()))

print('Public key')
print(' HEX: {}'.format(b2h(pubkey.pub)))
Пример #8
0
    def test_e2e_mixed(self):
        """Simulated End-To-End mixed spending"""

        select_params('regtest')
        # keys
        threshold = 2
        prv1 = b'\x00' * 31 + b'\x01'
        prv2 = b'\x00' * 31 + b'\x02'
        prv3 = b'\x00' * 31 + b'\x03'

        all_privkeys = [PrivateKey(prv) for prv in [prv1, prv2, prv3]]
        pubkeys = [privkey.pubkey() for privkey in all_privkeys]

        # signlesig
        output = P2PKH(pubkeys[0])
        self.assertEqual(output.address(),
                         'mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r')

        txid = h2b_rev(
            '57227d04c12267c96efa316b81c0f66b96b254760bc055a8479d411fbbf78ef7')
        vout = 2
        height = 150
        amount_ss = 100000000
        scriptpubkey = h2b(
            '76a914751e76e8199196d454941c45d1b3a323f1433bd688ac')

        self.assertEqual(scriptpubkey, output.scriptpubkey())
        utxo_ss = Utxo(txid, vout, height, amount_ss, scriptpubkey)

        signer_ss = SignerP2PKH(all_privkeys[0])

        # multisig
        output = P2WSHMultisig(threshold, pubkeys)
        self.assertEqual(
            output.address(),
            'bcrt1qztp0l0rwc8846ardl02fkyrrx43p96j47scz8l7qz3vnfteqc4eq3cu8hw')

        # obtain utxo data from node (these were obtained from a regtest)
        txid = h2b_rev(
            '57227d04c12267c96efa316b81c0f66b96b254760bc055a8479d411fbbf78ef7')
        vout = 0
        height = 150
        amount_ms = 100000000
        scriptpubkey = h2b(
            '002012c2ffbc6ec1cf5d746dfbd49b1063356212ea55f43023ffc0145934af20c572'
        )

        self.assertEqual(output.scriptpubkey(), scriptpubkey)
        utxo_ms = Utxo(txid, vout, height, amount_ms, scriptpubkey)

        keys = all_privkeys[:2] + pubkeys[2:]
        signer_ms = SignerP2WSHMultisig(threshold, keys, amount_ms)

        # create a transaction spending both utxos to the same single sig address
        fee = 1000
        amount_send = amount_ss + amount_ms - fee
        scriptpubkey_send = signer_ss.scriptpubkey()

        tx = Transaction()
        tx.add_input(utxo_ss.txid, utxo_ss.vout, 0xffffffff)
        tx.add_input(utxo_ms.txid, utxo_ms.vout, 0xffffffff)
        tx.add_output(scriptpubkey_send, amount_send)
        expected_unsigned_tx = \
            '0200000002f78ef7bb1f419d47a855c00b7654b2966bf6c0816b31fa6ec96722c1047d22570200000000fffffffff78ef7bb1f419d47a855c00b7654b29' \
            '66bf6c0816b31fa6ec96722c1047d22570000000000ffffffff0118beeb0b000000001976a914751e76e8199196d454941c45d1b3a323f1433bd688ac00' \
            '000000'
        self.assertEqual(expected_unsigned_tx, tx.to_hex())

        # sign transaction
        tx.sign(0, signer_ss)
        tx.sign(1, signer_ms)
        expected_signed_tx = \
            '02000000000102f78ef7bb1f419d47a855c00b7654b2966bf6c0816b31fa6ec96722c1047d2257020000006a47304402200cc337a7eed7c209080683e2b' \
            '053d49254d80bd83dce2001d3f278a5247c8242022048f69a73b78f4033c30faafd7fe797cd1c85c1b3faf440786683241685d0f7ac01210279be667ef9' \
            'dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798fffffffff78ef7bb1f419d47a855c00b7654b2966bf6c0816b31fa6ec96722c1047d2' \
            '2570000000000ffffffff0118beeb0b000000001976a914751e76e8199196d454941c45d1b3a323f1433bd688ac00040047304402205cc5744b6dd00584' \
            '1012f6a800b02decbc16730196cd542ae6c0309d3756aace02207c1fced19ec704088342dcce2bdaf7c2c1f88268c3b1da7e7ce6ccc6d31181f10147304' \
            '4022026c9c4f5ead32262f01f033b3887b59fed8ddded912bb3e7f329d3076f3aedc8022013300fe03a62081857b6d0ab3eab3691e21b53ff36fee145ae' \
            '54128284b56b64016952210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c6047f9441ed7d6d3045406e95c07cd' \
            '85c778e4b8cef3ca7abac09b95c709ee52102f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f953ae00000000'
        self.assertEqual(expected_signed_tx, tx.to_hex(use_witness=True))
        select_params('testnet')
Пример #9
0
    def test_e2e_p2shp2wsh_multisig(self):
        """Simulated End-To-End P2SH-P2WSH-multisig-2of3 spending"""

        select_params('regtest')
        # keys
        threshold = 2
        prv1 = b'\x00' * 31 + b'\x01'
        prv2 = b'\x00' * 31 + b'\x02'
        prv3 = b'\x00' * 31 + b'\x03'

        all_privkeys = [PrivateKey(prv) for prv in [prv1, prv2, prv3]]
        pubkeys = [privkey.pubkey() for privkey in all_privkeys]

        # address
        output = P2SHP2WSHMultisig(threshold, pubkeys)
        self.assertEqual(output.address(),
                         '2NBbyaKyqn2AhMzSnQZrVPAW46KW1it9v7r')

        # obtain utxo data from node (these were obtained from a regtest)
        txid = h2b_rev(
            'cc8c5def8f258a7054e606ba53b20244c412632528c742db42b3f70de11914e3')
        vout = 0
        height = 150
        amount = 100000000
        scriptpubkey = h2b('a914c95ef7c9117a56571c2ddc44e5fd8ba29d45989387')

        self.assertEqual(output.scriptpubkey(), scriptpubkey)
        utxo = Utxo(txid, vout, height, amount, scriptpubkey)
        self.assertEqual(output.address(), utxo.address())

        # create the signer
        keys = all_privkeys[:2] + pubkeys[2:]
        signer = SignerP2SHP2WSHMultisig(threshold, keys, amount)
        self.assertEqual(signer.address(), output.address())
        self.assertEqual(signer.scriptpubkey(), scriptpubkey)
        self.assertEqual(signer.address(), utxo.address())

        # create a transaction spending utxo to the same address
        fee = 1000
        amount_send = amount - fee
        scriptpubkey_send = signer.scriptpubkey()

        tx = Transaction()
        tx.add_input(utxo.txid, utxo.vout, 0xffffffff)
        tx.add_output(scriptpubkey_send, amount_send)
        expected_unsigned_tx = \
            '0200000001e31419e10df7b342db42c728256312c44402b253ba06e654708a258fef5d8ccc0000000000ffffffff0118ddf5050000000017a914c95ef7c' \
            '9117a56571c2ddc44e5fd8ba29d4598938700000000'
        self.assertEqual(expected_unsigned_tx, tx.to_hex())

        # sign transaction
        tx.sign(0, signer)
        expected_signed_tx = \
            '02000000000101e31419e10df7b342db42c728256312c44402b253ba06e654708a258fef5d8ccc000000002322002012c2ffbc6ec1cf5d746dfbd49b106' \
            '3356212ea55f43023ffc0145934af20c572ffffffff0118ddf5050000000017a914c95ef7c9117a56571c2ddc44e5fd8ba29d4598938704004730440220' \
            '5cb17ae6db374ed3df9b14829139f04bc6cd9e4ea06e3acb1e1329f15f19e75502207fd2c1a08b0f28c34b60fb8abee231553c2e98d4c5fab56557ad9f9' \
            '6a86a45b20147304402206e8c36b552ede9facc292ce626eb4d0857707f36b93e23f6bf39503feb50eae00220245fb8990277f64e1ecfad6467925b6c5d' \
            '79783e5786b7bd45191ffb11bf824e016952210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c6047f9441ed7d6' \
            'd3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee52102f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f953ae00' \
            '000000'
        self.assertEqual(expected_signed_tx, tx.to_hex(use_witness=True))

        # other set of signers can sign too (eg 1st and 3rd)
        keys = all_privkeys[:1] + pubkeys[1:2] + all_privkeys[-1:]
        signer_1_3 = SignerP2SHP2WSHMultisig(threshold, keys, amount)
        # override signature
        tx.sign(0, signer_1_3)
        expected_signed_tx_1_3 = \
            '02000000000101e31419e10df7b342db42c728256312c44402b253ba06e654708a258fef5d8ccc000000002322002012c2ffbc6ec1cf5d746dfbd49b106' \
            '3356212ea55f43023ffc0145934af20c572ffffffff0118ddf5050000000017a914c95ef7c9117a56571c2ddc44e5fd8ba29d4598938704004730440220' \
            '5cb17ae6db374ed3df9b14829139f04bc6cd9e4ea06e3acb1e1329f15f19e75502207fd2c1a08b0f28c34b60fb8abee231553c2e98d4c5fab56557ad9f9' \
            '6a86a45b20147304402205ee619c2a08e7b963802bd8bcc8d9ca5a9750e469bf9501650f4be7cb753981a022029ee7dda9e4fb2f14dee62740d1e784a52' \
            '79bf513410fe5eef56abc4bfbbd392016952210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c6047f9441ed7d6' \
            'd3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee52102f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f953ae00' \
            '000000'
        self.assertEqual(expected_signed_tx_1_3, tx.to_hex(use_witness=True))
        select_params('testnet')
Пример #10
0
    def test_e2e_p2wsh_multisig(self):
        """Simulated End-To-End P2WSH-multisig-2of3 spending"""

        select_params('regtest')
        # keys
        threshold = 2
        prv1 = b'\x00' * 31 + b'\x01'
        prv2 = b'\x00' * 31 + b'\x02'
        prv3 = b'\x00' * 31 + b'\x03'

        all_privkeys = [PrivateKey(prv) for prv in [prv1, prv2, prv3]]
        pubkeys = [privkey.pubkey() for privkey in all_privkeys]

        # address
        output = P2WSHMultisig(threshold, pubkeys)
        self.assertEqual(
            output.address(),
            'bcrt1qztp0l0rwc8846ardl02fkyrrx43p96j47scz8l7qz3vnfteqc4eq3cu8hw')

        # obtain utxo data from node (these were obtained from a regtest)
        txid = h2b_rev(
            '3367a61a77802774c76afcdb5e220013a541cc55fb82f3903ef7a077b718682b')
        vout = 1
        height = 150
        amount = 100000000
        scriptpubkey = h2b(
            '002012c2ffbc6ec1cf5d746dfbd49b1063356212ea55f43023ffc0145934af20c572'
        )

        self.assertEqual(output.scriptpubkey(), scriptpubkey)
        utxo = Utxo(txid, vout, height, amount, scriptpubkey)
        self.assertEqual(output.address(), utxo.address())

        # create the signer
        keys = all_privkeys[:2] + pubkeys[2:]
        signer = SignerP2WSHMultisig(threshold, keys, amount)
        self.assertEqual(signer.address(), output.address())
        self.assertEqual(signer.scriptpubkey(), scriptpubkey)
        self.assertEqual(signer.address(), utxo.address())

        # create a transaction spending utxo to the same address
        fee = 1000
        amount_send = amount - fee
        scriptpubkey_send = signer.scriptpubkey()

        tx = Transaction()
        tx.add_input(utxo.txid, utxo.vout, 0xffffffff)
        tx.add_output(scriptpubkey_send, amount_send)
        expected_unsigned_tx = \
            '02000000012b6818b777a0f73e90f382fb55cc41a51300225edbfc6ac7742780771aa667330100000000ffffffff0118ddf5050000000022002012c2ffb' \
            'c6ec1cf5d746dfbd49b1063356212ea55f43023ffc0145934af20c57200000000'
        self.assertEqual(expected_unsigned_tx, tx.to_hex())

        # sign transaction
        tx.sign(0, signer)
        expected_signed_tx = \
            '020000000001012b6818b777a0f73e90f382fb55cc41a51300225edbfc6ac7742780771aa667330100000000ffffffff0118ddf5050000000022002012c' \
            '2ffbc6ec1cf5d746dfbd49b1063356212ea55f43023ffc0145934af20c57204004730440220469b44477440b64a49500eb263ebdacd6532a2a802efc151' \
            'b3fe1319d705bf88022010fb1ade40a9f9ad868914a92f890b2e9efd2401a06245d239d1c4a6a7d2c2ac0147304402204b5372642f89dbe6ea90ec48e99' \
            '60a261420af6c474158ae380f2b7ad73797e00220204e3fa572f6a72bd7ce78509c51ba5ace2637644ee079651d6dc5ff9752abc1016952210279be667e' \
            'f9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee' \
            '52102f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f953ae00000000'
        self.assertEqual(expected_signed_tx, tx.to_hex(use_witness=True))

        # other set of signers can sign too (eg 1st and 3rd)
        keys = all_privkeys[:1] + pubkeys[1:2] + all_privkeys[-1:]
        signer_1_3 = SignerP2WSHMultisig(threshold, keys, amount)
        # override signature
        tx.sign(0, signer_1_3)
        expected_signed_tx_1_3 = \
            '020000000001012b6818b777a0f73e90f382fb55cc41a51300225edbfc6ac7742780771aa667330100000000ffffffff0118ddf5050000000022002012c' \
            '2ffbc6ec1cf5d746dfbd49b1063356212ea55f43023ffc0145934af20c57204004730440220469b44477440b64a49500eb263ebdacd6532a2a802efc151' \
            'b3fe1319d705bf88022010fb1ade40a9f9ad868914a92f890b2e9efd2401a06245d239d1c4a6a7d2c2ac01473044022041b9e84820750e9765b5e7a203f' \
            '558f757a9f5ba8b79a1f66141f870316a0fe1022035d7f443daaf6a2729bf714719b1b0bcb63980d231c4e5a4ed0fd956cfb92747016952210279be667e' \
            'f9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee' \
            '52102f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f953ae00000000'
        self.assertEqual(expected_signed_tx_1_3, tx.to_hex(use_witness=True))
        select_params('testnet')