def test_invalid_language(self):
        self.setup_mnemonic_pin_passphrase()
        self.assertEqual(self.client.features.language, 'english')

        with self.client:
            self.client.set_expected_responses([
                proto.ButtonRequest(),
                proto.PinMatrixRequest(),
                proto.Success(),
                proto.Features()
            ])
            self.client.apply_settings(language='nonexistent')

        self.assertEqual(self.client.features.language, 'english')
 def test_entropy(self):
     for l in [
             0, 1, 2, 3, 4, 5, 8, 9, 16, 17, 32, 33, 64, 65, 128, 129, 256,
             257, 512, 513, 1024
     ]:
         with self.client:
             self.client.set_expected_responses([
                 proto.ButtonRequest(
                     code=proto_types.ButtonRequest_ProtectCall),
                 proto.Entropy()
             ])
             ent = self.client.get_entropy(l)
             self.assertTrue(len(ent) >= l)
             print('entropy = ', entropy(ent))
示例#3
0
    def test_p2sh(self):
        self.setup_mnemonic_nopin_nopassphrase()

        inp1 = proto_types.TxInputType(
            address_n=[0],  # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
            # amount=400000,
            prev_hash=binascii.unhexlify(
                '54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3'
            ),
            prev_index=1,
        )

        out1 = proto_types.TxOutputType(
            address='3DKGE1pvPpBAgZj94MbCinwmksewUNNYVR',  # p2sh
            amount=400000 - 10000,
            script_type=proto_types.PAYTOSCRIPTHASH,
        )

        with self.client:
            self.client.set_tx_api(TXAPIBitcoin())
            self.client.set_expected_responses([
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(request_type=proto_types.TXFINISHED)
            ])
            serialized_tx = self.client.simple_sign_tx('Bitcoin', [
                inp1,
            ], [
                out1,
            ])

        # Accepted by network: tx 8cc1f4adf7224ce855cf535a5104594a0004cb3b640d6714fdb00b9128832dd5
        self.assertEqual(
            binascii.hexlify(serialized_tx),
            '0100000001a3fb2d38322c3b327e54005cebc0686d52fcdf536e53bb5ef481a7de8056aa54010000006b4830450221009e020b0390ccad533b73b552f8a99a9d827212c558e4f755503674d07c92ad4502202d606f7316990e0461c51d4add25054f19c697aa3e3c2ced4d568f0b2c57e62f0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0170f305000000000017a9147f844bdb0b8fd54b64e3d16c85dc1170f1ff97c18700000000'
        )
    def test_send_native_change(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("49'/1'/0'/0/0"),
            # QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i
            amount=12300000,
            prev_hash=binascii.unhexlify('09144602765ce3dd8f4329445b20e3684e948709c5cdcaf12da3bb079c99448a'),
            prev_index=0,
            script_type=proto_types.SPENDWITNESS,
        )
        out1 = proto_types.TxOutputType(
            address='2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp',
            amount=5000000,
            script_type=proto_types.PAYTOADDRESS,
        )
        out2 = proto_types.TxOutputType(
            address_n=self.client.expand_path("49'/1'/0'/1/0"),
            script_type=proto_types.PAYTOWITNESS,
            amount=12300000 - 11000 - 5000000,
        )
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1, out2])

        self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001018a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090000000000ffffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014d16b8c0680c61fc6ed2e407455715055e41052f502483045022100a7ca8f097525f9044e64376dc0a0f5d4aeb8d15d66808ba97979a0475b06b66502200597c8ebcef63e047f9aeef1a8001d3560470cf896c12f6990eec4faec599b950121033add1f0e8e3c3136f7428dd4a4de1057380bd311f5b0856e2269170b4ffa65bf00000000')
    def test_send_p2sh_change(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("49'/1'/0'/1/0"),
            # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
            amount=123456789,
            prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'),
            prev_index=0,
            script_type=proto_types.SPENDP2SHWITNESS,
        )
        out1 = proto_types.TxOutputType(
            address='QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i',
            amount=12300000,
            script_type=proto_types.PAYTOADDRESS,
        )
        out2 = proto_types.TxOutputType(
            address_n=self.client.expand_path("49'/1'/0'/1/0"),
            script_type=proto_types.PAYTOP2SHWITNESS,
            amount=123456789 - 11000 - 12300000,
        )
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1, out2])

        self.assertEqual(binascii.hexlify(serialized_tx), b'0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001600140099a7ecbd938ed1839f5f6bf6d50933c6db9d5c3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100bd3d8b8ad35c094e01f6282277300e575f1021678fc63ec3f9945d6e35670da3022052e26ef0dd5f3741c9d5939d1dec5464c15ab5f2c85245e70a622df250d4eb7c012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000')
