def test_show_multisig_3(self):
     self.setup_mnemonic_allallall()
     nodes = map(
         lambda index: btc.get_public_node(
             self.client, parse_path("999'/1'/%d'" % index)
         ),
         range(1, 4),
     )
     multisig1 = proto.MultisigRedeemScriptType(
         nodes=[bip32.deserialize(n.xpub) for n in nodes],
         address_n=[2, 0],
         signatures=[b"", b"", b""],
         m=2,
     )
     # multisig2 = proto.MultisigRedeemScriptType(
     #     pubkeys=map(lambda n: proto.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 1]), nodes),
     #     signatures=[b'', b'', b''],
     #     m=2,
     # )
     for i in [1, 2, 3]:
         assert (
             btc.get_address(
                 self.client,
                 "Testnet",
                 parse_path("999'/1'/%d'/2/0" % i),
                 False,
                 multisig1,
                 script_type=proto.InputScriptType.SPENDP2SHWITNESS,
             )
             == "2N2MxyAfifVhb3AMagisxaj3uij8bfXqf4Y"
         )
    def test_multisig(self):
        self.setup_mnemonic_allallall()
        xpubs = []
        for n in range(1, 4):
            node = btc.get_public_node(self.client, parse_path("44'/0'/%d'" % n))
            xpubs.append(node.xpub)

        for nr in range(1, 4):
            assert (
                btc.get_address(
                    self.client,
                    "Bitcoin",
                    parse_path("44'/0'/%d'/0/0" % nr),
                    show_display=(nr == 1),
                    multisig=getmultisig(0, 0, xpubs=xpubs),
                )
                == "3Pdz86KtfJBuHLcSv4DysJo4aQfanTqCzG"
            )
            assert (
                btc.get_address(
                    self.client,
                    "Bitcoin",
                    parse_path("44'/0'/%d'/1/0" % nr),
                    show_display=(nr == 1),
                    multisig=getmultisig(1, 0, xpubs=xpubs),
                )
                == "36gP3KVx1ooStZ9quZDXbAF3GCr42b2zzd"
            )
    def test_bch_multisig(self):
        self.setup_mnemonic_allallall()
        xpubs = []
        for n in range(1, 4):
            node = btc.get_public_node(self.client, parse_path("44'/145'/%d'" % n))
            xpubs.append(node.xpub)

        for nr in range(1, 4):
            assert (
                btc.get_address(
                    self.client,
                    "Bcash",
                    parse_path("44'/145'/%d'/0/0" % nr),
                    show_display=(nr == 1),
                    multisig=getmultisig(0, 0, xpubs=xpubs),
                )
                == "bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw"
            )
            assert (
                btc.get_address(
                    self.client,
                    "Bcash",
                    parse_path("44'/145'/%d'/1/0" % nr),
                    show_display=(nr == 1),
                    multisig=getmultisig(1, 0, xpubs=xpubs),
                )
                == "bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a"
            )
 def test_multisig_missing(self):
     self.setup_mnemonic_allallall()
     xpubs = []
     for n in range(1, 4):
         # shift account numbers by 10 to create valid multisig,
         # but not containing the keys used below
         n = n + 10
         node = btc.get_public_node(self.client, parse_path("44'/0'/%d'" % n))
         xpubs.append(node.xpub)
     for nr in range(1, 4):
         with pytest.raises(CallException):
             btc.get_address(
                 self.client,
                 "Bitcoin",
                 parse_path("44'/0'/%d'/0/0" % nr),
                 show_display=(nr == 1),
                 multisig=getmultisig(0, 0, xpubs=xpubs),
             )
         with pytest.raises(CallException):
             btc.get_address(
                 self.client,
                 "Bitcoin",
                 parse_path("44'/0'/%d'/1/0" % nr),
                 show_display=(nr == 1),
                 multisig=getmultisig(1, 0, xpubs=xpubs),
             )
    def test_testnet_one_two_fee(self):
        self.setup_mnemonic_allallall()
        # see 87be0736f202f7c2bff0781b42bad3e0cdcb54761939da69ea793a3735552c56

        # tx: e5040e1bc1ae7667ffb9e5248e90b2fb93cd9150234151ce90e14ab2f5933bcd
        # input 0: 0.31 BTC
        inp1 = proto.TxInputType(
            address_n=parse_path("44'/1'/0'/0/0"),
            # amount=31000000,
            prev_hash=TXHASH_e5040e,
            prev_index=0,
        )

        out1 = proto.TxOutputType(
            address="msj42CCGruhRsFrGATiUuh25dtxYtnpbTx",
            amount=30090000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        out2 = proto.TxOutputType(
            address_n=parse_path("44'/1'/0'/1/0"),
            amount=900000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        _, serialized_tx = check_sign_tx(self.client, "Testnet", [inp1], [out1, out2])

        assert (
            serialized_tx.hex()
            == "0100000001cd3b93f5b24ae190ce5141235091cd93fbb2908e24e5b9ff6776aec11b0e04e5000000006b483045022100eba3bbcbb82ab1ebac88a394e8fb53b0263dadbb3e8072f0a21ee62818c911060220686a9b7f306d028b54a228b5c47cc6c27b1d01a3b0770440bcc64d55d8bace2c0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff021023cb01000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288aca0bb0d00000000001976a9143d3cca567e00a04819742b21a696a67da796498b88ac00000000"
        )
    def test_one_two_fee(self):
        self.setup_mnemonic_allallall()

        # tx: c275c333fd1b36bef4af316226c66a8b3693fbfcc081a5e16a2ae5fcb09e92bf

        inp1 = proto.TxInputType(
            address_n=parse_path(
                "m/44'/0'/0'/0/5"
            ),  # 1GA9u9TfCG7SWmKCveBumdA1TZpfom6ZdJ
            # amount=50000,
            prev_hash=TXHASH_50f6f1,
            prev_index=1,
        )

        out1 = proto.TxOutputType(
            address_n=parse_path(
                "m/44'/0'/0'/1/3"
            ),  # 1EcL6AyfQTyWKGvXwNSfsWoYnD3whzVFdu
            amount=30000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        out2 = proto.TxOutputType(
            address="1Up15Msx4sbvUCGm8Xgo2Zp5FQim3wE59",
            amount=10000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        _, serialized_tx = check_sign_tx(self.client, "Bitcoin", [inp1], [out1, out2])

        assert (
            serialized_tx.hex()
            == "01000000016d20f69067ad1ffd50ee7c0f377dde2c932ccb03e84b5659732da99c20f1f650010000006a47304402203429bd3ce7b38c5c1e8a15340edd79ced41a2939aae62e259d2e3d18e0c5ee7602201b83b10ebc4d6dcee3f9eb42ba8f1ef8a059a05397e0c1b9223d1565a3e6ec01012102a7a079c1ef9916b289c2ff21a992c808d0de3dfcf8a9f163205c5c9e21f55d5cffffffff0230750000000000001976a914954820f1de627a703596ac0396f986d958e3de4c88ac10270000000000001976a91405427736705cfbfaff76b1cff48283707fb1037088ac00000000"
        )
 def test_monero_getwatchkey(self):
     self.setup_mnemonic_nopin_nopassphrase()
     res = monero.get_watch_key(self.client, parse_path("m/44h/128h/0h"))
     assert (
         res.address
         == b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM"
     )
     assert (
         res.watch_key.hex()
         == "8722520a581e2a50cc1adab4a1692401effd37b0d63b9d9b60fd7f34ea2b950e"
     )
     res = monero.get_watch_key(self.client, parse_path("m/44h/128h/1h"))
     assert (
         res.address
         == b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie"
     )
     assert (
         res.watch_key.hex()
         == "1f70b7d9e86c11b7a5bee883b75c43d6be189c8f812726ea1ecd94b06bb7db04"
     )
     res = monero.get_watch_key(self.client, parse_path("m/44h/128h/2h"))
     assert (
         res.address
         == b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH"
     )
     assert (
         res.watch_key.hex()
         == "e0671fbed2c9231fe4f286962862813a4a4d153c793bf5d0e3742119723f3000"
     )
def test_timestamp_included(client):
    # tx: 3bf506c81ce84eda891679ddc797d162c17c60b15d6c0ac23be5e31369e7235f
    # input 0: 0.01 CPC
    # tx: f3a6e6411f1b2dffd76d2729bae8e056f8f9ecf8996d3f428e75a6f23f2c5e8c
    # input 0: 0.02 CPC

    inp1 = messages.TxInputType(
        address_n=parse_path("m/44'/289'/0'/0/0"), prev_hash=TXHASH_3bf506, prev_index=0
    )

    inp2 = messages.TxInputType(
        address_n=parse_path("m/44'/289'/0'/0/0"), prev_hash=TXHASH_f3a6e6, prev_index=1
    )

    out1 = messages.TxOutputType(
        address="CUGi8RGPWxbHM6FxF4eMEfqmQ6Bs5VjCdr",
        amount=3000000 - 20000,
        script_type=messages.OutputScriptType.PAYTOADDRESS,
    )

    with client:
        details = messages.SignTx(version=1, timestamp=0x5BCF5C66)
        _, timestamp_tx = btc.sign_tx(
            client,
            "Capricoin",
            [inp1, inp2],
            [out1],
            details=details,
            prev_txes=tx_cache("Capricoin"),
        )

    # Accepted by network https://insight.capricoin.org/tx/1bf227e6e24fe1f8ac98849fe06a2c5b77762e906fcf7e82787675f7f3a10bb8
    accepted_txhex = "01000000665ccf5b025f23e76913e3e53bc20a6c5db1607cc162d197c7dd791689da4ee81cc806f53b000000006b483045022100fce7ccbeb9524f36d118ebcfebcb133a05c236c4478e2051cfd5c9632920aee602206921b7be1a81f30cce3d8e7dba4597fc16a2761c42321c49d65eeacdfe3781250121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff8c5e2c3ff2a6758e423f6d99f8ecf9f856e0e8ba29276dd7ff2d1b1f41e6a6f3010000006a473044022015d967166fe9f89fbed8747328b1c4658aa1d7163e731c5fd5908feafe08e9a6022028af30801098418bd298cc60b143c52c48466f5791256721304b6eba4fdf0b3c0121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff01a0782d00000000001976a914818437acfd15780debd31f3fd21d4ca678bb36d188ac00000000"
    assert timestamp_tx.hex() == accepted_txhex
    def test_change_on_main_chain_allowed(self):
        self.setup_mnemonic_allallall()
        # see 87be0736f202f7c2bff0781b42bad3e0cdcb54761939da69ea793a3735552c56

        # tx: e5040e1bc1ae7667ffb9e5248e90b2fb93cd9150234151ce90e14ab2f5933bcd
        # input 0: 0.31 BTC
        inp1 = proto.TxInputType(
            address_n=parse_path("44'/1'/0'/0/0"),
            # amount=31000000,
            prev_hash=TXHASH_e5040e,
            prev_index=0,
        )

        out1 = proto.TxOutputType(
            address="msj42CCGruhRsFrGATiUuh25dtxYtnpbTx",
            amount=30090000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        # change on main chain is allowed => treated as a change
        out_change = proto.TxOutputType(
            address_n=parse_path("44'/1'/0'/0/0"),
            amount=900000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        check_sign_tx(self.client, "Testnet", [inp1], [out1, out_change])
    def test_ethereum_signtx_nodata(self):
        self.setup_mnemonic_nopin_nopassphrase()

        with self.client:
            self.client.set_expected_responses(
                [
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.EthereumTxRequest(data_length=None),  # v,r,s checked later
                ]
            )

            sig_v, sig_r, sig_s = ethereum.sign_tx(
                self.client,
                n=parse_path("44'/60'/0'/0/100"),
                nonce=0,
                gas_price=20,
                gas_limit=20,
                to=TO_ADDR,
                value=10,
            )

        assert sig_v == 27
        assert (
            sig_r.hex()
            == "2f548f63ddb4cf19b6b9f922da58ff71833b967d590f3b4dcc2a70810338a982"
        )
        assert (
            sig_s.hex()
            == "428d35f0dca963b5196b63e7aa5e0405d8bff77d6aee1202183f1f68dacb4483"
        )

        with self.client:
            self.client.set_expected_responses(
                [
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.EthereumTxRequest(data_length=None),
                ]
            )

            sig_v, sig_r, sig_s = ethereum.sign_tx(
                self.client,
                n=parse_path("44'/60'/0'/0/100"),
                nonce=123456,
                gas_price=20000,
                gas_limit=20000,
                to=TO_ADDR,
                value=12345678901234567890,
            )
        assert sig_v == 27
        assert (
            sig_r.hex()
            == "3bf0470cd7f5ad8d82613199f73deadc55c3c9f32f91b1a21b5ef644144ebd58"
        )
        assert (
            sig_s.hex()
            == "48b3ef1b2502febdf35e9ff4df0ba1fda62f042fad639eb4852a297fc9872ebd"
        )
 def test_show_segwit(self):
     self.setup_mnemonic_allallall()
     assert (
         btc.get_address(
             self.client,
             "Testnet",
             parse_path("49'/1'/0'/0/0"),
             True,
             None,
             script_type=proto.InputScriptType.SPENDWITNESS,
         )
         == "tb1qqzv60m9ajw8drqulta4ld4gfx0rdh82un5s65s"
     )
     assert (
         btc.get_address(
             self.client,
             "Testnet",
             parse_path("49'/1'/0'/1/0"),
             False,
             None,
             script_type=proto.InputScriptType.SPENDWITNESS,
         )
         == "tb1q694ccp5qcc0udmfwgp692u2s2hjpq5h407urtu"
     )
     assert (
         btc.get_address(
             self.client,
             "Testnet",
             parse_path("44'/1'/0'/0/0"),
             False,
             None,
             script_type=proto.InputScriptType.SPENDWITNESS,
         )
         == "tb1q54un3q39sf7e7tlfq99d6ezys7qgc62a6rxllc"
     )
     assert (
         btc.get_address(
             self.client,
             "Testnet",
             parse_path("44'/1'/0'/0/0"),
             False,
             None,
             script_type=proto.InputScriptType.SPENDADDRESS,
         )
         == "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q"
     )
     assert (
         btc.get_address(
             self.client,
             "Groestlcoin",
             parse_path("84'/17'/0'/0/0"),
             False,
             None,
             script_type=proto.InputScriptType.SPENDWITNESS,
         )
         == "grs1qw4teyraux2s77nhjdwh9ar8rl9dt7zww8r6lne"
     )
 def test_show_segwit(self):
     self.setup_mnemonic_allallall()
     assert (
         btc.get_address(
             self.client,
             "Testnet",
             parse_path("49'/1'/0'/1/0"),
             True,
             None,
             script_type=proto.InputScriptType.SPENDP2SHWITNESS,
         )
         == "2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX"
     )
     assert (
         btc.get_address(
             self.client,
             "Testnet",
             parse_path("49'/1'/0'/0/0"),
             False,
             None,
             script_type=proto.InputScriptType.SPENDP2SHWITNESS,
         )
         == "2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp"
     )
     assert (
         btc.get_address(
             self.client,
             "Testnet",
             parse_path("44'/1'/0'/0/0"),
             False,
             None,
             script_type=proto.InputScriptType.SPENDP2SHWITNESS,
         )
         == "2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc"
     )
     assert (
         btc.get_address(
             self.client,
             "Testnet",
             parse_path("44'/1'/0'/0/0"),
             False,
             None,
             script_type=proto.InputScriptType.SPENDADDRESS,
         )
         == "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q"
     )
     assert (
         btc.get_address(
             self.client,
             "Groestlcoin Testnet",
             parse_path("49'/1'/0'/0/0"),
             False,
             None,
             script_type=proto.InputScriptType.SPENDP2SHWITNESS,
         )
         == "2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e"
     )
    def test_tezos_get_address(self):
        self.setup_mnemonic_allallall()

        path = parse_path("m/44'/1729'/0'")
        address = get_address(self.client, path, show_display=True)
        assert address == "tz1Kef7BSg6fo75jk37WkKRYSnJDs69KVqt9"

        path = parse_path("m/44'/1729'/1'")
        address = get_address(self.client, path, show_display=True)
        assert address == "tz1ekQapZCX4AXxTJhJZhroDKDYLHDHegvm1"
    def test_tezos_get_public_key(self):
        self.setup_mnemonic_allallall()

        path = parse_path("m/44'/1729'/0'")
        pk = get_public_key(self.client, path)
        assert pk == "edpkttLhEbVfMC3DhyVVFzdwh8ncRnEWiLD1x8TAuPU7vSJak7RtBX"

        path = parse_path("m/44'/1729'/1'")
        pk = get_public_key(self.client, path)
        assert pk == "edpkuTPqWjcApwyD3VdJhviKM5C13zGk8c4m87crgFarQboF3Mp56f"
 def test_nem_getaddress(self):
     self.setup_mnemonic_nopin_nopassphrase()
     assert (
         nem.get_address(self.client, parse_path("m/44'/1'/0'/0'/0'"), 0x68)
         == "NB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQGHUBWQN"
     )
     assert (
         nem.get_address(self.client, parse_path("m/44'/1'/0'/0'/0'"), 0x98)
         == "TB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQHSBNBMF"
     )
    def test_ripple_get_address(self):
        # data from https://iancoleman.io/bip39/#english
        self.setup_mnemonic_allallall()

        address = get_address(self.client, parse_path("m/44'/144'/0'/0/0"))
        assert address == "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H"
        address = get_address(self.client, parse_path("m/44'/144'/0'/0/1"))
        assert address == "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws"
        address = get_address(self.client, parse_path("m/44'/144'/1'/0/0"))
        assert address == "rJX2KwzaLJDyFhhtXKi3htaLfaUH2tptEX"
    def test_ethereum_signtx_newcontract(self):
        self.setup_mnemonic_allallall()

        # contract creation without data should fail.
        with pytest.raises(Exception):
            ethereum.sign_tx(
                self.client,
                n=parse_path("44'/60'/0'/0/0"),
                nonce=123456,
                gas_price=20000,
                gas_limit=20000,
                to="",
                value=12345678901234567890,
            )

        with self.client:
            self.client.set_expected_responses(
                [
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.EthereumTxRequest(
                        data_length=1024,
                        signature_r=None,
                        signature_s=None,
                        signature_v=None,
                    ),
                    proto.EthereumTxRequest(data_length=1024),
                    proto.EthereumTxRequest(data_length=1024),
                    proto.EthereumTxRequest(data_length=3),
                    proto.EthereumTxRequest(),
                ]
            )

            sig_v, sig_r, sig_s = ethereum.sign_tx(
                self.client,
                n=parse_path("44'/60'/0'/0/0"),
                nonce=0,
                gas_price=20000,
                gas_limit=20000,
                to="",
                value=12345678901234567890,
                data=b"ABCDEFGHIJKLMNOP" * 256 + b"!!!",
            )
        assert sig_v == 28
        assert (
            sig_r.hex()
            == "c86bda9de238b1c602648996561e7270a3be208da96bbf23474cb8e4014b9f93"
        )
        assert (
            sig_s.hex()
            == "18742403f75a05e7fa9868c30b36f1e55628de02d01c03084c1ff6775a13137c"
        )
 def test_monero_getaddress(self):
     self.setup_mnemonic_nopin_nopassphrase()
     assert (
         monero.get_address(self.client, parse_path("m/44h/128h/0h"))
         == b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM"
     )
     assert (
         monero.get_address(self.client, parse_path("m/44h/128h/1h"))
         == b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie"
     )
     assert (
         monero.get_address(self.client, parse_path("m/44h/128h/2h"))
         == b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH"
     )
 def test_ripple_get_address_other(self):
     # data from https://github.com/you21979/node-ripple-bip32/blob/master/test/test.js
     debuglink.load_device_by_mnemonic(
         self.client,
         mnemonic="armed bundle pudding lazy strategy impulse where identify submit weekend physical antenna flight social acoustic absurd whip snack decide blur unfold fiction pumpkin athlete",
         pin="",
         passphrase_protection=False,
         label="test",
         language="english",
     )
     address = get_address(self.client, parse_path("m/44'/144'/0'/0/0"))
     assert address == "r4ocGE47gm4G4LkA9mriVHQqzpMLBTgnTY"
     address = get_address(self.client, parse_path("m/44'/144'/0'/0/1"))
     assert address == "rUt9ULSrUvfCmke8HTFU1szbmFpWzVbBXW"
 def test_bch(self):
     self.setup_mnemonic_allallall()
     assert (
         btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/0/0"))
         == "bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv"
     )
     assert (
         btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/0/1"))
         == "bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4"
     )
     assert (
         btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/1/0"))
         == "bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw"
     )
 def test_grs(self):
     self.setup_mnemonic_allallall()
     assert (
         btc.get_address(self.client, "Groestlcoin", parse_path("44'/17'/0'/0/0"))
         == "Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM"
     )
     assert (
         btc.get_address(self.client, "Groestlcoin", parse_path("44'/17'/0'/1/0"))
         == "FmRaqvVBRrAp2Umfqx9V1ectZy8gw54QDN"
     )
     assert (
         btc.get_address(self.client, "Groestlcoin", parse_path("44'/17'/0'/1/1"))
         == "Fmhtxeh7YdCBkyQF7AQG4QnY8y3rJg89di"
     )
    def test_lisk_sign_tx_send_wrong_path(self):
        self.setup_mnemonic_allallall()

        with self.client:
            self.client.set_expected_responses(
                [
                    proto.ButtonRequest(
                        code=proto.ButtonRequestType.UnknownDerivationPath
                    ),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
                    proto.LiskSignedTx(
                        signature=bytes.fromhex(
                            "cdce9eba2ea8fa75f90fbc725f0d9de6152c7189a3044ab2fe307d9ff54754856e09125d7a15376eaf4bb5451b63881821948222ccd9ffb5da4d9b1aa8bd4904"
                        )
                    ),
                ]
            )

            lisk.sign_tx(
                self.client,
                parse_path("m/44'/134'/123456'/123456'/123456'/123456'/123456'"),
                {
                    "amount": "10000000",
                    "recipientId": "9971262264659915921L",
                    "timestamp": 57525937,
                    "type": 0,
                    "fee": "10000000",
                    "asset": {},
                },
            )
    def test_nem_signtx_mosaic_supply_change(self):
        self.setup_mnemonic_nopin_nopassphrase()

        with self.client:
            tx = nem.sign_tx(
                self.client,
                parse_path("m/44'/1'/0'/0'/0'"),
                {
                    "timeStamp": 74649215,
                    "fee": 2000000,
                    "type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
                    "deadline": 74735615,
                    "message": {},
                    "mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
                    "supplyType": 1,
                    "delta": 1,
                    "version": (0x98 << 24),
                    "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
                    "creationFee": 1500,
                },
            )

            assert (
                tx.data.hex()
                == "02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000"
            )
            assert (
                tx.signature.hex()
                == "928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a"
            )
    def test_lisk_sign_tx_send_with_data(self):
        self.setup_mnemonic_allallall()

        with self.client:
            self.client.set_expected_responses(
                [
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
                    proto.LiskSignedTx(
                        signature=bytes.fromhex(
                            "4e83a651e82f2f787a71a5f44a2911dd0429ee4001b80c79fb7d174ea63ceeefdfba55aa3a9f31fa14b8325a39ad973dcd7eadbaa77b0447a9893f84b60f210e"
                        )
                    ),
                ]
            )

            lisk.sign_tx(
                self.client,
                parse_path("m/44'/134'/0'"),
                {
                    "amount": "10000000",
                    "recipientId": "9971262264659915921L",
                    "timestamp": 57525937,
                    "type": 0,
                    "fee": "20000000",
                    "asset": {"data": "Test data"},
                },
            )
    def test_nem_signtx_xem_as_mosaic(self):
        self.setup_mnemonic_nopin_nopassphrase()

        tx = nem.sign_tx(
            self.client,
            parse_path("m/44'/1'/0'/0'/0'"),
            {
                "timeStamp": 76809215,
                "amount": 5000000,
                "fee": 1000000,
                "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
                "type": nem.TYPE_TRANSACTION_TRANSFER,
                "deadline": 76895615,
                "version": (0x98 << 24),
                "message": {},
                "mosaics": [
                    {
                        "mosaicId": {"namespaceId": "nem", "name": "xem"},
                        "quantity": 9000000,
                    }
                ],
            },
        )

        # trezor should display 45 XEM (multiplied by amount)
        assert (
            tx.data.hex()
            == "0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a404b4c000000000000000000010000001a0000000e000000030000006e656d0300000078656d4054890000000000"
        )
        assert (
            tx.signature.hex()
            == "7b25a84b65adb489ea55739f1ca2d83a0ae069c3c58d0ea075fc30bfe8f649519199ad2324ca229c6c3214191469f95326e99712124592cae7cd3a092c93ac0c"
        )
    def test_nem_signtx_known_mosaic(self):

        self.setup_mnemonic_nopin_nopassphrase()

        tx = nem.sign_tx(
            self.client,
            parse_path("m/44'/1'/0'/0'/0'"),
            {
                "timeStamp": 76809215,
                "amount": 3000000,
                "fee": 1000000,
                "recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT",
                "type": nem.TYPE_TRANSACTION_TRANSFER,
                "deadline": 76895615,
                "version": (0x68 << 24),
                "message": {},
                "mosaics": [
                    {
                        "mosaicId": {"namespaceId": "dim", "name": "token"},
                        "quantity": 111000,
                    }
                ],
            },
        )

        # trezor should display 0 XEM and 0.333 DIMTOK
        assert (
            tx.data.hex()
            == "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c54c0c62d000000000000000000010000001c000000100000000300000064696d05000000746f6b656e98b1010000000000"
        )
        assert (
            tx.signature.hex()
            == "e7f14ef8c39727bfd257e109cd5acac31542f2e41f2e5deb258fc1db602b690eb1cabca41a627fe2adc51f3193db85c76b41c80bb60161eb8738ebf20b507104"
        )
    def test_nem_signtx_unknown_mosaic(self):
        self.setup_mnemonic_nopin_nopassphrase()

        tx = nem.sign_tx(
            self.client,
            parse_path("m/44'/1'/0'/0'/0'"),
            {
                "timeStamp": 76809215,
                "amount": 2000000,
                "fee": 1000000,
                "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
                "type": nem.TYPE_TRANSACTION_TRANSFER,
                "deadline": 76895615,
                "version": (0x98 << 24),
                "message": {},
                "mosaics": [
                    {
                        "mosaicId": {"namespaceId": "xxx", "name": "aa"},
                        "quantity": 3500000,
                    }
                ],
            },
        )

        # trezor should display warning about unknown mosaic and then dialog for 7000000 raw units of xxx.aa and 0 XEM
        assert (
            tx.data.hex()
            == "0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e00000000000000000001000000190000000d00000003000000787878020000006161e067350000000000"
        )
        assert (
            tx.signature.hex()
            == "2f0280420eceb41ef9e5d94fa44ddda9cdc70b8f423ae18af577f6d85df64bb4aaf40cf24fc6eef47c63b0963611f8682348cecdc49a9b64eafcbe7afcb49102"
        )
    def test_nem_signtx_known_mosaic_with_levy(self):

        self.setup_mnemonic_nopin_nopassphrase()

        tx = nem.sign_tx(
            self.client,
            parse_path("m/44'/1'/0'/0'/0'"),
            {
                "timeStamp": 76809215,
                "amount": 2000000,
                "fee": 1000000,
                "recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT",
                "type": nem.TYPE_TRANSACTION_TRANSFER,
                "deadline": 76895615,
                "version": (0x68 << 24),
                "message": {},
                "mosaics": [
                    {
                        "mosaicId": {"namespaceId": "dim", "name": "coin"},
                        "quantity": 222000,
                    }
                ],
            },
        )

        # trezor should display 0 XEM and 0.444 DIM and levy of 0.000444 DIM
        assert (
            tx.data.hex()
            == "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000010000001b0000000f0000000300000064696d04000000636f696e3063030000000000"
        )
        assert (
            tx.signature.hex()
            == "d3222dd7b83d66bda0539827ac6f909d06e40350b5e5e893d6fa762f954e9bf7da61022ef04950e7b6dfa88a2278f2f8a1b21df2bc3af22b388cb3a90bf76f07"
        )
    def test_ontology_get_ont_address(self):
        self.setup_mnemonic_nopin_nopassphrase()

        assert (
            ontology.get_address(self.client, parse_path("m/44'/1024'/0'/0/0"))
            == "ANzeepWmi9hoLBA3UiwVhUm7Eku196VUHk"
        )
    def test_ontology_get_neo_address(self):
        self.setup_mnemonic_nopin_nopassphrase()

        assert (
            ontology.get_address(self.client, parse_path("m/44'/888'/0'/0/0"))
            == "AZEMburLePcdfqBFnVfdbsXKiBSnmtgFZr"
        )
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.

import pytest

from trezorlib import messages, tezos
from trezorlib.protobuf import dict_to_proto
from trezorlib.tools import parse_path

TEZOS_PATH = parse_path("m/44'/1729'/0'")
TEZOS_PATH_10 = parse_path("m/44'/1729'/10'")
TEZOS_PATH_15 = parse_path("m/44'/1729'/15'")


@pytest.mark.altcoin
@pytest.mark.tezos
@pytest.mark.skip_t1
class TestMsgTezosSignTx:
    def input_flow(self, debug, num_pages):
        yield
        for _ in range(num_pages - 1):
            debug.swipe_up()
        debug.press_yes()

    def test_tezos_sign_tx_proposal(self, client):
    def test_send_bch_nochange(self):
        self.setup_mnemonic_allallall()
        inp1 = proto.TxInputType(
            address_n=parse_path("44'/145'/0'/1/0"),
            # bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
            amount=1896050,
            prev_hash=bytes.fromhex(
                "502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
            ),
            prev_index=0,
            script_type=proto.InputScriptType.SPENDADDRESS,
        )
        inp2 = proto.TxInputType(
            address_n=parse_path("44'/145'/0'/0/1"),
            # bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
            amount=73452,
            prev_hash=bytes.fromhex(
                "502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
            ),
            prev_index=1,
            script_type=proto.InputScriptType.SPENDADDRESS,
        )
        out1 = proto.TxOutputType(
            address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4",
            amount=1934960,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ])
            _, serialized_tx = btc.sign_tx(self.client,
                                           "Bcash", [inp1, inp2], [out1],
                                           prev_txes=TX_API)

        assert (
            serialized_tx.hex() ==
            "01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000"
        )
    def test_send_bch_multisig_wrongchange(self):
        self.setup_mnemonic_allallall()
        nodes = [
            btc.get_public_node(self.client,
                                parse_path("48'/145'/%d'" % i)).node
            for i in range(1, 4)
        ]

        def getmultisig(chain, nr, signatures=[b"", b"", b""], nodes=nodes):
            return proto.MultisigRedeemScriptType(nodes=nodes,
                                                  address_n=[chain, nr],
                                                  signatures=signatures,
                                                  m=2)

        correcthorse = proto.HDNodeType(
            depth=1,
            fingerprint=0,
            child_num=0,
            chain_code=bytes.fromhex(
                "0000000000000000000000000000000000000000000000000000000000000000"
            ),
            public_key=bytes.fromhex(
                "0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71"
            ),
        )
        sig = bytes.fromhex(
            "304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae"
        )
        inp1 = proto.TxInputType(
            address_n=parse_path("48'/145'/1'/1/0"),
            multisig=getmultisig(1, 0, [b"", sig, b""]),
            # bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a
            amount=24000,
            prev_hash=bytes.fromhex(
                "f68caf10df12d5b07a34601d88fa6856c6edcbf4d05ebef3486510ae1c293d5f"
            ),
            prev_index=1,
            script_type=proto.InputScriptType.SPENDMULTISIG,
        )
        out1 = proto.TxOutputType(
            address_n=parse_path("48'/145'/1'/1/1"),
            multisig=proto.MultisigRedeemScriptType(
                pubkeys=[
                    proto.HDNodePathType(node=nodes[0], address_n=[1, 1]),
                    proto.HDNodePathType(node=correcthorse, address_n=[]),
                    proto.HDNodePathType(node=correcthorse, address_n=[]),
                ],
                signatures=[b"", b"", b""],
                m=2,
            ),
            script_type=proto.OutputScriptType.PAYTOMULTISIG,
            amount=23000,
        )
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ])
            (signatures1, serialized_tx) = btc.sign_tx(self.client,
                                                       "Bcash", [inp1], [out1],
                                                       prev_txes=TX_API)
        assert (
            signatures1[0].hex() ==
            "304402201badcdcafef4855ed58621f95935efcbc72068510472140f4ec5e252faa0af93022003310a43488288f70aedee96a5af2643a255268a6858cda9ae3001ea5e3c7557"
        )
        assert (
            serialized_tx.hex() ==
            "01000000015f3d291cae106548f3be5ed0f4cbedc65668fa881d60347ab0d512df10af8cf601000000fc0047304402201badcdcafef4855ed58621f95935efcbc72068510472140f4ec5e252faa0af93022003310a43488288f70aedee96a5af2643a255268a6858cda9ae3001ea5e3c75574147304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae414c69522102245739b55787a27228a4fe78b3a324366cc645fbaa708cad45da351a334341192102debbdcb0b6970d5ade84a50fdbda1c701cdde5c9925d9b6cd8e05a9a15dbef352102ffe5fa04547b2b0c3cfbc21c08a1ddfb147025fee10274cdcd5c1bdeee88eae253aeffffffff01d85900000000000017a914a23eb2a1ed4003d357770120f5c370e199ee55468700000000"
        )
# as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.

import pytest

from trezorlib import lisk
from trezorlib.tools import parse_path

from ..common import MNEMONIC12

LISK_PATH = parse_path("m/44h/134h/0h/0h")


@pytest.mark.altcoin
@pytest.mark.lisk
class TestMsgLiskGetPublicKey:
    @pytest.mark.setup_client(mnemonic=MNEMONIC12)
    def test_lisk_get_public_key(self, client):
        sig = lisk.get_public_key(client, LISK_PATH)
        assert (
            sig.public_key.hex()
            == "eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294"
        )
    def test_send_btg_multisig_change(self, client):
        nodes = [
            btc.get_public_node(
                client, parse_path(f"48'/156'/{i}'"), coin_name="Bgold"
            ).node
            for i in range(1, 4)
        ]

        def getmultisig(chain, nr, signatures=[b"", b"", b""], nodes=nodes):
            return proto.MultisigRedeemScriptType(
                nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2
            )

        inp1 = proto.TxInputType(
            address_n=parse_path("48'/156'/3'/0/0"),
            multisig=getmultisig(0, 0),
            # 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R
            amount=1252382934,
            prev_hash=TXHASH_25526b,
            prev_index=0,
            script_type=proto.InputScriptType.SPENDMULTISIG,
        )
        out1 = proto.TxOutputType(
            address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
            amount=24000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )
        out2 = proto.TxOutputType(
            address_n=parse_path("48'/156'/3'/1/0"),
            multisig=getmultisig(1, 0),
            script_type=proto.OutputScriptType.PAYTOMULTISIG,
            amount=1252382934 - 24000 - 1000,
        )
        with client:
            client.set_expected_responses(
                [
                    request_input(0),
                    request_meta(TXHASH_25526b),
                    request_input(0, TXHASH_25526b),
                    request_output(0, TXHASH_25526b),
                    request_output(1, TXHASH_25526b),
                    request_output(0),
                    proto.ButtonRequest(code=B.ConfirmOutput),
                    request_output(1),
                    proto.ButtonRequest(code=B.SignTx),
                    request_input(0),
                    request_output(0),
                    request_output(1),
                    request_finished(),
                ]
            )
            signatures, serialized_tx = btc.sign_tx(
                client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
            )

        assert (
            signatures[0].hex()
            == "30440220271c46ef3d7c37bd499804128623da3aa0014f3b4447dd39c4573b23c4537f6902205329167b9eb48427af62b04bf5138295f4c38613f6ba955934d15c499bff0d8a"
        )

        inp1 = proto.TxInputType(
            address_n=parse_path("48'/156'/1'/0/0"),
            multisig=getmultisig(0, 0, [b"", b"", signatures[0]]),
            amount=1252382934,
            prev_hash=TXHASH_25526b,
            prev_index=0,
            script_type=proto.InputScriptType.SPENDMULTISIG,
        )
        out2.address_n[2] = H_(1)

        with client:
            client.set_expected_responses(
                [
                    request_input(0),
                    request_meta(TXHASH_25526b),
                    request_input(0, TXHASH_25526b),
                    request_output(0, TXHASH_25526b),
                    request_output(1, TXHASH_25526b),
                    request_output(0),
                    proto.ButtonRequest(code=B.ConfirmOutput),
                    request_output(1),
                    proto.ButtonRequest(code=B.SignTx),
                    request_input(0),
                    request_output(0),
                    request_output(1),
                    request_finished(),
                ]
            )
            signatures, serialized_tx = btc.sign_tx(
                client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API
            )

        assert (
            signatures[0].hex()
            == "3045022100bdf8c4bd14217c183612c7e8f79691f6479bcb35aa403f77d70182f58633ac6e02205b10a79b7894bb40248a120c8fcb7096a46950593e4c5b48a20bc5ebe53d85fa"
        )
        assert (
            btc_hash(serialized_tx)[::-1].hex()
            == "b45ba21b69e1e1c6ad79f5408fe70d92fb861742d239cb6a952213f60c253e40"
        )
Exemple #36
0
def test_send_bch_multisig_change(client):
    nodes = [
        btc.get_public_node(
            client, parse_path(f"48'/145'/{i}'/0'"), coin_name="Bcash"
        ).node
        for i in range(1, 4)
    ]

    EMPTY_SIGNATURES = [b"", b"", b""]

    def getmultisig(chain, nr, signatures):
        return messages.MultisigRedeemScriptType(
            nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2
        )

    inp1 = messages.TxInputType(
        address_n=parse_path("48'/145'/3'/0'/0/0"),
        multisig=getmultisig(0, 0, EMPTY_SIGNATURES),
        amount=48490,
        prev_hash=TXHASH_8b6db9,
        prev_index=0,
        script_type=messages.InputScriptType.SPENDMULTISIG,
    )
    out1 = messages.TxOutputType(
        address="bitcoincash:qqq8gx2j76nw4dfefumxmdwvtf2tpsjznusgsmzex9",
        amount=24000,
        script_type=messages.OutputScriptType.PAYTOADDRESS,
    )
    out2 = messages.TxOutputType(
        address_n=parse_path("48'/145'/3'/0'/1/0"),
        multisig=getmultisig(1, 0, EMPTY_SIGNATURES),
        script_type=messages.OutputScriptType.PAYTOMULTISIG,
        amount=24000,
    )
    with client:
        client.set_expected_responses(
            [
                request_input(0),
                request_output(0),
                messages.ButtonRequest(code=B.ConfirmOutput),
                request_output(1),
                messages.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_meta(TXHASH_8b6db9),
                request_input(0, TXHASH_8b6db9),
                request_output(0, TXHASH_8b6db9),
                request_input(0),
                request_output(0),
                request_output(1),
                request_finished(),
            ]
        )
        (signatures1, serialized_tx) = btc.sign_tx(
            client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
        )

    assert (
        signatures1[0].hex()
        == "304402202b75dbb307d2556b9a85851d27ab118b3f06344bccb6e21b0a5dfcf74e0e644f02206611c59396d44741d34fd7bb602be06ef91690b22b47c3f3c271e15e20176ac0"
    )

    inp1 = messages.TxInputType(
        address_n=parse_path("48'/145'/1'/0'/0/0"),
        multisig=getmultisig(0, 0, [b"", b"", signatures1[0]]),
        # bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw
        amount=48490,
        prev_hash=TXHASH_8b6db9,
        prev_index=0,
        script_type=messages.InputScriptType.SPENDMULTISIG,
    )
    out2.address_n[2] = H_(1)

    with client:
        client.set_expected_responses(
            [
                request_input(0),
                request_output(0),
                messages.ButtonRequest(code=B.ConfirmOutput),
                request_output(1),
                messages.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_meta(TXHASH_8b6db9),
                request_input(0, TXHASH_8b6db9),
                request_output(0, TXHASH_8b6db9),
                request_input(0),
                request_output(0),
                request_output(1),
                request_finished(),
            ]
        )
        (signatures1, serialized_tx) = btc.sign_tx(
            client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
        )

    assert (
        signatures1[0].hex()
        == "3045022100cc12faf18a489d8014e978ef7ca0760aa6487cdb40b49dd991bfe9c66625f5a802206088fef49ecad30679d55eaa870741bbb8b83fac08eb078872ac276c8139015d"
    )
    assert (
        serialized_tx.hex()
        == "0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfd0000483045022100cc12faf18a489d8014e978ef7ca0760aa6487cdb40b49dd991bfe9c66625f5a802206088fef49ecad30679d55eaa870741bbb8b83fac08eb078872ac276c8139015d4147304402202b75dbb307d2556b9a85851d27ab118b3f06344bccb6e21b0a5dfcf74e0e644f02206611c59396d44741d34fd7bb602be06ef91690b22b47c3f3c271e15e20176ac0414c6952210290cc724ccb90a6c7c1c3b291938449464ea474390183909e51bcd2807ecb779d210222f537684e2933563f737192fbf1947fd9034402e5708d10f6decd8e1f03e172210350df5cb41013d6b06581230556006b0a85ccccd205745cc10c927755193c241b53aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a914dfc8c2dda26f7151ed7df8aeeca24089e6410fdd8700000000"
    )
    def test_one_one_fee_sapling(self, client):
        # prevout: e3820602226974b1dd87b7113cc8aea8c63e5ae29293991e7bfa80c126930368:0
        # input 1: 3.0 TAZ

        inp1 = proto.TxInputType(
            address_n=parse_path(
                "m/Zcash Testnet/0h/0/0"
            ),  # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
            amount=300000000,
            prev_hash=TXHASH_e38206,
            prev_index=0,
        )

        out1 = proto.TxOutputType(
            address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
            amount=300000000 - 1940,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        with client:
            client.set_expected_responses(
                [
                    proto.TxRequest(
                        request_type=proto.RequestType.TXINPUT,
                        details=proto.TxRequestDetailsType(request_index=0),
                    ),
                    proto.TxRequest(
                        request_type=proto.RequestType.TXOUTPUT,
                        details=proto.TxRequestDetailsType(request_index=0),
                    ),
                    proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.TxRequest(
                        request_type=proto.RequestType.TXINPUT,
                        details=proto.TxRequestDetailsType(request_index=0),
                    ),
                    proto.TxRequest(
                        request_type=proto.RequestType.TXOUTPUT,
                        details=proto.TxRequestDetailsType(request_index=0),
                    ),
                    proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
                ]
            )

            details = proto.SignTx(
                version=4,
                overwintered=True,
                version_group_id=0x892F2085,
                branch_id=0x76B809BB,
            )
            _, serialized_tx = btc.sign_tx(
                client,
                "Zcash Testnet",
                [inp1],
                [out1],
                details=details,
                prev_txes=TX_API,
            )

        # Accepted by network: tx 0cef132c1d6d67f11cfa48f7fca3209da29cf872ac782354bedb686e61a17a78
        assert (
            serialized_tx.hex()
            == "0400008085202f890168039326c180fa7b1e999392e25a3ec6a8aec83c11b787ddb1746922020682e3000000006b483045022100f28298891f48706697a6f898ac18e39ce2c7cebe547b585d51cc22d80b1b21a602201a807b8a18544832d95d1e3ada82c0617bc6d97d3f24d1fb4801ac396647aa880121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c9be111000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000000000000000000000000000000000"
        )
Exemple #38
0
import pytest

from trezorlib import btc, messages
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path

from .. import bip32

pytestmark = pytest.mark.skip_ui

VECTORS_BITCOIN = (  # coin_name, xpub_magic, path, xpub
    (
        "Bitcoin",
        0x0488B21E,
        parse_path("m/44h/0h/0h"),
        "xpub6BiVtCpG9fQPxnPmHXG8PhtzQdWC2Su4qWu6XW9tpWFYhxydCLJGrWBJZ5H6qTAHdPQ7pQhtpjiYZVZARo14qHiay2fvrX996oEP42u8wZy",
    ),
    (
        "Bitcoin",
        0x0488B21E,
        parse_path("m/44h/0h/10h"),
        "xpub6BiVtCpG9fQQR6cSuFeDaSvCDgNvNme499JUGX4RHDiZVWwZy9NwNieWKXHLe8XRbdrEmY87aqztBCbRJkXWV7VJB96XBT5cpkqYMHwvLWB",
    ),
    (
        "Bitcoin",
        0x0488B21E,
        parse_path("m/44h/0h/0h/0/0"),
        "xpub6FVDRC1jiWNTuT3embehwSZ1buxRDyZGbTakVCkBr6w2LwpERmYqXyvtrLeJX9hqzLaucS3qJXGekeFsSVCELkbgepp7FVGeH5BYekEgT9x",
    ),
    (
Exemple #39
0
def test_p2wpkh_in_p2sh_presigned(client):
    inp1 = proto.TxInputType(
        # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
        amount=111145789,
        prev_hash=TXHASH_091446,
        prev_index=1,
        script_type=proto.InputScriptType.EXTERNAL,
        script_sig=bytearray.fromhex("160014d16b8c0680c61fc6ed2e407455715055e41052f5"),
        witness=bytes.fromhex(
            "02483045022100ead79ee134f25bb585b48aee6284a4bb14e07f03cc130253e83450d095515e5202201e161e9402c8b26b666f2b67e5b668a404ef7e57858ae9a6a68c3837e65fdc69012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b79"
        ),
    )
    inp2 = proto.TxInputType(
        address_n=parse_path("84'/1'/0'/1/0"),
        amount=7289000,
        prev_hash=TXHASH_65b811,
        prev_index=1,
        script_type=proto.InputScriptType.SPENDWITNESS,
    )
    out1 = proto.TxOutputType(
        address="tb1q54un3q39sf7e7tlfq99d6ezys7qgc62a6rxllc",
        amount=12300000,
        script_type=proto.OutputScriptType.PAYTOADDRESS,
    )
    out2 = proto.TxOutputType(
        # address_n=parse_path("44'/1'/0'/0/0"),
        address="2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc",
        script_type=proto.OutputScriptType.PAYTOADDRESS,
        amount=45600000,
    )
    out3 = proto.TxOutputType(
        address="mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q",
        amount=111145789 + 7289000 - 11000 - 12300000 - 45600000,
        script_type=proto.OutputScriptType.PAYTOADDRESS,
    )

    with client:
        client.set_expected_responses(
            [
                request_input(0),
                request_input(1),
                request_meta(TXHASH_65b811),
                request_input(0, TXHASH_65b811),
                request_output(0, TXHASH_65b811),
                request_output(1, TXHASH_65b811),
                request_output(0),
                proto.ButtonRequest(code=B.ConfirmOutput),
                request_output(1),
                proto.ButtonRequest(code=B.ConfirmOutput),
                request_output(2),
                proto.ButtonRequest(code=B.ConfirmOutput),
                proto.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_meta(TXHASH_091446),
                request_input(0, TXHASH_091446),
                request_output(0, TXHASH_091446),
                request_output(1, TXHASH_091446),
                request_input(0),
                request_input(1),
                request_output(0),
                request_output(1),
                request_output(2),
                request_input(0),
                request_input(1),
                request_finished(),
            ]
        )
        _, serialized_tx = btc.sign_tx(
            client,
            "Testnet",
            [inp1, inp2],
            [out1, out2, out3],
            prev_txes=TX_CACHE_TESTNET,
        )

    assert (
        serialized_tx.hex()
        == "010000000001028a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090100000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff7b010c5faeb41cc5c253121b6bf69bf1a7c5867cd7f2d91569fea0ecd311b8650100000000ffffffff03e0aebb0000000000160014a579388225827d9f2fe9014add644487808c695d00cdb7020000000017a91491233e24a9bf8dbb19c1187ad876a9380c12e787870d859b03000000001976a914a579388225827d9f2fe9014add644487808c695d88ac02483045022100ead79ee134f25bb585b48aee6284a4bb14e07f03cc130253e83450d095515e5202201e161e9402c8b26b666f2b67e5b668a404ef7e57858ae9a6a68c3837e65fdc69012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7902463043021f585c54a84dc7326fa60e22729accd41153c7dd4725bd4c8f751aa3a8cd8d6a0220631bfd83fc312cc6d5d129572a25178696d81eaf50c8c3f16c6121be4f4c029d012103505647c017ff2156eb6da20fae72173d3b681a1d0a629f95f49e884db300689f00000000"
    )

    # Test corrupted script hash in scriptsig.
    inp1.script_sig[10] ^= 1
    with client:
        client.set_expected_responses(
            [
                request_input(0),
                request_input(1),
                request_meta(TXHASH_65b811),
                request_input(0, TXHASH_65b811),
                request_output(0, TXHASH_65b811),
                request_output(1, TXHASH_65b811),
                request_output(0),
                proto.ButtonRequest(code=B.ConfirmOutput),
                request_output(1),
                proto.ButtonRequest(code=B.ConfirmOutput),
                request_output(2),
                proto.ButtonRequest(code=B.ConfirmOutput),
                proto.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_meta(TXHASH_091446),
                request_input(0, TXHASH_091446),
                request_output(0, TXHASH_091446),
                request_output(1, TXHASH_091446),
                proto.Failure(code=proto.FailureType.DataError),
            ]
        )

        with pytest.raises(TrezorFailure, match="Invalid public key hash"):
            btc.sign_tx(
                client,
                "Testnet",
                [inp1, inp2],
                [out1, out2, out3],
                prev_txes=TX_CACHE_TESTNET,
            )
Exemple #40
0
 def get_bad_address():
     btc.get_address(client,
                     "Bitcoin",
                     parse_path("m/44'"),
                     show_display=True)
Exemple #41
0
    def test_ethereum_signtx_data(self):
        self.setup_mnemonic_nopin_nopassphrase()

        with self.client:
            self.client.set_expected_responses(
                [
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.EthereumTxRequest(data_length=None),
                ]
            )

            sig_v, sig_r, sig_s = ethereum.sign_tx(
                self.client,
                n=parse_path("44'/60'/0'/0/0"),
                nonce=0,
                gas_price=20,
                gas_limit=20,
                to=TO_ADDR,
                value=10,
                data=b"abcdefghijklmnop" * 16,
            )
        assert sig_v == 27
        assert (
            sig_r.hex()
            == "e90f9e3dbfb34861d40d67570cb369049e675c6eebfdda6b08413a2283421b85"
        )
        assert (
            sig_s.hex()
            == "763912b8801f76cbea7792d98123a245514beeab2f3afebb4bab637888e8393a"
        )

        with self.client:
            self.client.set_expected_responses(
                [
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.EthereumTxRequest(
                        data_length=1024,
                        signature_r=None,
                        signature_s=None,
                        signature_v=None,
                    ),
                    proto.EthereumTxRequest(data_length=1024),
                    proto.EthereumTxRequest(data_length=1024),
                    proto.EthereumTxRequest(data_length=3),
                    proto.EthereumTxRequest(),
                ]
            )

            sig_v, sig_r, sig_s = ethereum.sign_tx(
                self.client,
                n=parse_path("44'/60'/0'/0/0"),
                nonce=123456,
                gas_price=20000,
                gas_limit=20000,
                to=TO_ADDR,
                value=12345678901234567890,
                data=b"ABCDEFGHIJKLMNOP" * 256 + b"!!!",
            )
        assert sig_v == 27
        assert (
            sig_r.hex()
            == "dd96d82d791118a55601dfcede237760d2e9734b76c373ede5362a447c42ac48"
        )
        assert (
            sig_s.hex()
            == "60a77558f28d483d476f9507cd8a6a4bb47b86611aaff95fd5499b9ee9ebe7ee"
        )
    def test_send_bch_change(self):
        self.setup_mnemonic_allallall()
        inp1 = proto.TxInputType(
            address_n=parse_path("44'/145'/0'/0/0"),
            # bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv
            amount=1995344,
            prev_hash=bytes.fromhex(
                "bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78"
            ),
            prev_index=0,
            script_type=proto.InputScriptType.SPENDADDRESS,
        )
        out1 = proto.TxOutputType(
            address_n=parse_path("44'/145'/0'/1/0"),
            amount=1896050,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )
        out2 = proto.TxOutputType(
            address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4",
            amount=73452,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ])
            _, serialized_tx = btc.sign_tx(self.client,
                                           "Bcash", [inp1], [out1, out2],
                                           prev_txes=TX_API)

        assert (
            serialized_tx.hex() ==
            "0100000001781a716b1e15b41b07157933e5d777392a75bf87132650cb2e7d46fb8dc237bc000000006a473044022061aee4f17abe044d5df8c52c9ffd3b84e5a29743517e488b20ecf1ae0b3e4d3a02206bb84c55e407f3b684ff8d9bea0a3409cfd865795a19d10b3d3c31f12795c34a412103a020b36130021a0f037c1d1a02042e325c0cb666d6478c1afdcd9d913b9ef080ffffffff0272ee1c00000000001976a914b1401fce7e8bf123c88a0467e0ed11e3b9fbef5488acec1e0100000000001976a914d51eca49695cdf47e7f4b55507893e3ad53fe9d888ac00000000"
        )
Exemple #43
0
 def get_bad_address():
     btc.get_address(client, "Bitcoin", parse_path("m/0"))
    def test_one_one_fee_overwinter(self, client):
        # prevout: aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc:1
        # input 1: 3.0 TAZ

        inp1 = proto.TxInputType(
            address_n=parse_path(
                "m/Zcash Testnet/0h/0/0"
            ),  # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
            amount=300000000,
            prev_hash=TXHASH_aaf51e,
            prev_index=1,
        )

        out1 = proto.TxOutputType(
            address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
            amount=300000000 - 1940,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        with client:
            client.set_expected_responses(
                [
                    proto.TxRequest(
                        request_type=proto.RequestType.TXINPUT,
                        details=proto.TxRequestDetailsType(request_index=0),
                    ),
                    proto.TxRequest(
                        request_type=proto.RequestType.TXOUTPUT,
                        details=proto.TxRequestDetailsType(request_index=0),
                    ),
                    proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                    proto.TxRequest(
                        request_type=proto.RequestType.TXINPUT,
                        details=proto.TxRequestDetailsType(request_index=0),
                    ),
                    proto.TxRequest(
                        request_type=proto.RequestType.TXOUTPUT,
                        details=proto.TxRequestDetailsType(request_index=0),
                    ),
                    proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
                ]
            )

            details = proto.SignTx(
                version=3,
                overwintered=True,
                version_group_id=0x03C48270,
                branch_id=0x5BA81B19,
            )
            _, serialized_tx = btc.sign_tx(
                client,
                "Zcash Testnet",
                [inp1],
                [out1],
                details=details,
                prev_txes=TX_API,
            )

        # Accepted by network: tx eda9b772c47f0c29310759960e0081c98707aa67a0a2738bcc71439fcf360675
        assert (
            serialized_tx.hex()
            == "030000807082c40301dc754d63eff4698ee321476872519c53f14cfe58c9425c7ee464c206461ef5aa010000006a47304402207e45f303b4e42be824513855eb21653e1d2749cd94dcd0f0613d3f85d4efd1e20220699ffbdbcad889af7ede5ce9febf7a5ef8f5619b2464824529974c400cffaebc0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c9be111000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac000000000000000000"
        )
Exemple #45
0
def test_p2wsh_external_presigned(client):
    inp1 = proto.TxInputType(
        address_n=parse_path("84'/1'/0'/0/0"),
        amount=12300000,
        prev_hash=TXHASH_091446,
        prev_index=0,
        script_type=proto.InputScriptType.SPENDWITNESS,
    )

    inp2 = proto.TxInputType(
        # 1-of-2 multisig
        # m/84'/1'/0/0/0' for "alcohol woman abuse ..." seed.
        # m/84'/1'/0/0/0' for "all all ... all" seed.
        # tb1qpzmgzpcumztvmpu3q27wwdggqav26j9dgks92pvnne2lz9ferxgssmhzlq
        prev_hash=TXHASH_a345b8,
        prev_index=0,
        script_type=proto.InputScriptType.EXTERNAL,
        amount=100,
        witness=bytearray.fromhex(
            "030047304402206b570b99c22c841548a35a9b9c673fa3b87a9563ed64ad7d979aa3e01b2e303802201d0bebf58b7243e09798e734fc32892936c4d0c4984bec755dc951ef646e4a9a0147512103505f0d82bbdd251511591b34f36ad5eea37d3220c2b81a1189084431ddb3aa3d2103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f86252ae"
        ),
    )

    out1 = proto.TxOutputType(
        address="2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp",
        amount=12300000 + 100 - 10000,
        script_type=proto.OutputScriptType.PAYTOADDRESS,
    )

    with client:
        client.set_expected_responses(
            [
                request_input(0),
                request_meta(TXHASH_091446),
                request_input(0, TXHASH_091446),
                request_output(0, TXHASH_091446),
                request_output(1, TXHASH_091446),
                request_input(1),
                request_output(0),
                proto.ButtonRequest(code=B.ConfirmOutput),
                proto.ButtonRequest(code=B.SignTx),
                request_input(1),
                request_meta(TXHASH_a345b8),
                request_input(0, TXHASH_a345b8),
                request_output(0, TXHASH_a345b8),
                request_input(0),
                request_input(1),
                request_output(0),
                request_input(0),
                request_input(1),
                request_finished(),
            ]
        )

        _, serialized_tx = btc.sign_tx(
            client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET
        )

    assert (
        serialized_tx.hex()
        == "010000000001028a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090000000000ffffffff48e37c58a68ab4899400dc0950a661817ea7bac3e4556044c685b35957b845a30000000000ffffffff013488bb000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c9870247304402204270cf602ec151e72b99c5048755379c368c6c7cd722e4234ad4bb7b1b87d09d02207fa59b1c2926ea6b4f0094ab77c08e50b089a199a5bc8419e1ee6674809c4fb4012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862030047304402206b570b99c22c841548a35a9b9c673fa3b87a9563ed64ad7d979aa3e01b2e303802201d0bebf58b7243e09798e734fc32892936c4d0c4984bec755dc951ef646e4a9a0147512103505f0d82bbdd251511591b34f36ad5eea37d3220c2b81a1189084431ddb3aa3d2103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f86252ae00000000"
    )

    # Test corrupted signature in witness.
    inp2.witness[10] ^= 1
    with client:
        client.set_expected_responses(
            [
                request_input(0),
                request_meta(TXHASH_091446),
                request_input(0, TXHASH_091446),
                request_output(0, TXHASH_091446),
                request_output(1, TXHASH_091446),
                request_input(1),
                request_output(0),
                proto.ButtonRequest(code=B.ConfirmOutput),
                proto.ButtonRequest(code=B.SignTx),
                request_input(1),
                request_meta(TXHASH_a345b8),
                request_input(0, TXHASH_a345b8),
                request_output(0, TXHASH_a345b8),
                proto.Failure(code=proto.FailureType.DataError),
            ]
        )

        with pytest.raises(TrezorFailure, match="Invalid signature"):
            btc.sign_tx(
                client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET
            )
    def test_2_of_3(self, client):
        nodes = [
            btc.get_public_node(client, parse_path("48'/0'/%d'" % index)).node
            for index in range(1, 4)
        ]

        multisig = proto.MultisigRedeemScriptType(nodes=nodes,
                                                  address_n=[0, 0],
                                                  signatures=[b"", b"", b""],
                                                  m=2)
        # Let's go to sign with key 1
        inp1 = proto.TxInputType(
            address_n=parse_path("48'/0'/1'/0/0"),
            prev_hash=TXHASH_c6091a,
            prev_index=1,
            script_type=proto.InputScriptType.SPENDMULTISIG,
            multisig=multisig,
        )

        out1 = proto.TxOutputType(
            address="12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss",
            amount=100000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        with client:
            client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXMETA,
                    details=proto.TxRequestDetailsType(tx_hash=TXHASH_c6091a),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0,
                                                       tx_hash=TXHASH_c6091a),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0,
                                                       tx_hash=TXHASH_c6091a),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1,
                                                       tx_hash=TXHASH_c6091a),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ])

            # Now we have first signature
            signatures1, _ = btc.sign_tx(client,
                                         "Bitcoin", [inp1], [out1],
                                         prev_txes=TX_API)

        assert (
            signatures1[0].hex() ==
            "3044022052f4a3dc5ca3e86ed66abb1e2b4d9b9ace7d96f5615944beea19e58280847c2902201bd3ff32a38366a4eed0373e27da26ebc0d2a4c2bbeffd83e8a60e313d95b9e3"
        )

        # ---------------------------------------
        # Let's do second signature using 3rd key

        multisig = proto.MultisigRedeemScriptType(
            nodes=nodes,
            address_n=[0, 0],
            signatures=[
                signatures1[0],
                b"",
                b"",
            ],  # Fill signature from previous signing process
            m=2,
        )

        # Let's do a second signature with key 3
        inp3 = proto.TxInputType(
            address_n=parse_path("48'/0'/3'/0/0"),
            prev_hash=TXHASH_c6091a,
            prev_index=1,
            script_type=proto.InputScriptType.SPENDMULTISIG,
            multisig=multisig,
        )

        with client:
            client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXMETA,
                    details=proto.TxRequestDetailsType(tx_hash=TXHASH_c6091a),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0,
                                                       tx_hash=TXHASH_c6091a),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0,
                                                       tx_hash=TXHASH_c6091a),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1,
                                                       tx_hash=TXHASH_c6091a),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ])
            signatures2, serialized_tx = btc.sign_tx(client,
                                                     "Bitcoin", [inp3], [out1],
                                                     prev_txes=TX_API)

        assert (
            signatures2[0].hex() ==
            "304402203828fd48540811be6a1b12967e7012587c46e6f05c78d42471e7b25c06bc7afc0220749274bc1aa698335b00400c5ba946a70b6b46c711324fbc4989279737a57f49"
        )

        assert (
            serialized_tx.hex() ==
            "010000000152ba4dfcde9c4bed88f55479cdea03e711ae586e9a89352a98230c4cdf1a09c601000000fc00473044022052f4a3dc5ca3e86ed66abb1e2b4d9b9ace7d96f5615944beea19e58280847c2902201bd3ff32a38366a4eed0373e27da26ebc0d2a4c2bbeffd83e8a60e313d95b9e30147304402203828fd48540811be6a1b12967e7012587c46e6f05c78d42471e7b25c06bc7afc0220749274bc1aa698335b00400c5ba946a70b6b46c711324fbc4989279737a57f49014c6952210203ed6187880ae932660086e55d4561a57952dd200aa3ed2aa66b73e5723a0ce7210360e7f32fd3c8dee27a166f6614c598929699ee66acdcbda5fb24571bf2ae1ca021037c4c7e5d3293ab0f97771dcfdf83caadab341f427f54713da8b2c590a834f03b53aeffffffff01a0860100000000001976a91412e8391ad256dcdc023365978418d658dfecba1c88ac00000000"
        )