示例#6
0
    def test_spend_coinbase(self):
        # 25 TEST generated to m/1 (mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV)
        # tx: d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236
        # input 0: 25.0027823 BTC

        self.setup_mnemonic_nopin_nopassphrase()

        inp1 = proto_types.TxInputType(address_n=[1],  # mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV
                             # amount=390000,
                             prev_hash=binascii.unhexlify('d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236'),
                             prev_index=0,
                             )

        out1 = proto_types.TxOutputType(address='mm6FM31rM5Vc3sw5D7kztiBg3jHUzyqF1g',
                              amount=2500278230 - 10000,
                              script_type=proto_types.PAYTOADDRESS,
                              )

        with self.client:
            self.client.set_tx_api(TxApiTestnet)
            self.client.set_expected_responses([
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236"))),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify(b"d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify(b"d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1, ], [out1, ])

        # Accepted by network: tx
        self.assertEqual(binascii.hexlify(serialized_tx), b'010000000136825bfdb78c8ede226c7c4f25a018e99a2c061d63c7fb425fca7c7d6721dad6000000006a473044022047845c366eb24f40be315c7815a154513c444c7989eb80f7ce7ff6aeb703d26a022007c1f5efadf67c5889634fd7ac39a7ce78bffac291673e8772ecd8389c901d9f01210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6ffffffff01c6100795000000001976a9143d2496e67f5f57a924353da42d4725b318e7a8ea88ac00000000')
示例#7
0
    def test_one_one_fee(self):
        self.setup_mnemonic_nopin_nopassphrase()

        # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
        # input 0: 0.0039 BTC

        inp1 = proto_types.TxInputType(address_n=[0],  # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
                             # amount=390000,
                             prev_hash=binascii.unhexlify(b'd5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'),
                             prev_index=0,
                             )

        out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
                              amount=390000 - 10000,
                              script_type=proto_types.PAYTOADDRESS,
                              )

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify(b"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify(b"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify(b"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])

            (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])

        # Accepted by network: tx fd79435246dee76b2f159d2db08032d666c95adc544de64c8c49f474df4a7fee
        self.assertEqual(binascii.hexlify(serialized_tx), b'010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b4830450221009a0b7be0d4ed3146ee262b42202841834698bb3ee39c24e7437df208b8b7077102202b79ab1e7736219387dffe8d615bbdba87e11477104b867ef47afed1a5ede7810121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0160cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000')
示例#8
0
    def test_fee_too_high(self):
        self.setup_mnemonic_nopin_nopassphrase()

        # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
        # input 0: 0.0039 BTC

        inp1 = proto_types.TxInputType(address_n=[0],  # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
                             # amount=390000,
                             prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'),
                             prev_index=0,
                             )

        out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
                              amount=390000 - 250000,
                              script_type=proto_types.PAYTOADDRESS,
                              )

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify(b"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify(b"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify(b"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_FeeOverThreshold),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])

        self.assertEqual(binascii.hexlify(serialized_tx), b'010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b483045022100a3b17b37de3bfecca47f0d49f7bb0d0f68d45df7defe45713d57e83731f5e3d902205404b14630cea6a88b23a5f7c3a1b88494757a8ca5e1c0b0b93cf3c38231c3bd0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff01e0220200000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000')
示例#9
0
    def test_one_three_fee(self):
        self.setup_mnemonic_nopin_nopassphrase()

        # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
        # input 0: 0.0039 BTC

        inp1 = proto_types.TxInputType(address_n=[0],  # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
                             # amount=390000,
                             prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'),
                             prev_index=0,
                             )

        out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
                              amount=390000 - 80000 - 12000 - 10000,
                              script_type=proto_types.PAYTOADDRESS,
                              )

        out2 = proto_types.TxOutputType(address='13uaUYn6XAooo88QvAqAVsiVvr2mAXutqP',
                              amount=12000,
                              script_type=proto_types.PAYTOADDRESS,
                              )

        out3 = proto_types.TxOutputType(address_n=[1],
                              amount=80000,
                              script_type=proto_types.PAYTOADDRESS,
                              )

        with self.client:
            self.client.set_expected_responses([proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                                                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                                                # proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), # don't confirm change
                                                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                                                proto.TxRequest(request_type=proto_types.TXFINISHED)])
            serialized_tx = self.client.simple_sign_tx('Bitcoin', [inp1, ], [out1, out2, out3])

        self.assertEqual(binascii.hexlify(serialized_tx), '010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b483045022100e695e2c530c7c0fc32e6b79b7cff56a7f70a8c9da787534f46b4204070f914fc02207b0879a81408a11e23b11d4c7965c62b5fc6d5c2d92340f5ee2da7b40e99314a0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0300650400000000001976a914de9b2a8da088824e8fe51debea566617d851537888ace02e0000000000001976a9141fe1d337fb81afca42818051e12fd18245d1b17288ac80380100000000001976a9140223b1a09138753c9cb0baf95a0a62c82711567a88ac00000000')
示例#10
0
    def test_ping(self):
        self.setup_mnemonic_pin_passphrase()

        with self.client:
            self.client.set_expected_responses([proto.Success()])
            res = self.client.ping('random data')
            self.assertEqual(res, 'random data')

        with self.client:
            self.client.set_expected_responses([proto.ButtonRequest(code=proto_types.ButtonRequest_ProtectCall), proto.Success()])
            res = self.client.ping('random data', button_protection=True)
            self.assertEqual(res, 'random data')

        with self.client:
            self.client.set_expected_responses([proto.PinMatrixRequest(), proto.Success()])
            res = self.client.ping('random data', pin_protection=True)
            self.assertEqual(res, 'random data')

        with self.client:
            self.client.set_expected_responses([proto.PassphraseRequest(), proto.Success()])
            res = self.client.ping('random data', passphrase_protection=True)
            self.assertEqual(res, 'random data')
示例#11
0
    def test_load_device(self):
        with self.client:
            self.client.set_expected_responses(
                [proto.ButtonRequest(),
                 proto.Success(),
                 proto.Features()])
            self.client.load_device_by_mnemonic('this is mnemonic',
                                                '1234',
                                                True,
                                                'label',
                                                'english',
                                                skip_checksum=True)

        # This must fail, because device is already initialized
        self.assertRaises(Exception,
                          self.client.load_device_by_mnemonic,
                          'this is mnemonic',
                          '1234',
                          True,
                          'label',
                          'english',
                          skip_checksum=True)
示例#12
0
    def test_not_enough_funds(self):
        self.setup_mnemonic_nopin_nopassphrase()

        # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
        # input 0: 0.0039 BTC

        inp1 = proto_types.TxInputType(
            address_n=[0],  # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
            # amount=390000,
            prev_hash=binascii.unhexlify(
                'd5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'
            ),
            prev_index=0,
        )

        out1 = proto_types.TxOutputType(
            address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
            amount=400000,
            script_type=proto_types.PAYTOADDRESS,
        )

        with self.client:
            self.client.set_expected_responses([
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.Failure(code=proto_types.Failure_NotEnoughFunds)
            ])

            try:
                self.client.simple_sign_tx('Bitcoin', [
                    inp1,
                ], [
                    out1,
                ])
            except CallException as e:
                self.assertEqual(e.args[0], proto_types.Failure_NotEnoughFunds)
            else:
                self.assert_(False, "types.Failure_NotEnoughFunds expected")
示例#13
0
    def test_send_multisig_1(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        nodes = map(
            lambda index: self.client.get_public_node(
                self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
        multisig = proto_types.MultisigRedeemScriptType(
            pubkeys=map(
                lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub),
                                                     address_n=[2, 0]), nodes),
            signatures=[b'', b'', b''],
            m=2,
        )

        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("999'/1'/1'/2/0"),
            prev_hash=binascii.unhexlify(
                '9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be'
            ),
            prev_index=1,
            script_type=proto_types.SPENDP2SHWITNESS,
            multisig=multisig,
            amount=1610436)

        out1 = proto_types.TxOutputType(
            address='T7nZJt6QbGJy6Hok4EF2LqtJPcT7z7VFSrSysGS3tEqCfDPwizqy4',
            amount=1605000,
            script_type=proto_types.PAYTOADDRESS)

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
            # store signature
            inp1.multisig.signatures[0] = signatures1[0]
            # sign with third key
            inp1.address_n[2] = 0x80000003
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures2,
             serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])

        # f41cbedd8becee05a830f418d13aa665125464547db5c7a6cd28f21639fe1228
        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d180000000000220020c5f4a0a4ea7c0392efe0a9670a73264cffa90b19107cd8a8e9750ff93c77fdfb0400483045022100a9b681f324ff4cf419ab06820d07248cc4e359c77334bf448ae7b5cdf3995ddf022039811f91f55b602368b4ba08a217b82bfd62d1a97dc635deb1457e7cfcc1550b0147304402201ad86a795c3d26881d696fa0a0619c24c4d505718132a82965cc2a609c9d8798022067cd490ce1366cde77e307ced5b13040bbc04991619ea6f49e06cece9a83268b01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000'
        )
示例#14
0
    def test_attack_change_input_address(self):
        # This unit test attempts to modify input address after the Trezor checked
        # that it matches the change output

        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("49'/1'/0'/1/0"),
            # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
            amount=123456789,
            prev_hash=binascii.unhexlify(
                '20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'
            ),
            prev_index=0,
            script_type=proto_types.SPENDP2SHWITNESS,
        )
        out1 = proto_types.TxOutputType(
            address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
            amount=12300000,
            script_type=proto_types.PAYTOADDRESS,
        )
        out2 = proto_types.TxOutputType(
            address_n=self.client.expand_path("49'/1'/12345'/1/0"),
            script_type=proto_types.PAYTOP2SHWITNESS,
            amount=123456789 - 11000 - 12300000,
        )

        global run_attack
        run_attack = True

        def attack_processor(req, msg):
            import sys
            global run_attack

            if req.details.tx_hash != b'':
                return msg

            if req.request_type != proto_types.TXINPUT:
                return msg

            if req.details.request_index != 0:
                return msg

            if not run_attack:
                return msg

            msg.inputs[0].address_n[2] = 12345 + 0x80000000
            run_attack = False
            return msg

        # Test if the transaction can be signed normally
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures,
             serialized_tx) = self.client.sign_tx('Testnet', [inp1],
                                                  [out1, out2])

        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a914dae9e09a7fc3bbe5a716fffec1bbb340b82a4fb9870248304502210099b5c4f8fd4402c9c0136fee5f711137d64fc9f14587e01bfa7798f5428f845d0220253e21c98f5b1b64efae69bc2ea9799c5620a43450baa6762a0c3cf4fdc886e5012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000'
        )

        # Now run the attack, must trigger the exception
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.Failure(code=proto_types.Failure_ProcessError),
            ])
            self.assertRaises(CallException,
                              self.client.sign_tx,
                              'Testnet', [inp1], [out1, out2],
                              debug_processor=attack_processor)
示例#15
0
    def test_send_p2sh(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("49'/1'/0'/1/0"),
            # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
            amount=123456789,
            prev_hash=binascii.unhexlify(
                '20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'
            ),
            prev_index=0,
            script_type=proto_types.SPENDP2SHWITNESS,
        )
        out1 = proto_types.TxOutputType(
            address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
            amount=12300000,
            script_type=proto_types.PAYTOADDRESS,
        )
        out2 = proto_types.TxOutputType(
            address='2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX',
            script_type=proto_types.PAYTOADDRESS,
            amount=123456789 - 11000 - 12300000,
        )
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures,
             serialized_tx) = self.client.sign_tx('Testnet', [inp1],
                                                  [out1, out2])

        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000'
        )
示例#16
0
    def test_one_one_fee(self):
        self.setup_mnemonic_allallall()

        # tx: 93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c
        # input 0: 1.234567 TAZ

        inp1 = proto_types.TxInputType(
            address_n=[2147483692, 2147483649, 2147483648, 0,
                       0],  # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
            # amount=123456700,
            prev_hash=binascii.unhexlify(
                b'93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c'
            ),
            prev_index=0,
        )

        out1 = proto_types.TxOutputType(
            address='tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z',
            amount=123456700 - 1940,
            script_type=proto_types.PAYTOADDRESS,
        )

        with self.client:
            self.client.set_tx_api(TxApiZcashTestnet)
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXMETA,
                    details=proto_types.
                    TxRequestDetailsType(tx_hash=binascii.unhexlify(
                        b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"
                    ))),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(
                        request_index=0,
                        tx_hash=binascii.unhexlify(
                            b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"
                        ))),
                proto.TxRequest(
                    request_type=proto_types.TXEXTRADATA,
                    details=proto_types.
                    TxRequestDetailsType(tx_hash=binascii.unhexlify(
                        b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"
                    ),
                                         extra_data_offset=0,
                                         extra_data_len=1024)),
                proto.TxRequest(
                    request_type=proto_types.TXEXTRADATA,
                    details=proto_types.
                    TxRequestDetailsType(tx_hash=binascii.unhexlify(
                        b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"
                    ),
                                         extra_data_offset=1024,
                                         extra_data_len=1024)),
                proto.TxRequest(
                    request_type=proto_types.TXEXTRADATA,
                    details=proto_types.
                    TxRequestDetailsType(tx_hash=binascii.unhexlify(
                        b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"
                    ),
                                         extra_data_offset=2048,
                                         extra_data_len=1024)),
                proto.TxRequest(
                    request_type=proto_types.TXEXTRADATA,
                    details=proto_types.
                    TxRequestDetailsType(tx_hash=binascii.unhexlify(
                        b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"
                    ),
                                         extra_data_offset=3072,
                                         extra_data_len=629)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])

            (signatures,
             serialized_tx) = self.client.sign_tx('Zcash Testnet', [
                 inp1,
             ], [
                 out1,
             ])

        # Accepted by network: tx dcc2a10894e0e8a785c2afd4de2d958207329b9acc2b987fd768a09c5efc4547
        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'01000000015c2f725c959f9b0c66db42f185a9ebb51b51d675d79a047d4a6c62cc633e3793000000006a4730440220670b2b63d749a7038f9aea6ddf0302fe63bdcad93dafa4a89a1f0e7300ae2484022002c50af43fd867490cea0c527273c5828ff1b9a5115678f155a1830737cf29390121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff0128c55b07000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000'
        )