Exemple #47
0
def test_send_bch_multisig_wrongchange(client):
    nodes = [
        btc.get_public_node(
            client, parse_path(f"48'/145'/{i}'/0'"), coin_name="Bcash"
        ).node
        for i in range(1, 4)
    ]

    def getmultisig(chain, nr, signatures):
        return messages.MultisigRedeemScriptType(
            nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2
        )

    correcthorse = messages.HDNodeType(
        depth=1,
        fingerprint=0,
        child_num=0,
        chain_code=bytes.fromhex(
            "0000000000000000000000000000000000000000000000000000000000000000"
        ),
        public_key=bytes.fromhex(
            "0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71"
        ),
    )
    sig = bytes.fromhex(
        "304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae"
    )
    inp1 = messages.TxInputType(
        address_n=parse_path("48'/145'/1'/0'/1/0"),
        multisig=getmultisig(1, 0, [b"", sig, b""]),
        # bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a
        amount=24000,
        prev_hash=TXHASH_f68caf,
        prev_index=1,
        script_type=messages.InputScriptType.SPENDMULTISIG,
    )
    out1 = messages.TxOutputType(
        address_n=parse_path("48'/145'/1'/0'/1/1"),
        multisig=messages.MultisigRedeemScriptType(
            pubkeys=[
                messages.HDNodePathType(node=nodes[0], address_n=[1, 1]),
                messages.HDNodePathType(node=correcthorse, address_n=[]),
                messages.HDNodePathType(node=correcthorse, address_n=[]),
            ],
            signatures=[b"", b"", b""],
            m=2,
        ),
        script_type=messages.OutputScriptType.PAYTOMULTISIG,
        amount=23000,
    )
    with client:
        client.set_expected_responses(
            [
                request_input(0),
                request_output(0),
                messages.ButtonRequest(code=B.ConfirmOutput),
                messages.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_meta(TXHASH_f68caf),
                request_input(0, TXHASH_f68caf),
                request_output(0, TXHASH_f68caf),
                request_output(1, TXHASH_f68caf),
                request_input(0),
                request_output(0),
                request_finished(),
            ]
        )
        (signatures1, serialized_tx) = btc.sign_tx(
            client, "Bcash", [inp1], [out1], prev_txes=TX_API
        )
    assert (
        signatures1[0].hex()
        == "304402205ce02f7bf3ef225e4a17e2b5a98dc6ca5536a6b68088f94200390a1d505c4f3e022045657781095e01422736c5541b03b014101d76e54089eda030cb016dfce10e98"
    )
    assert (
        serialized_tx.hex()
        == "01000000015f3d291cae106548f3be5ed0f4cbedc65668fa881d60347ab0d512df10af8cf601000000fc0047304402205ce02f7bf3ef225e4a17e2b5a98dc6ca5536a6b68088f94200390a1d505c4f3e022045657781095e01422736c5541b03b014101d76e54089eda030cb016dfce10e984147304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae414c69522102962724052105f03332ab700812afc5ca665d264b13339be1fe7f7fdd3a2a685821024364cd1fdc2aa05bc8b09874a57aa1082a47ac9062d35f22ed5f4afefb3f67fc21024d375b44804f3b0c3493ea0806eb25cc85f51e0d616d6bd6e4ef0388e71cd29e53aeffffffff01d85900000000000017a9140d5566bfc721e6c3d5ab583841d387f3939ffed38700000000"
    )
    def test_ripple_sign_simple_tx(self):
        self.setup_mnemonic_allallall()

        msg = ripple.create_sign_tx_msg({
            "TransactionType": "Payment",
            "Payment": {
                "Amount": 100000000,
                "Destination": "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws",
            },
            "Flags": 0x80000000,
            "Fee": 100000,
            "Sequence": 25,
        })
        resp = ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/0"),
                              msg)
        assert (
            resp.signature.hex() ==
            "3045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c0"
        )
        assert (
            resp.serialized_tx.hex() ==
            "12000022800000002400000019614000000005f5e1006840000000000186a0732102131facd1eab748d6cddc492f54b04e8c35658894f4add2232ebc5afe7521dbe474473045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c081148fb40e1ffa5d557ce9851a535af94965e0dd098883147148ebebf7304ccdf1676fefcf9734cf1e780826"
        )

        msg = ripple.create_sign_tx_msg({
            "TransactionType": "Payment",
            "Payment": {
                "Amount": 1,
                "Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
            },
            "Fee": 10,
            "Sequence": 1,
        })
        resp = ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/2"),
                              msg)
        assert (
            resp.signature.hex() ==
            "3044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f"
        )
        assert (
            resp.serialized_tx.hex() ==
            "1200002280000000240000000161400000000000000168400000000000000a732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed274463044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988"
        )

        msg = ripple.create_sign_tx_msg({
            "TransactionType": "Payment",
            "Payment": {
                "Amount": 100000009,
                "Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
                "DestinationTag": 123456,
            },
            "Flags": 0,
            "Fee": 100,
            "Sequence": 100,
            "LastLedgerSequence": 333111,
        })
        resp = ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/2"),
                              msg)
        assert (
            resp.signature.hex() ==
            "30450221008770743a472bb2d1c746a53ef131cc17cc118d538ec910ca928d221db4494cf702201e4ef242d6c3bff110c3cc3897a471fed0f5ac10987ea57da63f98dfa01e94df"
        )
        assert (
            resp.serialized_tx.hex() ==
            "120000228000000024000000642e0001e240201b00051537614000000005f5e109684000000000000064732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed2744730450221008770743a472bb2d1c746a53ef131cc17cc118d538ec910ca928d221db4494cf702201e4ef242d6c3bff110c3cc3897a471fed0f5ac10987ea57da63f98dfa01e94df8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988"
        )