示例#17
0
    def test_send_multisig_1(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        nodes = map(
            lambda index: self.client.get_public_node(
                self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
        multisig = proto_types.MultisigRedeemScriptType(
            pubkeys=map(
                lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub),
                                                     address_n=[2, 0]), nodes),
            signatures=[b'', b'', b''],
            m=2,
        )

        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("999'/1'/1'/2/0"),
            prev_hash=binascii.unhexlify(
                '9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be'
            ),
            prev_index=1,
            script_type=proto_types.SPENDP2SHWITNESS,
            multisig=multisig,
            amount=1610436)

        out1 = proto_types.TxOutputType(
            address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
            amount=1605000,
            script_type=proto_types.PAYTOADDRESS)

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
            # store signature
            inp1.multisig.signatures[0] = signatures1[0]
            # sign with third key
            inp1.address_n[2] = 0x80000003
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures2,
             serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])

        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402205b44c20cf2681690edaaf7cd2e30d4704124dd8b7eb1fb7f459d3906c3c374a602205ca359b6544ce2c101c979899c782f7d141c3b0454ea69202b1fb4c09d3b715701473044022052fafa64022554ae436dbf781e550bf0d326fef31eea1438350b3ff1940a180102202851bd19203b7fe8582a9ef52e82aa9f61cd52d4bcedfe6dcc0cf782468e6a8e01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000'
        )
    def test_attack_change_input(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiBitcoinCash)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("44'/145'/1000'/0/0"),
            # 1MH9KKcvdCTY44xVDC2k3fjBbX5Cz29N1q
            amount=1995344,
            prev_hash=binascii.unhexlify(
                'bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78'
            ),
            prev_index=0,
            script_type=proto_types.SPENDADDRESS,
        )
        out1 = proto_types.TxOutputType(
            address_n=self.client.expand_path("44'/145'/1000'/1/0"),
            amount=1896050,
            script_type=proto_types.PAYTOADDRESS,
        )
        out2 = proto_types.TxOutputType(
            address='1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3',
            amount=73452,
            script_type=proto_types.PAYTOADDRESS,
        )

        global attack_ctr
        attack_ctr = 0

        def attack_processor(req, msg):
            import sys
            global attack_ctr

            if req.details.tx_hash != b'':
                return msg

            if req.request_type != proto_types.TXINPUT:
                return msg

            attack_ctr += 1
            if attack_ctr <= 1:
                return msg

            msg.inputs[0].address_n[2] = 1 + 0x80000000
            return msg

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.Failure(code=proto_types.Failure_ProcessError),
            ])
            self.assertRaises(CallException,
                              self.client.sign_tx,
                              'Bcash', [inp1], [out1, out2],
                              debug_processor=attack_processor)
    def test_signtx(self):
        self.setup_mnemonic_pin_passphrase()

        inp1 = proto_types.TxInputType(
            address_n=[0],  # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
            prev_hash=binascii.unhexlify(
                'd5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'
            ),
            prev_index=0,
        )

        out1 = proto_types.TxOutputType(
            address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
            amount=390000 - 10000,
            script_type=proto_types.PAYTOADDRESS,
        )

        with self.client:

            self.client.set_expected_responses([
                proto.PinMatrixRequest(),
                proto.PassphraseRequest(),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXMETA,
                    details=proto_types.
                    TxRequestDetailsType(tx_hash=binascii.unhexlify(
                        "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
                    ))),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(
                        request_index=0,
                        tx_hash=binascii.unhexlify(
                            "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
                        ))),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(
                        request_index=1,
                        tx_hash=binascii.unhexlify(
                            "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
                        ))),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(
                        request_index=0,
                        tx_hash=binascii.unhexlify(
                            "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
                        ))),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            self.client.sign_tx('Bitcoin', [
                inp1,
            ], [
                out1,
            ])
    def test_send_bch_multisig_wrongchange(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiBitcoinCash)
        xpubs = []
        for n in map(
                lambda index: self.client.get_public_node(
                    self.client.expand_path("44'/145'/" + str(index) + "'")),
                range(1, 4)):
            xpubs.append(n.xpub)

        def getmultisig(chain, nr, signatures=[b'', b'', b''], xpubs=xpubs):
            return proto_types.MultisigRedeemScriptType(
                pubkeys=map(
                    lambda xpub: proto_types.HDNodePathType(
                        node=deserialize(xpub), address_n=[chain, nr]), xpubs),
                signatures=signatures,
                m=2,
            )

        correcthorse = proto_types.HDNodeType(
            depth=1,
            fingerprint=0,
            child_num=0,
            chain_code=binascii.unhexlify(
                '0000000000000000000000000000000000000000000000000000000000000000'
            ),
            public_key=binascii.unhexlify(
                '0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71'
            ))
        sig = binascii.unhexlify(
            b'304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae'
        )
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("44'/145'/1'/1/0"),
            multisig=getmultisig(1, 0, [b'', sig, b'']),
            # 3CPtPpL5mGAPdxUeUDfm2RNdWoSN9dKpXE
            amount=24000,
            prev_hash=binascii.unhexlify(
                'f68caf10df12d5b07a34601d88fa6856c6edcbf4d05ebef3486510ae1c293d5f'
            ),
            prev_index=1,
            script_type=proto_types.SPENDMULTISIG,
        )
        out1 = proto_types.TxOutputType(
            address_n=self.client.expand_path("44'/145'/1'/1/1"),
            multisig=proto_types.MultisigRedeemScriptType(
                pubkeys=[
                    proto_types.HDNodePathType(node=deserialize(xpubs[0]),
                                               address_n=[1, 1]),
                    proto_types.HDNodePathType(node=correcthorse,
                                               address_n=[]),
                    proto_types.HDNodePathType(node=correcthorse, address_n=[])
                ],
                signatures=[b'', b'', b''],
                m=2,
            ),
            script_type=proto_types.PAYTOMULTISIG,
            amount=23000)
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures1,
             serialized_tx) = self.client.sign_tx('Bcash', [inp1], [out1])
        self.assertEqual(
            binascii.hexlify(signatures1[0]),
            b'3044022052ccf022b3684ecce9f961ce8828387b97267c86bedf0ce16a24bf014e62e42c022035d315ddbeeef7ab3456bd09aed8b625ea58852216b60e4b84ba9f85827d305c'
        )
        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'01000000015f3d291cae106548f3be5ed0f4cbedc65668fa881d60347ab0d512df10af8cf601000000fc00473044022052ccf022b3684ecce9f961ce8828387b97267c86bedf0ce16a24bf014e62e42c022035d315ddbeeef7ab3456bd09aed8b625ea58852216b60e4b84ba9f85827d305c4147304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae414c69522103d62b2af2272bbd67cbe30eeaf4226c7f2d57d2a0ed1aab5ab736fb40bb2f5ffe21036d5e0d7ca3589465711eec91436249d7234d3a994c219024fc75cec98fc02ae221024f58378a69b68e89301a6ff882116e0fa35446ec9bfd86532eeb05941ec1f8c853aeffffffff01d85900000000000017a9140bb11de6558871f49fc241341992ece9986f7c5c8700000000'
        )
    def test_send_both(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("49'/1'/0'/1/0"),
            # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
            amount=111145789,
            prev_hash=binascii.unhexlify('09144602765ce3dd8f4329445b20e3684e948709c5cdcaf12da3bb079c99448a'),
            prev_index=1,
            script_type=proto_types.SPENDP2SHWITNESS,
        )
        inp2 = proto_types.TxInputType(
            address_n=self.client.expand_path("49'/1'/0'/1/0"),
            # QWzGpyMkAEvmkSVprBzRRVQMP6UPp17q4kQn
            amount=7289000,
            prev_hash=binascii.unhexlify('65b811d3eca0fe6915d9f2d77c86c5a7f19bf66b1b1253c2c51cb4ae5f0c017b'),
            prev_index=1,
            script_type=proto_types.SPENDWITNESS,
        )
        out1 = proto_types.TxOutputType(
            address='QWzCpc1NeTN7hNDzK9sQQ9yrTQP8zh5Hef5J',
            amount=12300000,
            script_type=proto_types.PAYTOADDRESS,
        )
        out2 = proto_types.TxOutputType(
            # address_n=self.client.expand_path("44'/1'/0'/0/0"),
            # script_type=proto_types.PAYTOP2SHWITNESS,
            address='2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc',
            script_type=proto_types.PAYTOADDRESS,
            amount=45600000,
        )
        out3 = proto_types.TxOutputType(
            address='mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q',
            amount=111145789 + 7289000 - 11000 - 12300000 - 45600000,
            script_type=proto_types.PAYTOADDRESS,
        )

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=2)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=2)),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1, inp2], [out1, out2, out3])

        # 0e480a97c7a545c85e101a2f13c9af0e115d43734e1448f0cac3e55fe8e7399d
        self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001028a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090100000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff7b010c5faeb41cc5c253121b6bf69bf1a7c5867cd7f2d91569fea0ecd311b8650100000000ffffffff03e0aebb0000000000160014a579388225827d9f2fe9014add644487808c695d00cdb7020000000017a91491233e24a9bf8dbb19c1187ad876a9380c12e787870d859b03000000001976a914a579388225827d9f2fe9014add644487808c695d88ac02483045022100ead79ee134f25bb585b48aee6284a4bb14e07f03cc130253e83450d095515e5202201e161e9402c8b26b666f2b67e5b668a404ef7e57858ae9a6a68c3837e65fdc69012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7902483045022100b4099ec4c7b3123795b3c080a86f4b745f3784eb3f77de79bef1d8da319cbee5022039766865d448a4a3e435a95d0df3ff56ebc6532bf538988a7e8a679b40ec41b6012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000')
示例#22
0
    def test_send_multisig_4_change(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        nodes = map(
            lambda index: self.client.get_public_node(
                self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
        multisig = proto_types.MultisigRedeemScriptType(
            pubkeys=map(
                lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub),
                                                     address_n=[1, 1]), nodes),
            signatures=[b'', b'', b''],
            m=2,
        )
        multisig2 = proto_types.MultisigRedeemScriptType(
            pubkeys=map(
                lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub),
                                                     address_n=[1, 2]), nodes),
            signatures=[b'', b'', b''],
            m=2,
        )

        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("999'/1'/1'/1/1"),
            prev_hash=binascii.unhexlify(
                '31bc1c88ce6ae337a6b3057a16d5bad0b561ad1dfc047d0a7fbb8814668f91e5'
            ),
            prev_index=0,
            script_type=proto_types.SPENDP2SHWITNESS,
            multisig=multisig,
            amount=1603000)

        out1 = proto_types.TxOutputType(
            address_n=self.client.expand_path("999'/1'/1'/1/2"),
            amount=1602000,
            multisig=multisig2,
            script_type=proto_types.PAYTOWITNESS)

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
            # store signature
            inp1.multisig.signatures[0] = signatures1[0]
            # sign with third key
            inp1.address_n[2] = 0x80000003
            out1.address_n[2] = 0x80000003
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures2,
             serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])

        # c0bf56060a109624b4635222696d94a7d533cacea1b3f8245417a4348c045829
        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'01000000000101e5918f661488bb7f0a7d04fc1dad61b5d0bad5167a05b3a637e36ace881cbc3100000000232200205b9824093eaf5cdcf8247c00dc0b557a7720957828fcde8384ac11f80a91f403ffffffff01d071180000000000220020e77caf5fbef07b1e461475c02afd4aed877693263d69c81e14617304349b629a040047304402204832553b0da1009da496881e58e8e2e41010cfe5c0161623048093f1b1a817b7022020dad8bf887acf574af80bfe4b39cd24e95019fd5e6b8ae967471e21ddc67354014830450221009e5d60847e7275edcf4619ed8ee462c56a042eef75d17da2d44e6b13d78e50e50220665195492900ef87a5eb8a924fa0ac9afc4fc75ca704ff356dc3a213979970c80169522103f4040006e3561b3e76c6d4113225c84748ab9d55ffd23f9578ab4c18fb0c3b9721020975f2e6922897ff6b80da6412a8d6ebd67e33c9611d081656a53ef967964e5021026b0546f23a6ce6b756c2c30b4176ce6f1c3268744f7aca82668d5116c4f764e453ae00000000'
        )
    def test_send_bch_multisig_change(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiBitcoinCash)
        xpubs = []
        for n in map(
                lambda index: self.client.get_public_node(
                    self.client.expand_path("44'/145'/" + str(index) + "'")),
                range(1, 4)):
            xpubs.append(n.xpub)

        def getmultisig(chain, nr, signatures=[b'', b'', b''], xpubs=xpubs):
            return proto_types.MultisigRedeemScriptType(
                pubkeys=map(
                    lambda xpub: proto_types.HDNodePathType(
                        node=deserialize(xpub), address_n=[chain, nr]), xpubs),
                signatures=signatures,
                m=2,
            )

        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("44'/145'/3'/0/0"),
            multisig=getmultisig(0, 0),
            # 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R
            amount=48490,
            prev_hash=binascii.unhexlify(
                '8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0'
            ),
            prev_index=0,
            script_type=proto_types.SPENDMULTISIG,
        )
        out1 = proto_types.TxOutputType(
            address='113Q5hHQNQ3bc1RpPX6UNw4GAXstyeA3Dk',
            amount=24000,
            script_type=proto_types.PAYTOADDRESS,
        )
        out2 = proto_types.TxOutputType(
            address_n=self.client.expand_path("44'/145'/3'/1/0"),
            multisig=getmultisig(1, 0),
            script_type=proto_types.PAYTOMULTISIG,
            amount=24000)
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures1,
             serialized_tx) = self.client.sign_tx('Bcash', [inp1],
                                                  [out1, out2])

        self.assertEqual(
            binascii.hexlify(signatures1[0]),
            b'3045022100bcb1a7134a13025a06052546ee1c6ac3640a0abd2d130190ed13ed7fcb43e9cd02207c381478e2ee123c850425bfbf6d3c691230eb37e333832cb32a1ed3f2cd9e85'
        )

        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("44'/145'/1'/0/0"),
            multisig=getmultisig(0, 0, [b'', b'', signatures1[0]]),
            # 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R
            amount=48490,
            prev_hash=binascii.unhexlify(
                '8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0'
            ),
            prev_index=0,
            script_type=proto_types.SPENDMULTISIG,
        )
        out2.address_n[2] = 1 + 0x80000000

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures1,
             serialized_tx) = self.client.sign_tx('Bcash', [inp1],
                                                  [out1, out2])

        self.assertEqual(
            binascii.hexlify(signatures1[0]),
            b'3045022100f1153636371ba1f84389460e1265a8fa296569bc18e117c31f4e8f0fc0650c01022022932cc84766ff0c0f65ed9633ad311ae90d4c8fe71f5e1890b1e8f74dd516fa'
        )
        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfe0000483045022100f1153636371ba1f84389460e1265a8fa296569bc18e117c31f4e8f0fc0650c01022022932cc84766ff0c0f65ed9633ad311ae90d4c8fe71f5e1890b1e8f74dd516fa41483045022100bcb1a7134a13025a06052546ee1c6ac3640a0abd2d130190ed13ed7fcb43e9cd02207c381478e2ee123c850425bfbf6d3c691230eb37e333832cb32a1ed3f2cd9e85414c69522102fcf63419c319ce1a42d69120a3599d6da8c5dd4caf2888220eccde5a1ff7c5d021036d7d5ef79370b7fabe2c058698a20219e97fc70868e65ecdd6b37cc18e8a88bd2103505dc649dab8cd1655a4c0daf0ec5f955881c9d7011478ea881fac11cab1e49953aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a914756c06d7e77de3950a6124f026d8e1a2464b3ecf8700000000'
        )