Exemple #49
0
def test_p2wpkh_with_proof(client):
    inp1 = proto.TxInputType(
        # seed "alcohol woman abuse must during monitor noble actual mixed trade anger aisle"
        # 84'/1'/0'/0/0
        # tb1qnspxpr2xj9s2jt6qlhuvdnxw6q55jvygcf89r2
        amount=100000,
        prev_hash=TXHASH_e5b7e2,
        prev_index=0,
        script_type=proto.InputScriptType.EXTERNAL,
        ownership_proof=bytearray.fromhex(
            "534c001900016b2055d8190244b2ed2d46513c40658a574d3bc2deb6969c0535bb818b44d2c40002483045022100d4ad0374c922848c71d913fba59c81b9075e0d33e884d953f0c4b4806b8ffd0c022024740e6717a2b6a5aa03148c3a28b02c713b4e30fc8aeae67fa69eb20e8ddcd9012103505f0d82bbdd251511591b34f36ad5eea37d3220c2b81a1189084431ddb3aa3d"
        ),
    )
    inp2 = proto.TxInputType(
        address_n=parse_path("84'/1'/0'/1/0"),
        amount=7289000,
        prev_hash=TXHASH_65b811,
        prev_index=1,
        script_type=proto.InputScriptType.SPENDWITNESS,
    )
    out1 = proto.TxOutputType(
        address="tb1q54un3q39sf7e7tlfq99d6ezys7qgc62a6rxllc",
        amount=1230000,
        script_type=proto.OutputScriptType.PAYTOADDRESS,
    )
    out2 = proto.TxOutputType(
        address="mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q",
        amount=100000 + 7289000 - 11000 - 1230000,
        script_type=proto.OutputScriptType.PAYTOADDRESS,
    )

    with client:
        client.set_expected_responses(
            [
                request_input(0),
                request_input(1),
                request_meta(TXHASH_65b811),
                request_input(0, TXHASH_65b811),
                request_output(0, TXHASH_65b811),
                request_output(1, TXHASH_65b811),
                request_output(0),
                proto.ButtonRequest(code=B.ConfirmOutput),
                request_output(1),
                proto.ButtonRequest(code=B.ConfirmOutput),
                proto.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_meta(TXHASH_e5b7e2),
                request_input(0, TXHASH_e5b7e2),
                request_output(0, TXHASH_e5b7e2),
                request_output(1, TXHASH_e5b7e2),
                request_input(0),
                request_input(1),
                request_output(0),
                request_output(1),
                request_input(1),
                request_finished(),
            ]
        )
        _, serialized_tx = btc.sign_tx(
            client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET,
        )

    assert (
        serialized_tx.hex()
        == "010000000001028abbd1cf69e00fbf60fa3ba475dccdbdba4a859ffa6bfd1ee820a75b1be2b7e50000000000ffffffff7b010c5faeb41cc5c253121b6bf69bf1a7c5867cd7f2d91569fea0ecd311b8650100000000ffffffff02b0c4120000000000160014a579388225827d9f2fe9014add644487808c695da0cf5d00000000001976a914a579388225827d9f2fe9014add644487808c695d88ac0002483045022100b17fe0eb21da96bdf9640bbe94f6198ff2ced183765753ee3d5119e661977cb20220121dfdc7a121afdcc08fae1389c7147a10bc58b2daea46799c6e6547c648ba1d012103505647c017ff2156eb6da20fae72173d3b681a1d0a629f95f49e884db300689f00000000"
    )

    # Test corrupted ownership proof.
    inp1.ownership_proof[10] ^= 1
    with pytest.raises(TrezorFailure, match="Invalid signature"):
        btc.sign_tx(
            client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET,
        )
    def test_opreturn(self, client):
        inp1 = proto.TxInputType(address_n=parse_path("44'/0'/0'/0/2"),
                                 prev_hash=TXHASH_d5f65e,
                                 prev_index=0)

        out1 = proto.TxOutputType(
            address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1",
            amount=390000 - 10000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        out2 = proto.TxOutputType(
            op_return_data=b"test of the op_return data",
            amount=0,
            script_type=proto.OutputScriptType.PAYTOOPRETURN,
        )

        with client:
            client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXMETA,
                    details=proto.TxRequestDetailsType(tx_hash=TXHASH_d5f65e),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0,
                                                       tx_hash=TXHASH_d5f65e),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=1,
                                                       tx_hash=TXHASH_d5f65e),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0,
                                                       tx_hash=TXHASH_d5f65e),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ])
            _, serialized_tx = btc.sign_tx(client,
                                           "Bitcoin", [inp1], [out1, out2],
                                           prev_txes=TX_API)

        assert (
            serialized_tx.hex() ==
            "010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b483045022100bc36e1227b334e856c532bbef86d30a96823a5f2461738f4dbf969dfbcf1b40b022078c5353ec9a4bce2bb05bd1ec466f2ab379c1aad926e208738407bba4e09784b012103330236b68aa6fdcaca0ea72e11b360c84ed19a338509aa527b678a7ec9076882ffffffff0260cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000000000001c6a1a74657374206f6620746865206f705f72657475726e206461746100000000"
        )
    def signTx(cls, tx):
        def int_to_big_endian(value):
            return value.to_bytes((value.bit_length() + 7) // 8, 'big')

        address_n = tools.parse_path(cls.hdpath())

        msg = proto.EthereumSignTx(address_n=address_n,
                                   nonce=int_to_big_endian(tx['nonce']),
                                   gas_price=int_to_big_endian(tx['gasPrice']),
                                   gas_limit=int_to_big_endian(tx['gas']),
                                   chain_id=int(tx['chainId']),
                                   value=int_to_big_endian(tx['value']))

        if tx['to']:
            msg.to = tx['to']

        data = None

        if tx['data'].__class__ is str:
            data = bytes.fromhex(tx['data'].replace('0x', ''))
        elif tx['data'].__class__ is bytes:
            data = tx['data']

        if data:
            msg.data_length = len(data)
            data, chunk = data[1024:], data[:1024]
            msg.data_initial_chunk = chunk

        try:
            response = cls.call_raw(msg, atomic=False)

            # Confused?   Ask trezor why.  I don't know why.
            # ButtonAck is a no-op afaict.  But you still have to send it.
            # Punch the monkey.
            # Punch it.
            # Punch the monkey.
            # Punch the monkey.
            # Punch the monkey.
            while response.__class__.__name__ == 'ButtonRequest':
                response = cls.call_raw(proto.ButtonAck())

            if response.__class__.__name__ == 'PinMatrixRequest':
                cls.matrix_request_window()
                raise SignTxError("Credstick needs to be unlocked")
            elif response.__class__.__name__ == 'PassphraseRequest':
                cls.passphrase_request_window()
                raise SignTxError("Credstick needs to be unlocked")
            elif response.__class__.__name__ == 'Failure':
                raise SignTxError

        except TransportException:
            raise SignTxError

        while response.data_length is not None:
            data_length = response.data_length
            data, chunk = data[data_length:], data[:data_length]
            response = cls.call_raw(proto.EthereumTxAck(data_chunk=chunk),
                                    atomic=False)

        # above, we were calling out with atomic=False to
        # prevent the session from being terminated.
        cls.transport.end_session()

        _v = response.signature_v
        _r = response.signature_r
        _s = response.signature_s

        sutx = serializable_unsigned_transaction_from_dict(tx)

        return cls.signed_tx(sutx, _v, int(_r.hex(), 16), int(_s.hex(), 16))
Exemple #52
0
def test_p2pkh_presigned(client):
    inp1 = proto.TxInputType(
        # mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q
        address_n=parse_path("m/44h/1h/0h/0/0"),
        prev_hash=TXHASH_e5040e,
        prev_index=0,
        # amount=31000000,
    )

    inp1ext = proto.TxInputType(
        # mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q
        # address_n=parse_path("m/44h/1h/0h/0/0"),
        prev_hash=TXHASH_e5040e,
        prev_index=0,
        amount=31000000,
        script_type=proto.InputScriptType.EXTERNAL,
        script_sig=bytes.fromhex(
            "473044022054fa66bfe1de1c850d59840f165143a66075bae78be3a6bc2809d1ac09431d380220019ecb086e16384f18cbae09b02bd2dce18763cd06454d33d93630561250965e0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
        ),
    )

    inp2 = proto.TxInputType(
        # mopZWqZZyQc3F2Sy33cvDtJchSAMsnLi7b
        address_n=parse_path("m/44h/1h/0h/0/1"),
        prev_hash=TXHASH_d830b8,
        prev_index=1,
        # amount=600000000,
    )

    inp2ext = proto.TxInputType(
        # mopZWqZZyQc3F2Sy33cvDtJchSAMsnLi7b
        # address_n=parse_path("m/44h/1h/0h/0/1"),
        prev_hash=TXHASH_d830b8,
        prev_index=1,
        amount=600000000,
        script_type=proto.InputScriptType.EXTERNAL,
        script_sig=bytearray.fromhex(
            "463043021f3a0a7fdf27b340358ddf8b4e6e3e6cc0be728d6f1d9d3413ae59741f57599002204809d59a9432a2c7fcb10639c5efa82935d8c3cc21b185ff5e44f0e1a80e635401210294e3e5e77e22eea0e4c0d30d89beb4db7f69b4bf1ae709e411d6a06618b8f852"
        ),
    )

    out1 = proto.TxOutputType(
        address="tb1qnspxpr2xj9s2jt6qlhuvdnxw6q55jvygcf89r2",
        amount=620000000,
        script_type=proto.OutputScriptType.PAYTOWITNESS,
    )

    out2 = proto.TxOutputType(
        address_n=parse_path("44h/1h/0h/1/0"),
        amount=31000000 + 600000000 - 620000000 - 10000,
        script_type=proto.OutputScriptType.PAYTOADDRESS,
    )

    # Test with first input as pre-signed external.
    with client:
        _, serialized_tx = btc.sign_tx(
            client,
            "Testnet",
            [inp1ext, inp2],
            [out1, out2],
            prev_txes=TX_CACHE_TESTNET,
        )

    expected_tx = "0100000002cd3b93f5b24ae190ce5141235091cd93fbb2908e24e5b9ff6776aec11b0e04e5000000006a473044022054fa66bfe1de1c850d59840f165143a66075bae78be3a6bc2809d1ac09431d380220019ecb086e16384f18cbae09b02bd2dce18763cd06454d33d93630561250965e0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff747b11157ff1d871f6d2efa282c21aa06d295a8288be680a7a23d9c377b830d80100000069463043021f3a0a7fdf27b340358ddf8b4e6e3e6cc0be728d6f1d9d3413ae59741f57599002204809d59a9432a2c7fcb10639c5efa82935d8c3cc21b185ff5e44f0e1a80e635401210294e3e5e77e22eea0e4c0d30d89beb4db7f69b4bf1ae709e411d6a06618b8f852ffffffff020073f424000000001600149c02608d469160a92f40fdf8c6ccced029493088b0b1a700000000001976a9143d3cca567e00a04819742b21a696a67da796498b88ac00000000"
    assert serialized_tx.hex() == expected_tx

    # Test with second input as pre-signed external.
    with client:
        _, serialized_tx = btc.sign_tx(
            client,
            "Testnet",
            [inp1, inp2ext],
            [out1, out2],
            prev_txes=TX_CACHE_TESTNET,
        )

    assert serialized_tx.hex() == expected_tx

    # Test corrupted signature in scriptsig.
    inp2ext.script_sig[10] ^= 1
    with pytest.raises(TrezorFailure, match="Invalid signature"):
        _, serialized_tx = btc.sign_tx(
            client,
            "Testnet",
            [inp1, inp2ext],
            [out1, out2],
            prev_txes=TX_CACHE_TESTNET,
        )
    def test_send_multisig_1(self, client):
        nodes = [
            btc.get_public_node(
                client, parse_path(f"49'/156'/{i}'"), coin_name="Bgold"
            ).node
            for i in range(1, 4)
        ]
        multisig = proto.MultisigRedeemScriptType(
            nodes=nodes, address_n=[1, 0], signatures=[b"", b"", b""], m=2
        )

        inp1 = proto.TxInputType(
            address_n=parse_path("49'/156'/1'/1/0"),
            prev_hash=TXHASH_25526b,
            prev_index=0,
            script_type=proto.InputScriptType.SPENDP2SHWITNESS,
            multisig=multisig,
            amount=1252382934,
        )

        out1 = proto.TxOutputType(
            address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
            amount=1252382934 - 1000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        with client:
            client.set_expected_responses(
                [
                    request_input(0),
                    request_meta(TXHASH_25526b),
                    request_input(0, TXHASH_25526b),
                    request_output(0, TXHASH_25526b),
                    request_output(1, TXHASH_25526b),
                    request_output(0),
                    proto.ButtonRequest(code=B.ConfirmOutput),
                    proto.ButtonRequest(code=B.SignTx),
                    request_input(0),
                    request_output(0),
                    request_input(0),
                    request_finished(),
                ]
            )
            signatures, _ = btc.sign_tx(
                client, "Bgold", [inp1], [out1], prev_txes=TX_API
            )
            # store signature
            inp1.multisig.signatures[0] = signatures[0]
            # sign with third key
            inp1.address_n[2] = H_(3)
            client.set_expected_responses(
                [
                    request_input(0),
                    request_meta(TXHASH_25526b),
                    request_input(0, TXHASH_25526b),
                    request_output(0, TXHASH_25526b),
                    request_output(1, TXHASH_25526b),
                    request_output(0),
                    proto.ButtonRequest(code=B.ConfirmOutput),
                    proto.ButtonRequest(code=B.SignTx),
                    request_input(0),
                    request_output(0),
                    request_input(0),
                    request_finished(),
                ]
            )
            _, serialized_tx = btc.sign_tx(
                client, "Bgold", [inp1], [out1], prev_txes=TX_API
            )

        assert (
            btc_hash(serialized_tx)[::-1].hex()
            == "efa5b21916ac7ea5316c38b2d7d5520d80cbe563c58304f956ea6ddb241001d1"
        )
    def test_show_multisig_xpubs(self, client):
        nodes = [
            btc.get_public_node(client,
                                tools.parse_path(f"48h/0h/{i}h"),
                                coin_name="Bitcoin") for i in range(3)
        ]
        multisig = messages.MultisigRedeemScriptType(
            nodes=[n.node for n in nodes],
            signatures=[b"", b"", b""],
            address_n=[0, 0],
            m=2,
        )

        xpubs = [[n.xpub[i * 16:(i + 1) * 16] for i in range(5)]
                 for n in nodes]

        for i in range(3):

            def input_flow():
                yield  # show address
                assert client.debug.wait_layout().lines == [
                    "Multisig 2 of 3",
                    "34yJV2b2GtbmxfZNw",
                    "jPyuyUYkUbUnogqa8",
                ]

                client.debug.press_no()
                yield  # show QR code
                assert client.debug.wait_layout().text.startswith("Qr")

                client.debug.press_no()
                yield  # show XPUB#1
                lines = client.debug.wait_layout().lines
                assert lines[0] == "XPUB #1 " + ("(yours)"
                                                 if i == 0 else "(others)")
                assert lines[1:] == xpubs[0]
                # just for UI test
                client.debug.swipe_up()

                client.debug.press_no()
                yield  # show XPUB#2
                lines = client.debug.wait_layout().lines
                assert lines[0] == "XPUB #2 " + ("(yours)"
                                                 if i == 1 else "(others)")
                assert lines[1:] == xpubs[1]
                # just for UI test
                client.debug.swipe_up()

                client.debug.press_no()
                yield  # show XPUB#3
                lines = client.debug.wait_layout().lines
                assert lines[0] == "XPUB #3 " + ("(yours)"
                                                 if i == 2 else "(others)")
                assert lines[1:] == xpubs[2]
                # just for UI test
                client.debug.swipe_up()

                client.debug.press_yes()

            with client:
                client.set_input_flow(input_flow)
                btc.get_address(
                    client,
                    "Bitcoin",
                    tools.parse_path(f"48h/0h/{i}h/0/0"),
                    show_display=True,
                    multisig=multisig,
                    script_type=messages.InputScriptType.SPENDMULTISIG,
                )
    def test_one_one_rewards_claim(self, client):
        # prevout: 7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1:0
        # input 1: 10.9997 KMD

        inp1 = proto.TxInputType(
            address_n=parse_path(
                "44'/141'/0'/0/0"),  # R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi
            amount=1099970000,
            prev_hash=TXHASH_7b28bd,
            prev_index=0,
        )

        out1 = proto.TxOutputType(
            address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi",
            amount=1099970000 - 10000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        # kmd interest, vout sum > vin sum
        out2 = proto.TxOutputType(
            address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi",
            amount=79605,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        with client:
            er = [
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
            ]
            if TREZOR_VERSION != 1:  # extra screen for lock_time
                er += [
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx)
                ]
            er += [
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ]
            client.set_expected_responses(er)

            details = proto.SignTx(
                version=4,
                overwintered=True,
                version_group_id=0x892F2085,
                branch_id=0x76B809BB,
                lock_time=0x5D2AF1F2,
            )
            _, serialized_tx = btc.sign_tx(
                client,
                "Komodo",
                [inp1],
                [out1, out2],
                details=details,
                prev_txes=TX_API,
            )

        # Accepted by network: tx c775678ceb18277729b427c7acf2f8ce63ac02fc2366f47ce08a3f443ff0e059
        assert (
            serialized_tx.hex() ==
            "0400008085202f8901b134cddb4951fe1acd7744bf9b828a816501570ed8ebd4f076979e1191bd287b000000006a4730440220483a58f5be3a147c773c663008c992a7fcea4d03bdf4c1d4bc0535c0d98ddf0602207b19d69140dd00c7a94f048c712aeaed55dfd27f581c7212d9cc5e476fe1dc9f012102a87aef7b1a8f676e452d6240767699719cd58b0261c822472c25df146938bca5ffffffff02c00e9041000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acf5360100000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acf2f12a5d000000000000000000000000000000"
        )
    def test_send_bch_multisig_change(self):
        self.setup_mnemonic_allallall()
        nodes = [
            btc.get_public_node(self.client,
                                parse_path("48'/145'/%d'" % i)).node
            for i in range(1, 4)
        ]

        def getmultisig(chain, nr, signatures=[b"", b"", b""], nodes=nodes):
            return proto.MultisigRedeemScriptType(nodes=nodes,
                                                  address_n=[chain, nr],
                                                  signatures=signatures,
                                                  m=2)

        inp1 = proto.TxInputType(
            address_n=parse_path("48'/145'/3'/0/0"),
            multisig=getmultisig(0, 0),
            amount=48490,
            prev_hash=bytes.fromhex(
                "8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0"
            ),
            prev_index=0,
            script_type=proto.InputScriptType.SPENDMULTISIG,
        )
        out1 = proto.TxOutputType(
            address="bitcoincash:qqq8gx2j76nw4dfefumxmdwvtf2tpsjznusgsmzex9",
            amount=24000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )
        out2 = proto.TxOutputType(
            address_n=parse_path("48'/145'/3'/1/0"),
            multisig=getmultisig(1, 0),
            script_type=proto.OutputScriptType.PAYTOMULTISIG,
            amount=24000,
        )
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ])
            (signatures1, serialized_tx) = btc.sign_tx(self.client,
                                                       "Bcash", [inp1],
                                                       [out1, out2],
                                                       prev_txes=TX_API)

        assert (
            signatures1[0].hex() ==
            "3045022100a05f77bb39515c21c43e6c4ba401f39ed5d409dc3cfcd90f9a8345a08cc4bc8202205faf8f3b0775748278495324fdd60f370460452e4995e546450209ec4804a0f3"
        )

        inp1 = proto.TxInputType(
            address_n=parse_path("48'/145'/1'/0/0"),
            multisig=getmultisig(0, 0, [b"", b"", signatures1[0]]),
            # bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw
            amount=48490,
            prev_hash=bytes.fromhex(
                "8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0"
            ),
            prev_index=0,
            script_type=proto.InputScriptType.SPENDMULTISIG,
        )
        out2.address_n[2] = H_(1)

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ])
            (signatures1, serialized_tx) = btc.sign_tx(self.client,
                                                       "Bcash", [inp1],
                                                       [out1, out2],
                                                       prev_txes=TX_API)

        assert (
            signatures1[0].hex() ==
            "3044022006f239ef1f065a70873ab9d2c81a623a04ec7a37a0ec5299d3c585668f441f49022032b2f9ef13bc61230d14f6d79b9ad1bbebdf47b95e4757e9af1b1dcdf520d3ab"
        )
        assert (
            serialized_tx.hex() ==
            "0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfd0000473044022006f239ef1f065a70873ab9d2c81a623a04ec7a37a0ec5299d3c585668f441f49022032b2f9ef13bc61230d14f6d79b9ad1bbebdf47b95e4757e9af1b1dcdf520d3ab41483045022100a05f77bb39515c21c43e6c4ba401f39ed5d409dc3cfcd90f9a8345a08cc4bc8202205faf8f3b0775748278495324fdd60f370460452e4995e546450209ec4804a0f3414c69522102f8ca0d9665af03de32a7c19a167a4f6e97e4e0ed9505f75d11f7a45ab60b1f4d2103263d87cefd687bc15b4ef7801f9f538267b66d46f18e9fccc41d54071cfdd1ce210388568bf42f02298308eb6fa2fa4b446d544600253b4409be27e2c0c1a71c424853aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a91478574751407449b97f8054be2e40e684ad07d3738700000000"
        )
    def test_one_one_fee_sapling(self, client):
        # prevout: 2807c5b126ec8e2b078cab0f12e4c8b4ce1d7724905f8ebef8dca26b0c8e0f1d:0
        # input 1: 10.9998 KMD

        inp1 = proto.TxInputType(
            address_n=parse_path(
                "44'/141'/0'/0/0"),  # R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi
            amount=1099980000,
            prev_hash=TXHASH_2807c,
            prev_index=0,
        )

        out1 = proto.TxOutputType(
            address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi",
            amount=1099980000 - 10000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        with client:
            er = [
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
            ]
            if TREZOR_VERSION != 1:  # extra screen for lock_time
                er += [
                    proto.ButtonRequest(code=proto.ButtonRequestType.SignTx)
                ]
            er += [
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ]

            client.set_expected_responses(er)

            details = proto.SignTx(
                version=4,
                overwintered=True,
                version_group_id=0x892F2085,
                branch_id=0x76B809BB,
                lock_time=0x5D2A30B8,
            )
            _, serialized_tx = btc.sign_tx(client,
                                           "Komodo", [inp1], [out1],
                                           details=details,
                                           prev_txes=TX_API)

        # Accepted by network: tx 7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1
        assert (
            serialized_tx.hex() ==
            "0400008085202f89011d0f8e0c6ba2dcf8be8e5f9024771dceb4c8e4120fab8c072b8eec26b1c50728000000006a4730440220158c970ca2fc6bcc33026eb5366f0342f63b35d178f7efb334b1df78fe90b67202207bc4ff69f67cf843b08564a5adc77bf5593e28ab4d5104911824ac13fe885d8f012102a87aef7b1a8f676e452d6240767699719cd58b0261c822472c25df146938bca5ffffffff01d0359041000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acb8302a5d000000000000000000000000000000"
        )
    def test_attack_amount(self):
        self.setup_mnemonic_allallall()
        inp1 = proto.TxInputType(
            address_n=parse_path("44'/145'/0'/1/0"),
            # bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
            amount=300,
            prev_hash=bytes.fromhex(
                "502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
            ),
            prev_index=0,
            script_type=proto.InputScriptType.SPENDADDRESS,
        )
        inp2 = proto.TxInputType(
            address_n=parse_path("44'/145'/0'/0/1"),
            # bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
            amount=70,
            prev_hash=bytes.fromhex(
                "502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c"
            ),
            prev_index=1,
            script_type=proto.InputScriptType.SPENDADDRESS,
        )
        out1 = proto.TxOutputType(
            address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4",
            amount=200,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        # test if passes without modifications
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
            ])
            btc.sign_tx(self.client,
                        "Bcash", [inp1, inp2], [out1],
                        prev_txes=TX_API)

        run_attack = True

        def attack_processor(msg):
            nonlocal run_attack

            if run_attack and msg.tx.inputs and msg.tx.inputs[0] == inp1:
                # 300 is lowered to 280 at the first run
                # the user confirms 280 but the transaction
                # is spending 300 => larger fee without the user knowing
                msg.tx.inputs[0].amount = 280
                run_attack = False

            return msg

        # now fails
        self.client.set_filter(proto.TxAck, attack_processor)
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.Failure(),
            ])

            with pytest.raises(CallException) as exc:
                btc.sign_tx(self.client,
                            "Bcash", [inp1, inp2], [out1],
                            prev_txes=TX_API)

            assert exc.value.args[0] in (
                proto.FailureType.ProcessError,
                proto.FailureType.DataError,
            )
            assert exc.value.args[1].endswith(
                "Transaction has changed during signing")
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.