示例#24
0
    def test_opreturn(self):
        self.setup_mnemonic_nopin_nopassphrase()

        # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
        # input 0: 0.0039 BTC

        inp1 = proto_types.TxInputType(
            address_n=[0],  # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
            # amount=390000,
            prev_hash=binascii.unhexlify(
                'd5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'
            ),
            prev_index=0,
        )

        out1 = proto_types.TxOutputType(
            address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
            amount=390000 - 10000,
            script_type=proto_types.PAYTOADDRESS,
        )

        out2 = proto_types.TxOutputType(
            op_return_data=b'test of the op_return data',
            amount=0,
            script_type=proto_types.PAYTOOPRETURN,
        )

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXMETA,
                    details=proto_types.
                    TxRequestDetailsType(tx_hash=binascii.unhexlify(
                        "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
                    ))),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(
                        request_index=0,
                        tx_hash=binascii.unhexlify(
                            "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
                        ))),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(
                        request_index=1,
                        tx_hash=binascii.unhexlify(
                            "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
                        ))),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(
                        request_index=0,
                        tx_hash=binascii.unhexlify(
                            "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
                        ))),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures,
             serialized_tx) = self.client.sign_tx('Bitcoin', [
                 inp1,
             ], [out1, out2])

        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006a4730440220187b7b9c340a32fc8445418ad11fb3827d2e8bac7d730e1c9ad800353e7ba62f02206c0c5820ba8882c82923a39aee8d36d6d32e13daed73f7a3d6199de5f8e7ddfd0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0260cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000000000001c6a1a74657374206f6620746865206f705f72657475726e206461746100000000'
        )
示例#25
0
 def test_get_entropy(self):
     with self.client:
         self.setup_mnemonic_pin_passphrase()
         self.client.set_expected_responses(
             [proto.ButtonRequest(), proto.Entropy()])
         self.client.get_entropy(10)
    def test_send_bch_nochange(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiBitcoinCash)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("44'/145'/0'/1/0"),
            # 1HADRPJpgqBzThepERpVXNi6qRgiLQRNoE
            amount=1896050,
            prev_hash=binascii.unhexlify(
                '502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'
            ),
            prev_index=0,
            script_type=proto_types.SPENDADDRESS,
        )
        inp2 = proto_types.TxInputType(
            address_n=self.client.expand_path("44'/145'/0'/0/1"),
            # 1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3
            amount=73452,
            prev_hash=binascii.unhexlify(
                '502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'
            ),
            prev_index=1,
            script_type=proto_types.SPENDADDRESS,
        )
        out1 = proto_types.TxOutputType(
            address='15pnEDZJo3ycPUamqP3tEDnEju1oW5fBCz',
            amount=1934960,
            script_type=proto_types.PAYTOADDRESS,
        )
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures,
             serialized_tx) = self.client.sign_tx('Bcash', [inp1, inp2],
                                                  [out1])

        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000'
        )
 def _responses(self, inp1, inp2, change=0):
     resp = [
         proto.TxRequest(
             request_type=proto_types.TXINPUT,
             details=proto_types.TxRequestDetailsType(request_index=0)),
         proto.TxRequest(request_type=proto_types.TXMETA,
                         details=proto_types.TxRequestDetailsType(
                             tx_hash=inp1.prev_hash)),
         proto.TxRequest(request_type=proto_types.TXINPUT,
                         details=proto_types.TxRequestDetailsType(
                             request_index=0, tx_hash=inp1.prev_hash)),
         proto.TxRequest(request_type=proto_types.TXOUTPUT,
                         details=proto_types.TxRequestDetailsType(
                             request_index=0, tx_hash=inp1.prev_hash)),
         proto.TxRequest(request_type=proto_types.TXOUTPUT,
                         details=proto_types.TxRequestDetailsType(
                             request_index=1, tx_hash=inp1.prev_hash)),
         proto.TxRequest(
             request_type=proto_types.TXINPUT,
             details=proto_types.TxRequestDetailsType(request_index=1)),
         proto.TxRequest(request_type=proto_types.TXMETA,
                         details=proto_types.TxRequestDetailsType(
                             tx_hash=inp2.prev_hash)),
         proto.TxRequest(request_type=proto_types.TXINPUT,
                         details=proto_types.TxRequestDetailsType(
                             request_index=0, tx_hash=inp2.prev_hash)),
         proto.TxRequest(request_type=proto_types.TXOUTPUT,
                         details=proto_types.TxRequestDetailsType(
                             request_index=0, tx_hash=inp2.prev_hash)),
         proto.TxRequest(request_type=proto_types.TXOUTPUT,
                         details=proto_types.TxRequestDetailsType(
                             request_index=1, tx_hash=inp2.prev_hash)),
         proto.TxRequest(
             request_type=proto_types.TXOUTPUT,
             details=proto_types.TxRequestDetailsType(request_index=0)),
     ]
     if change != 1:
         resp.append(
             proto.ButtonRequest(
                 code=proto_types.ButtonRequest_ConfirmOutput))
     resp.append(
         proto.TxRequest(
             request_type=proto_types.TXOUTPUT,
             details=proto_types.TxRequestDetailsType(request_index=1)))
     if change != 2:
         resp.append(
             proto.ButtonRequest(
                 code=proto_types.ButtonRequest_ConfirmOutput))
     resp += [
         proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
         proto.TxRequest(
             request_type=proto_types.TXINPUT,
             details=proto_types.TxRequestDetailsType(request_index=0)),
         proto.TxRequest(
             request_type=proto_types.TXINPUT,
             details=proto_types.TxRequestDetailsType(request_index=1)),
         proto.TxRequest(
             request_type=proto_types.TXOUTPUT,
             details=proto_types.TxRequestDetailsType(request_index=0)),
         proto.TxRequest(
             request_type=proto_types.TXOUTPUT,
             details=proto_types.TxRequestDetailsType(request_index=1)),
         proto.TxRequest(
             request_type=proto_types.TXINPUT,
             details=proto_types.TxRequestDetailsType(request_index=0)),
         proto.TxRequest(
             request_type=proto_types.TXINPUT,
             details=proto_types.TxRequestDetailsType(request_index=1)),
         proto.TxRequest(
             request_type=proto_types.TXOUTPUT,
             details=proto_types.TxRequestDetailsType(request_index=0)),
         proto.TxRequest(
             request_type=proto_types.TXOUTPUT,
             details=proto_types.TxRequestDetailsType(request_index=1)),
         proto.TxRequest(
             request_type=proto_types.TXOUTPUT,
             details=proto_types.TxRequestDetailsType(request_index=0)),
         proto.TxRequest(
             request_type=proto_types.TXOUTPUT,
             details=proto_types.TxRequestDetailsType(request_index=1)),
         proto.TxRequest(request_type=proto_types.TXFINISHED),
     ]
     return resp
示例#28
0
    def test_send_multisig_2(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        nodes = map(
            lambda index: self.client.get_public_node(
                self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
        multisig = proto_types.MultisigRedeemScriptType(
            pubkeys=map(
                lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub),
                                                     address_n=[2, 1]), nodes),
            signatures=[b'', b'', b''],
            m=2,
        )

        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("999'/1'/2'/2/1"),
            prev_hash=binascii.unhexlify(
                'f41cbedd8becee05a830f418d13aa665125464547db5c7a6cd28f21639fe1228'
            ),
            prev_index=0,
            script_type=proto_types.SPENDWITNESS,
            multisig=multisig,
            amount=1605000)

        out1 = proto_types.TxOutputType(
            address='T7nY3A3kewpDKumsdhonP4TBDfTXFSc2RNhZxkqmeeszRDHjM5yUn',
            amount=1604000,
            script_type=proto_types.PAYTOADDRESS)

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
            # store signature
            inp1.multisig.signatures[1] = signatures1[0]
            # sign with first key
            inp1.address_n[2] = 0x80000001
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures2,
             serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])

        # c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc
        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'010000000001012812fe3916f228cda6c7b57d5464541265a63ad118f430a805eeec8bddbe1cf40000000000ffffffff01a0791800000000002200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a10400483045022100cc97f21a7cabc543a9b4ac52424e8f7e420622903f2417a1c08a6af68058ec4a02200baca0b222fc825078d94e8e1b55f174c4828bed16697e4281cda2a0c799eecf01473044022009b8058dc30fa7a13310dd8f1a99c4341c4cd95f771c5a41c4381f956e2344c102205e829c560c0184fd4b4db8971f99711e2a87409afa4df0840b4f12a87b2c8afc0169522102740ec30d0af8591a0dd4a3e3b274e57f3f73bdc0638a9603f9ee6ade0475ba57210311aada919974e882abf0c67b5c0fba00000b26997312ca00345027d22359443021029382591271a79d4b12365fa27c67fad3753150d8eaa987e5a12dc5ba1bb2fa1653ae00000000'
        )