import pytest

from trezorlib import eos
from trezorlib.messages import EosSignedTx
from trezorlib.tools import parse_path

from ..common import MNEMONIC12

CHAIN_ID = "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f"
ADDRESS_N = parse_path("m/44'/194'/0'/0/0")


@pytest.mark.altcoin
@pytest.mark.eos
@pytest.mark.skip_t1
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
class TestMsgEosSignTx:
    @pytest.mark.setup_client(uninitialized=True)
    def input_flow(self, debug, pages):
        # confirm number of actions
        yield
        debug.press_yes()

        # swipe through pages
        yield
    def test_attack_change_input(self):
        self.setup_mnemonic_allallall()
        inp1 = proto.TxInputType(
            address_n=parse_path("44'/145'/10'/0/0"),
            amount=1995344,
            prev_hash=bytes.fromhex(
                "bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78"
            ),
            prev_index=0,
            script_type=proto.InputScriptType.SPENDADDRESS,
        )
        out1 = proto.TxOutputType(
            address_n=parse_path("44'/145'/10'/1/0"),
            amount=1896050,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )
        out2 = proto.TxOutputType(
            address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4",
            amount=73452,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        run_attack = False

        def attack_processor(msg):
            nonlocal run_attack

            if msg.tx.inputs and msg.tx.inputs[0] == inp1:
                if not run_attack:
                    run_attack = True
                else:
                    msg.tx.inputs[0].address_n[2] = H_(1)

            return msg

        self.client.set_filter(proto.TxAck, attack_processor)

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.TxRequest(
                    request_type=proto.RequestType.TXOUTPUT,
                    details=proto.TxRequestDetailsType(request_index=1),
                ),
                proto.ButtonRequest(
                    code=proto.ButtonRequestType.ConfirmOutput),
                proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
                proto.TxRequest(
                    request_type=proto.RequestType.TXINPUT,
                    details=proto.TxRequestDetailsType(request_index=0),
                ),
                proto.Failure(code=proto.FailureType.ProcessError),
            ])
            with pytest.raises(CallException):
                btc.sign_tx(self.client,
                            "Bcash", [inp1], [out1, out2],
                            prev_txes=TX_API)