示例#29
0
    def test_2_of_3(self):
        self.setup_mnemonic_nopin_nopassphrase()

        #key1 = self.client.get_public_node([1])
        #key2 = self.client.get_public_node([2])
        #key3 = self.client.get_public_node([3])

        # xpub:
        # print(ckd_public.serialize(self.client.get_public_node([]).node))
        # xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy

        # pubkeys:
        #    xpub/1: 0338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6
        #    xpub/2: 038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3
        #    xpub/3: 03477b9f0f34ae85434ce795f0c5e1e90c9420e5b5fad084d7cce9a487b94a7902

        # redeem script:
        # 52210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a621038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e32103477b9f0f34ae85434ce795f0c5e1e90c9420e5b5fad084d7cce9a487b94a790253ae

        # multisig address: 3E7GDtuHqnqPmDgwH59pVC7AvySiSkbibz

        # tx: c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52
        # input 1: 0.001 BTC

        node = ckd_public.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy')

        multisig = proto_types.MultisigRedeemScriptType(
                            pubkeys=[proto_types.HDNodePathType(node=node, address_n=[1]),
                                     proto_types.HDNodePathType(node=node, address_n=[2]),
                                     proto_types.HDNodePathType(node=node, address_n=[3])],
                            signatures=[b'', b'', b''],
                            m=2,
                            )

        # Let's go to sign with key 1
        inp1 = proto_types.TxInputType(address_n=[1],
                             prev_hash=binascii.unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52'),
                             prev_index=1,
                             script_type=proto_types.SPENDMULTISIG,
                             multisig=multisig,
                             )

        out1 = proto_types.TxOutputType(address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss',
                              amount=100000,
                              script_type=proto_types.PAYTOADDRESS)

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"))),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])

            # Now we have first signature
            (signatures1, _) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])

        self.assertEqual(binascii.hexlify(signatures1[0]), b'3045022100985cc1ba316d140eb4b2d4028d8cd1c451f87bff8ff679858732e516ad04cd3402207af6edda99972af0baa7702a3b7448517c8242e7bca669f6861771cdd16ee058')

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

        multisig = proto_types.MultisigRedeemScriptType(
                            pubkeys=[proto_types.HDNodePathType(node=node, address_n=[1]),
                                     proto_types.HDNodePathType(node=node, address_n=[2]),
                                     proto_types.HDNodePathType(node=node, address_n=[3])],
                            signatures=[signatures1[0], b'', b''], # Fill signature from previous signing process
                            m=2,
                            )

        # Let's do a second signature with key 3
        inp3 = proto_types.TxInputType(address_n=[3],
                 prev_hash=binascii.unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52'),
                 prev_index=1,
                 script_type=proto_types.SPENDMULTISIG,
                 multisig=multisig,
                 )

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"))),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures2, serialized_tx) = self.client.sign_tx('Bitcoin', [inp3, ], [out1, ])

        self.assertEqual(binascii.hexlify(signatures2[0]), b'3045022100f5428fe0531b3095675b40d87cab607ee036fac823b22e8dcec35b65aff6e52b022032129b4577ff923d321a1c70db5a6cec5bcc142cb2c51901af8b989cced23e0d')

        # Accepted by network: tx 8382a2b2e3ec8788800c1d46d285dfa9dd4051edddd75982fad166b9273e5ac6
        self.assertEqual(binascii.hexlify(serialized_tx), b'010000000152ba4dfcde9c4bed88f55479cdea03e711ae586e9a89352a98230c4cdf1a09c601000000fdfe0000483045022100985cc1ba316d140eb4b2d4028d8cd1c451f87bff8ff679858732e516ad04cd3402207af6edda99972af0baa7702a3b7448517c8242e7bca669f6861771cdd16ee05801483045022100f5428fe0531b3095675b40d87cab607ee036fac823b22e8dcec35b65aff6e52b022032129b4577ff923d321a1c70db5a6cec5bcc142cb2c51901af8b989cced23e0d014c6952210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a621038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e32103477b9f0f34ae85434ce795f0c5e1e90c9420e5b5fad084d7cce9a487b94a790253aeffffffff01a0860100000000001976a91412e8391ad256dcdc023365978418d658dfecba1c88ac00000000')
示例#30
0
    def test_send_multisig_3_change(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        nodes = map(
            lambda index: self.client.get_public_node(
                self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
        multisig = proto_types.MultisigRedeemScriptType(
            pubkeys=map(
                lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub),
                                                     address_n=[2, 0]), nodes),
            signatures=[b'', b'', b''],
            m=2,
        )
        multisig2 = proto_types.MultisigRedeemScriptType(
            pubkeys=map(
                lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub),
                                                     address_n=[1, 1]), nodes),
            signatures=[b'', b'', b''],
            m=2,
        )

        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("999'/1'/1'/2/0"),
            prev_hash=binascii.unhexlify(
                'c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc'
            ),
            prev_index=0,
            script_type=proto_types.SPENDWITNESS,
            multisig=multisig,
            amount=1604000)

        out1 = proto_types.TxOutputType(
            address_n=self.client.expand_path("999'/1'/1'/1/1"),
            amount=1603000,
            multisig=multisig2,
            script_type=proto_types.PAYTOP2SHWITNESS)

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
            # store signature
            inp1.multisig.signatures[0] = signatures1[0]
            # sign with third key
            inp1.address_n[2] = 0x80000003
            out1.address_n[2] = 0x80000003
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures2,
             serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])

        # 31bc1c88ce6ae337a6b3057a16d5bad0b561ad1dfc047d0a7fbb8814668f91e5
        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'01000000000101fc7901dd033f8c02da14f3ac916b6498036b80b4a0b4dc124e02c2bb408034c90000000000ffffffff01b87518000000000017a914a8655acf68f785125561158b0f4db9b5d0044047870400473044022057b571986c07f8ccb231811334ad06ee6f87b722495def2e9511c1da46f3433202207b6e95bdd99e7fc7d319486437cb930d40a4af3cd753c4cb960b330badbf7f35014730440220517ecc6d0a2544276921d8fc2077aec4285ab83b1b21f5eb73cdb6187a0583e4022043fb5ab942f8981c04a54c66a57c4d291fad8514d4a8afea09f01f2db7a8f32901695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000'
        )