def test_show_multisig_3(self): self.setup_mnemonic_allallall() nodes = map( lambda index: btc.get_public_node( self.client, parse_path("999'/1'/%d'" % index) ), range(1, 4), ) multisig1 = proto.MultisigRedeemScriptType( nodes=[bip32.deserialize(n.xpub) for n in nodes], address_n=[2, 0], signatures=[b"", b"", b""], m=2, ) # multisig2 = proto.MultisigRedeemScriptType( # pubkeys=map(lambda n: proto.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 1]), nodes), # signatures=[b'', b'', b''], # m=2, # ) for i in [1, 2, 3]: assert ( btc.get_address( self.client, "Testnet", parse_path("999'/1'/%d'/2/0" % i), False, multisig1, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N2MxyAfifVhb3AMagisxaj3uij8bfXqf4Y" )
def test_multisig(self): self.setup_mnemonic_allallall() xpubs = [] for n in range(1, 4): node = btc.get_public_node(self.client, parse_path("44'/0'/%d'" % n)) xpubs.append(node.xpub) for nr in range(1, 4): assert ( btc.get_address( self.client, "Bitcoin", parse_path("44'/0'/%d'/0/0" % nr), show_display=(nr == 1), multisig=getmultisig(0, 0, xpubs=xpubs), ) == "3Pdz86KtfJBuHLcSv4DysJo4aQfanTqCzG" ) assert ( btc.get_address( self.client, "Bitcoin", parse_path("44'/0'/%d'/1/0" % nr), show_display=(nr == 1), multisig=getmultisig(1, 0, xpubs=xpubs), ) == "36gP3KVx1ooStZ9quZDXbAF3GCr42b2zzd" )
def test_bch_multisig(self): self.setup_mnemonic_allallall() xpubs = [] for n in range(1, 4): node = btc.get_public_node(self.client, parse_path("44'/145'/%d'" % n)) xpubs.append(node.xpub) for nr in range(1, 4): assert ( btc.get_address( self.client, "Bcash", parse_path("44'/145'/%d'/0/0" % nr), show_display=(nr == 1), multisig=getmultisig(0, 0, xpubs=xpubs), ) == "bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw" ) assert ( btc.get_address( self.client, "Bcash", parse_path("44'/145'/%d'/1/0" % nr), show_display=(nr == 1), multisig=getmultisig(1, 0, xpubs=xpubs), ) == "bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a" )
def test_multisig_missing(self): self.setup_mnemonic_allallall() xpubs = [] for n in range(1, 4): # shift account numbers by 10 to create valid multisig, # but not containing the keys used below n = n + 10 node = btc.get_public_node(self.client, parse_path("44'/0'/%d'" % n)) xpubs.append(node.xpub) for nr in range(1, 4): with pytest.raises(CallException): btc.get_address( self.client, "Bitcoin", parse_path("44'/0'/%d'/0/0" % nr), show_display=(nr == 1), multisig=getmultisig(0, 0, xpubs=xpubs), ) with pytest.raises(CallException): btc.get_address( self.client, "Bitcoin", parse_path("44'/0'/%d'/1/0" % nr), show_display=(nr == 1), multisig=getmultisig(1, 0, xpubs=xpubs), )
def test_testnet_one_two_fee(self): self.setup_mnemonic_allallall() # see 87be0736f202f7c2bff0781b42bad3e0cdcb54761939da69ea793a3735552c56 # tx: e5040e1bc1ae7667ffb9e5248e90b2fb93cd9150234151ce90e14ab2f5933bcd # input 0: 0.31 BTC inp1 = proto.TxInputType( address_n=parse_path("44'/1'/0'/0/0"), # amount=31000000, prev_hash=TXHASH_e5040e, prev_index=0, ) out1 = proto.TxOutputType( address="msj42CCGruhRsFrGATiUuh25dtxYtnpbTx", amount=30090000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address_n=parse_path("44'/1'/0'/1/0"), amount=900000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) _, serialized_tx = check_sign_tx(self.client, "Testnet", [inp1], [out1, out2]) assert ( serialized_tx.hex() == "0100000001cd3b93f5b24ae190ce5141235091cd93fbb2908e24e5b9ff6776aec11b0e04e5000000006b483045022100eba3bbcbb82ab1ebac88a394e8fb53b0263dadbb3e8072f0a21ee62818c911060220686a9b7f306d028b54a228b5c47cc6c27b1d01a3b0770440bcc64d55d8bace2c0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff021023cb01000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288aca0bb0d00000000001976a9143d3cca567e00a04819742b21a696a67da796498b88ac00000000" )
def test_one_two_fee(self): self.setup_mnemonic_allallall() # tx: c275c333fd1b36bef4af316226c66a8b3693fbfcc081a5e16a2ae5fcb09e92bf inp1 = proto.TxInputType( address_n=parse_path( "m/44'/0'/0'/0/5" ), # 1GA9u9TfCG7SWmKCveBumdA1TZpfom6ZdJ # amount=50000, prev_hash=TXHASH_50f6f1, prev_index=1, ) out1 = proto.TxOutputType( address_n=parse_path( "m/44'/0'/0'/1/3" ), # 1EcL6AyfQTyWKGvXwNSfsWoYnD3whzVFdu amount=30000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="1Up15Msx4sbvUCGm8Xgo2Zp5FQim3wE59", amount=10000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) _, serialized_tx = check_sign_tx(self.client, "Bitcoin", [inp1], [out1, out2]) assert ( serialized_tx.hex() == "01000000016d20f69067ad1ffd50ee7c0f377dde2c932ccb03e84b5659732da99c20f1f650010000006a47304402203429bd3ce7b38c5c1e8a15340edd79ced41a2939aae62e259d2e3d18e0c5ee7602201b83b10ebc4d6dcee3f9eb42ba8f1ef8a059a05397e0c1b9223d1565a3e6ec01012102a7a079c1ef9916b289c2ff21a992c808d0de3dfcf8a9f163205c5c9e21f55d5cffffffff0230750000000000001976a914954820f1de627a703596ac0396f986d958e3de4c88ac10270000000000001976a91405427736705cfbfaff76b1cff48283707fb1037088ac00000000" )
def test_monero_getwatchkey(self): self.setup_mnemonic_nopin_nopassphrase() res = monero.get_watch_key(self.client, parse_path("m/44h/128h/0h")) assert ( res.address == b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM" ) assert ( res.watch_key.hex() == "8722520a581e2a50cc1adab4a1692401effd37b0d63b9d9b60fd7f34ea2b950e" ) res = monero.get_watch_key(self.client, parse_path("m/44h/128h/1h")) assert ( res.address == b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie" ) assert ( res.watch_key.hex() == "1f70b7d9e86c11b7a5bee883b75c43d6be189c8f812726ea1ecd94b06bb7db04" ) res = monero.get_watch_key(self.client, parse_path("m/44h/128h/2h")) assert ( res.address == b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH" ) assert ( res.watch_key.hex() == "e0671fbed2c9231fe4f286962862813a4a4d153c793bf5d0e3742119723f3000" )
def test_timestamp_included(client): # tx: 3bf506c81ce84eda891679ddc797d162c17c60b15d6c0ac23be5e31369e7235f # input 0: 0.01 CPC # tx: f3a6e6411f1b2dffd76d2729bae8e056f8f9ecf8996d3f428e75a6f23f2c5e8c # input 0: 0.02 CPC inp1 = messages.TxInputType( address_n=parse_path("m/44'/289'/0'/0/0"), prev_hash=TXHASH_3bf506, prev_index=0 ) inp2 = messages.TxInputType( address_n=parse_path("m/44'/289'/0'/0/0"), prev_hash=TXHASH_f3a6e6, prev_index=1 ) out1 = messages.TxOutputType( address="CUGi8RGPWxbHM6FxF4eMEfqmQ6Bs5VjCdr", amount=3000000 - 20000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) with client: details = messages.SignTx(version=1, timestamp=0x5BCF5C66) _, timestamp_tx = btc.sign_tx( client, "Capricoin", [inp1, inp2], [out1], details=details, prev_txes=tx_cache("Capricoin"), ) # Accepted by network https://insight.capricoin.org/tx/1bf227e6e24fe1f8ac98849fe06a2c5b77762e906fcf7e82787675f7f3a10bb8 accepted_txhex = "01000000665ccf5b025f23e76913e3e53bc20a6c5db1607cc162d197c7dd791689da4ee81cc806f53b000000006b483045022100fce7ccbeb9524f36d118ebcfebcb133a05c236c4478e2051cfd5c9632920aee602206921b7be1a81f30cce3d8e7dba4597fc16a2761c42321c49d65eeacdfe3781250121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff8c5e2c3ff2a6758e423f6d99f8ecf9f856e0e8ba29276dd7ff2d1b1f41e6a6f3010000006a473044022015d967166fe9f89fbed8747328b1c4658aa1d7163e731c5fd5908feafe08e9a6022028af30801098418bd298cc60b143c52c48466f5791256721304b6eba4fdf0b3c0121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff01a0782d00000000001976a914818437acfd15780debd31f3fd21d4ca678bb36d188ac00000000" assert timestamp_tx.hex() == accepted_txhex
def test_change_on_main_chain_allowed(self): self.setup_mnemonic_allallall() # see 87be0736f202f7c2bff0781b42bad3e0cdcb54761939da69ea793a3735552c56 # tx: e5040e1bc1ae7667ffb9e5248e90b2fb93cd9150234151ce90e14ab2f5933bcd # input 0: 0.31 BTC inp1 = proto.TxInputType( address_n=parse_path("44'/1'/0'/0/0"), # amount=31000000, prev_hash=TXHASH_e5040e, prev_index=0, ) out1 = proto.TxOutputType( address="msj42CCGruhRsFrGATiUuh25dtxYtnpbTx", amount=30090000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) # change on main chain is allowed => treated as a change out_change = proto.TxOutputType( address_n=parse_path("44'/1'/0'/0/0"), amount=900000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) check_sign_tx(self.client, "Testnet", [inp1], [out1, out_change])
def test_ethereum_signtx_nodata(self): self.setup_mnemonic_nopin_nopassphrase() with self.client: self.client.set_expected_responses( [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.EthereumTxRequest(data_length=None), # v,r,s checked later ] ) sig_v, sig_r, sig_s = ethereum.sign_tx( self.client, n=parse_path("44'/60'/0'/0/100"), nonce=0, gas_price=20, gas_limit=20, to=TO_ADDR, value=10, ) assert sig_v == 27 assert ( sig_r.hex() == "2f548f63ddb4cf19b6b9f922da58ff71833b967d590f3b4dcc2a70810338a982" ) assert ( sig_s.hex() == "428d35f0dca963b5196b63e7aa5e0405d8bff77d6aee1202183f1f68dacb4483" ) with self.client: self.client.set_expected_responses( [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.EthereumTxRequest(data_length=None), ] ) sig_v, sig_r, sig_s = ethereum.sign_tx( self.client, n=parse_path("44'/60'/0'/0/100"), nonce=123456, gas_price=20000, gas_limit=20000, to=TO_ADDR, value=12345678901234567890, ) assert sig_v == 27 assert ( sig_r.hex() == "3bf0470cd7f5ad8d82613199f73deadc55c3c9f32f91b1a21b5ef644144ebd58" ) assert ( sig_s.hex() == "48b3ef1b2502febdf35e9ff4df0ba1fda62f042fad639eb4852a297fc9872ebd" )
def test_show_segwit(self): self.setup_mnemonic_allallall() assert ( btc.get_address( self.client, "Testnet", parse_path("49'/1'/0'/0/0"), True, None, script_type=proto.InputScriptType.SPENDWITNESS, ) == "tb1qqzv60m9ajw8drqulta4ld4gfx0rdh82un5s65s" ) assert ( btc.get_address( self.client, "Testnet", parse_path("49'/1'/0'/1/0"), False, None, script_type=proto.InputScriptType.SPENDWITNESS, ) == "tb1q694ccp5qcc0udmfwgp692u2s2hjpq5h407urtu" ) assert ( btc.get_address( self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDWITNESS, ) == "tb1q54un3q39sf7e7tlfq99d6ezys7qgc62a6rxllc" ) assert ( btc.get_address( self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDADDRESS, ) == "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q" ) assert ( btc.get_address( self.client, "Groestlcoin", parse_path("84'/17'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDWITNESS, ) == "grs1qw4teyraux2s77nhjdwh9ar8rl9dt7zww8r6lne" )
def test_show_segwit(self): self.setup_mnemonic_allallall() assert ( btc.get_address( self.client, "Testnet", parse_path("49'/1'/0'/1/0"), True, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX" ) assert ( btc.get_address( self.client, "Testnet", parse_path("49'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp" ) assert ( btc.get_address( self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc" ) assert ( btc.get_address( self.client, "Testnet", parse_path("44'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDADDRESS, ) == "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q" ) assert ( btc.get_address( self.client, "Groestlcoin Testnet", parse_path("49'/1'/0'/0/0"), False, None, script_type=proto.InputScriptType.SPENDP2SHWITNESS, ) == "2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e" )
def test_tezos_get_address(self): self.setup_mnemonic_allallall() path = parse_path("m/44'/1729'/0'") address = get_address(self.client, path, show_display=True) assert address == "tz1Kef7BSg6fo75jk37WkKRYSnJDs69KVqt9" path = parse_path("m/44'/1729'/1'") address = get_address(self.client, path, show_display=True) assert address == "tz1ekQapZCX4AXxTJhJZhroDKDYLHDHegvm1"
def test_tezos_get_public_key(self): self.setup_mnemonic_allallall() path = parse_path("m/44'/1729'/0'") pk = get_public_key(self.client, path) assert pk == "edpkttLhEbVfMC3DhyVVFzdwh8ncRnEWiLD1x8TAuPU7vSJak7RtBX" path = parse_path("m/44'/1729'/1'") pk = get_public_key(self.client, path) assert pk == "edpkuTPqWjcApwyD3VdJhviKM5C13zGk8c4m87crgFarQboF3Mp56f"
def test_nem_getaddress(self): self.setup_mnemonic_nopin_nopassphrase() assert ( nem.get_address(self.client, parse_path("m/44'/1'/0'/0'/0'"), 0x68) == "NB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQGHUBWQN" ) assert ( nem.get_address(self.client, parse_path("m/44'/1'/0'/0'/0'"), 0x98) == "TB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQHSBNBMF" )
def test_ripple_get_address(self): # data from https://iancoleman.io/bip39/#english self.setup_mnemonic_allallall() address = get_address(self.client, parse_path("m/44'/144'/0'/0/0")) assert address == "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H" address = get_address(self.client, parse_path("m/44'/144'/0'/0/1")) assert address == "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws" address = get_address(self.client, parse_path("m/44'/144'/1'/0/0")) assert address == "rJX2KwzaLJDyFhhtXKi3htaLfaUH2tptEX"
def test_ethereum_signtx_newcontract(self): self.setup_mnemonic_allallall() # contract creation without data should fail. with pytest.raises(Exception): ethereum.sign_tx( self.client, n=parse_path("44'/60'/0'/0/0"), nonce=123456, gas_price=20000, gas_limit=20000, to="", value=12345678901234567890, ) with self.client: self.client.set_expected_responses( [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.EthereumTxRequest( data_length=1024, signature_r=None, signature_s=None, signature_v=None, ), proto.EthereumTxRequest(data_length=1024), proto.EthereumTxRequest(data_length=1024), proto.EthereumTxRequest(data_length=3), proto.EthereumTxRequest(), ] ) sig_v, sig_r, sig_s = ethereum.sign_tx( self.client, n=parse_path("44'/60'/0'/0/0"), nonce=0, gas_price=20000, gas_limit=20000, to="", value=12345678901234567890, data=b"ABCDEFGHIJKLMNOP" * 256 + b"!!!", ) assert sig_v == 28 assert ( sig_r.hex() == "c86bda9de238b1c602648996561e7270a3be208da96bbf23474cb8e4014b9f93" ) assert ( sig_s.hex() == "18742403f75a05e7fa9868c30b36f1e55628de02d01c03084c1ff6775a13137c" )
def test_monero_getaddress(self): self.setup_mnemonic_nopin_nopassphrase() assert ( monero.get_address(self.client, parse_path("m/44h/128h/0h")) == b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM" ) assert ( monero.get_address(self.client, parse_path("m/44h/128h/1h")) == b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie" ) assert ( monero.get_address(self.client, parse_path("m/44h/128h/2h")) == b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH" )
def test_ripple_get_address_other(self): # data from https://github.com/you21979/node-ripple-bip32/blob/master/test/test.js debuglink.load_device_by_mnemonic( self.client, mnemonic="armed bundle pudding lazy strategy impulse where identify submit weekend physical antenna flight social acoustic absurd whip snack decide blur unfold fiction pumpkin athlete", pin="", passphrase_protection=False, label="test", language="english", ) address = get_address(self.client, parse_path("m/44'/144'/0'/0/0")) assert address == "r4ocGE47gm4G4LkA9mriVHQqzpMLBTgnTY" address = get_address(self.client, parse_path("m/44'/144'/0'/0/1")) assert address == "rUt9ULSrUvfCmke8HTFU1szbmFpWzVbBXW"
def test_bch(self): self.setup_mnemonic_allallall() assert ( btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/0/0")) == "bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv" ) assert ( btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/0/1")) == "bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4" ) assert ( btc.get_address(self.client, "Bcash", parse_path("44'/145'/0'/1/0")) == "bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw" )
def test_grs(self): self.setup_mnemonic_allallall() assert ( btc.get_address(self.client, "Groestlcoin", parse_path("44'/17'/0'/0/0")) == "Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM" ) assert ( btc.get_address(self.client, "Groestlcoin", parse_path("44'/17'/0'/1/0")) == "FmRaqvVBRrAp2Umfqx9V1ectZy8gw54QDN" ) assert ( btc.get_address(self.client, "Groestlcoin", parse_path("44'/17'/0'/1/1")) == "Fmhtxeh7YdCBkyQF7AQG4QnY8y3rJg89di" )
def test_lisk_sign_tx_send_wrong_path(self): self.setup_mnemonic_allallall() with self.client: self.client.set_expected_responses( [ proto.ButtonRequest( code=proto.ButtonRequestType.UnknownDerivationPath ), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), proto.LiskSignedTx( signature=bytes.fromhex( "cdce9eba2ea8fa75f90fbc725f0d9de6152c7189a3044ab2fe307d9ff54754856e09125d7a15376eaf4bb5451b63881821948222ccd9ffb5da4d9b1aa8bd4904" ) ), ] ) lisk.sign_tx( self.client, parse_path("m/44'/134'/123456'/123456'/123456'/123456'/123456'"), { "amount": "10000000", "recipientId": "9971262264659915921L", "timestamp": 57525937, "type": 0, "fee": "10000000", "asset": {}, }, )
def test_nem_signtx_mosaic_supply_change(self): self.setup_mnemonic_nopin_nopassphrase() with self.client: tx = nem.sign_tx( self.client, parse_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 74649215, "fee": 2000000, "type": nem.TYPE_MOSAIC_SUPPLY_CHANGE, "deadline": 74735615, "message": {}, "mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"}, "supplyType": 1, "delta": 1, "version": (0x98 << 24), "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", "creationFee": 1500, }, ) assert ( tx.data.hex() == "02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000" ) assert ( tx.signature.hex() == "928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a" )
def test_lisk_sign_tx_send_with_data(self): self.setup_mnemonic_allallall() with self.client: self.client.set_expected_responses( [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), proto.LiskSignedTx( signature=bytes.fromhex( "4e83a651e82f2f787a71a5f44a2911dd0429ee4001b80c79fb7d174ea63ceeefdfba55aa3a9f31fa14b8325a39ad973dcd7eadbaa77b0447a9893f84b60f210e" ) ), ] ) lisk.sign_tx( self.client, parse_path("m/44'/134'/0'"), { "amount": "10000000", "recipientId": "9971262264659915921L", "timestamp": 57525937, "type": 0, "fee": "20000000", "asset": {"data": "Test data"}, }, )
def test_nem_signtx_xem_as_mosaic(self): self.setup_mnemonic_nopin_nopassphrase() tx = nem.sign_tx( self.client, parse_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 76809215, "amount": 5000000, "fee": 1000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", "type": nem.TYPE_TRANSACTION_TRANSFER, "deadline": 76895615, "version": (0x98 << 24), "message": {}, "mosaics": [ { "mosaicId": {"namespaceId": "nem", "name": "xem"}, "quantity": 9000000, } ], }, ) # trezor should display 45 XEM (multiplied by amount) assert ( tx.data.hex() == "0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a404b4c000000000000000000010000001a0000000e000000030000006e656d0300000078656d4054890000000000" ) assert ( tx.signature.hex() == "7b25a84b65adb489ea55739f1ca2d83a0ae069c3c58d0ea075fc30bfe8f649519199ad2324ca229c6c3214191469f95326e99712124592cae7cd3a092c93ac0c" )
def test_nem_signtx_known_mosaic(self): self.setup_mnemonic_nopin_nopassphrase() tx = nem.sign_tx( self.client, parse_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 76809215, "amount": 3000000, "fee": 1000000, "recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT", "type": nem.TYPE_TRANSACTION_TRANSFER, "deadline": 76895615, "version": (0x68 << 24), "message": {}, "mosaics": [ { "mosaicId": {"namespaceId": "dim", "name": "token"}, "quantity": 111000, } ], }, ) # trezor should display 0 XEM and 0.333 DIMTOK assert ( tx.data.hex() == "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c54c0c62d000000000000000000010000001c000000100000000300000064696d05000000746f6b656e98b1010000000000" ) assert ( tx.signature.hex() == "e7f14ef8c39727bfd257e109cd5acac31542f2e41f2e5deb258fc1db602b690eb1cabca41a627fe2adc51f3193db85c76b41c80bb60161eb8738ebf20b507104" )
def test_nem_signtx_unknown_mosaic(self): self.setup_mnemonic_nopin_nopassphrase() tx = nem.sign_tx( self.client, parse_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 76809215, "amount": 2000000, "fee": 1000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", "type": nem.TYPE_TRANSACTION_TRANSFER, "deadline": 76895615, "version": (0x98 << 24), "message": {}, "mosaics": [ { "mosaicId": {"namespaceId": "xxx", "name": "aa"}, "quantity": 3500000, } ], }, ) # trezor should display warning about unknown mosaic and then dialog for 7000000 raw units of xxx.aa and 0 XEM assert ( tx.data.hex() == "0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e00000000000000000001000000190000000d00000003000000787878020000006161e067350000000000" ) assert ( tx.signature.hex() == "2f0280420eceb41ef9e5d94fa44ddda9cdc70b8f423ae18af577f6d85df64bb4aaf40cf24fc6eef47c63b0963611f8682348cecdc49a9b64eafcbe7afcb49102" )
def test_nem_signtx_known_mosaic_with_levy(self): self.setup_mnemonic_nopin_nopassphrase() tx = nem.sign_tx( self.client, parse_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 76809215, "amount": 2000000, "fee": 1000000, "recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT", "type": nem.TYPE_TRANSACTION_TRANSFER, "deadline": 76895615, "version": (0x68 << 24), "message": {}, "mosaics": [ { "mosaicId": {"namespaceId": "dim", "name": "coin"}, "quantity": 222000, } ], }, ) # trezor should display 0 XEM and 0.444 DIM and levy of 0.000444 DIM assert ( tx.data.hex() == "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000010000001b0000000f0000000300000064696d04000000636f696e3063030000000000" ) assert ( tx.signature.hex() == "d3222dd7b83d66bda0539827ac6f909d06e40350b5e5e893d6fa762f954e9bf7da61022ef04950e7b6dfa88a2278f2f8a1b21df2bc3af22b388cb3a90bf76f07" )
def test_ontology_get_ont_address(self): self.setup_mnemonic_nopin_nopassphrase() assert ( ontology.get_address(self.client, parse_path("m/44'/1024'/0'/0/0")) == "ANzeepWmi9hoLBA3UiwVhUm7Eku196VUHk" )
def test_ontology_get_neo_address(self): self.setup_mnemonic_nopin_nopassphrase() assert ( ontology.get_address(self.client, parse_path("m/44'/888'/0'/0/0")) == "AZEMburLePcdfqBFnVfdbsXKiBSnmtgFZr" )
# # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the License along with this library. # If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>. import pytest from trezorlib import messages, tezos from trezorlib.protobuf import dict_to_proto from trezorlib.tools import parse_path TEZOS_PATH = parse_path("m/44'/1729'/0'") TEZOS_PATH_10 = parse_path("m/44'/1729'/10'") TEZOS_PATH_15 = parse_path("m/44'/1729'/15'") @pytest.mark.altcoin @pytest.mark.tezos @pytest.mark.skip_t1 class TestMsgTezosSignTx: def input_flow(self, debug, num_pages): yield for _ in range(num_pages - 1): debug.swipe_up() debug.press_yes() def test_tezos_sign_tx_proposal(self, client):
def test_send_bch_nochange(self): self.setup_mnemonic_allallall() inp1 = proto.TxInputType( address_n=parse_path("44'/145'/0'/1/0"), # bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw amount=1896050, prev_hash=bytes.fromhex( "502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c" ), prev_index=0, script_type=proto.InputScriptType.SPENDADDRESS, ) inp2 = proto.TxInputType( address_n=parse_path("44'/145'/0'/0/1"), # bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4 amount=73452, prev_hash=bytes.fromhex( "502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c" ), prev_index=1, script_type=proto.InputScriptType.SPENDADDRESS, ) out1 = proto.TxOutputType( address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4", amount=1934960, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(self.client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API) assert ( serialized_tx.hex() == "01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000" )
def test_send_bch_multisig_wrongchange(self): self.setup_mnemonic_allallall() nodes = [ btc.get_public_node(self.client, parse_path("48'/145'/%d'" % i)).node for i in range(1, 4) ] def getmultisig(chain, nr, signatures=[b"", b"", b""], nodes=nodes): return proto.MultisigRedeemScriptType(nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2) correcthorse = proto.HDNodeType( depth=1, fingerprint=0, child_num=0, chain_code=bytes.fromhex( "0000000000000000000000000000000000000000000000000000000000000000" ), public_key=bytes.fromhex( "0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71" ), ) sig = bytes.fromhex( "304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae" ) inp1 = proto.TxInputType( address_n=parse_path("48'/145'/1'/1/0"), multisig=getmultisig(1, 0, [b"", sig, b""]), # bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a amount=24000, prev_hash=bytes.fromhex( "f68caf10df12d5b07a34601d88fa6856c6edcbf4d05ebef3486510ae1c293d5f" ), prev_index=1, script_type=proto.InputScriptType.SPENDMULTISIG, ) out1 = proto.TxOutputType( address_n=parse_path("48'/145'/1'/1/1"), multisig=proto.MultisigRedeemScriptType( pubkeys=[ proto.HDNodePathType(node=nodes[0], address_n=[1, 1]), proto.HDNodePathType(node=correcthorse, address_n=[]), proto.HDNodePathType(node=correcthorse, address_n=[]), ], signatures=[b"", b"", b""], m=2, ), script_type=proto.OutputScriptType.PAYTOMULTISIG, amount=23000, ) with self.client: self.client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) (signatures1, serialized_tx) = btc.sign_tx(self.client, "Bcash", [inp1], [out1], prev_txes=TX_API) assert ( signatures1[0].hex() == "304402201badcdcafef4855ed58621f95935efcbc72068510472140f4ec5e252faa0af93022003310a43488288f70aedee96a5af2643a255268a6858cda9ae3001ea5e3c7557" ) assert ( serialized_tx.hex() == "01000000015f3d291cae106548f3be5ed0f4cbedc65668fa881d60347ab0d512df10af8cf601000000fc0047304402201badcdcafef4855ed58621f95935efcbc72068510472140f4ec5e252faa0af93022003310a43488288f70aedee96a5af2643a255268a6858cda9ae3001ea5e3c75574147304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae414c69522102245739b55787a27228a4fe78b3a324366cc645fbaa708cad45da351a334341192102debbdcb0b6970d5ade84a50fdbda1c701cdde5c9925d9b6cd8e05a9a15dbef352102ffe5fa04547b2b0c3cfbc21c08a1ddfb147025fee10274cdcd5c1bdeee88eae253aeffffffff01d85900000000000017a914a23eb2a1ed4003d357770120f5c370e199ee55468700000000" )
# as published by the Free Software Foundation. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the License along with this library. # If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>. import pytest from trezorlib import lisk from trezorlib.tools import parse_path from ..common import MNEMONIC12 LISK_PATH = parse_path("m/44h/134h/0h/0h") @pytest.mark.altcoin @pytest.mark.lisk class TestMsgLiskGetPublicKey: @pytest.mark.setup_client(mnemonic=MNEMONIC12) def test_lisk_get_public_key(self, client): sig = lisk.get_public_key(client, LISK_PATH) assert ( sig.public_key.hex() == "eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294" )
def test_send_btg_multisig_change(self, client): nodes = [ btc.get_public_node( client, parse_path(f"48'/156'/{i}'"), coin_name="Bgold" ).node for i in range(1, 4) ] def getmultisig(chain, nr, signatures=[b"", b"", b""], nodes=nodes): return proto.MultisigRedeemScriptType( nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2 ) inp1 = proto.TxInputType( address_n=parse_path("48'/156'/3'/0/0"), multisig=getmultisig(0, 0), # 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R amount=1252382934, prev_hash=TXHASH_25526b, prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, ) out1 = proto.TxOutputType( address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe", amount=24000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address_n=parse_path("48'/156'/3'/1/0"), multisig=getmultisig(1, 0), script_type=proto.OutputScriptType.PAYTOMULTISIG, amount=1252382934 - 24000 - 1000, ) with client: client.set_expected_responses( [ request_input(0), request_meta(TXHASH_25526b), request_input(0, TXHASH_25526b), request_output(0, TXHASH_25526b), request_output(1, TXHASH_25526b), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), request_output(1), proto.ButtonRequest(code=B.SignTx), request_input(0), request_output(0), request_output(1), request_finished(), ] ) signatures, serialized_tx = btc.sign_tx( client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API ) assert ( signatures[0].hex() == "30440220271c46ef3d7c37bd499804128623da3aa0014f3b4447dd39c4573b23c4537f6902205329167b9eb48427af62b04bf5138295f4c38613f6ba955934d15c499bff0d8a" ) inp1 = proto.TxInputType( address_n=parse_path("48'/156'/1'/0/0"), multisig=getmultisig(0, 0, [b"", b"", signatures[0]]), amount=1252382934, prev_hash=TXHASH_25526b, prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, ) out2.address_n[2] = H_(1) with client: client.set_expected_responses( [ request_input(0), request_meta(TXHASH_25526b), request_input(0, TXHASH_25526b), request_output(0, TXHASH_25526b), request_output(1, TXHASH_25526b), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), request_output(1), proto.ButtonRequest(code=B.SignTx), request_input(0), request_output(0), request_output(1), request_finished(), ] ) signatures, serialized_tx = btc.sign_tx( client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API ) assert ( signatures[0].hex() == "3045022100bdf8c4bd14217c183612c7e8f79691f6479bcb35aa403f77d70182f58633ac6e02205b10a79b7894bb40248a120c8fcb7096a46950593e4c5b48a20bc5ebe53d85fa" ) assert ( btc_hash(serialized_tx)[::-1].hex() == "b45ba21b69e1e1c6ad79f5408fe70d92fb861742d239cb6a952213f60c253e40" )
def test_send_bch_multisig_change(client): nodes = [ btc.get_public_node( client, parse_path(f"48'/145'/{i}'/0'"), coin_name="Bcash" ).node for i in range(1, 4) ] EMPTY_SIGNATURES = [b"", b"", b""] def getmultisig(chain, nr, signatures): return messages.MultisigRedeemScriptType( nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2 ) inp1 = messages.TxInputType( address_n=parse_path("48'/145'/3'/0'/0/0"), multisig=getmultisig(0, 0, EMPTY_SIGNATURES), amount=48490, prev_hash=TXHASH_8b6db9, prev_index=0, script_type=messages.InputScriptType.SPENDMULTISIG, ) out1 = messages.TxOutputType( address="bitcoincash:qqq8gx2j76nw4dfefumxmdwvtf2tpsjznusgsmzex9", amount=24000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) out2 = messages.TxOutputType( address_n=parse_path("48'/145'/3'/0'/1/0"), multisig=getmultisig(1, 0, EMPTY_SIGNATURES), script_type=messages.OutputScriptType.PAYTOMULTISIG, amount=24000, ) with client: client.set_expected_responses( [ request_input(0), request_output(0), messages.ButtonRequest(code=B.ConfirmOutput), request_output(1), messages.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_8b6db9), request_input(0, TXHASH_8b6db9), request_output(0, TXHASH_8b6db9), request_input(0), request_output(0), request_output(1), request_finished(), ] ) (signatures1, serialized_tx) = btc.sign_tx( client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API ) assert ( signatures1[0].hex() == "304402202b75dbb307d2556b9a85851d27ab118b3f06344bccb6e21b0a5dfcf74e0e644f02206611c59396d44741d34fd7bb602be06ef91690b22b47c3f3c271e15e20176ac0" ) inp1 = messages.TxInputType( address_n=parse_path("48'/145'/1'/0'/0/0"), multisig=getmultisig(0, 0, [b"", b"", signatures1[0]]), # bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw amount=48490, prev_hash=TXHASH_8b6db9, prev_index=0, script_type=messages.InputScriptType.SPENDMULTISIG, ) out2.address_n[2] = H_(1) with client: client.set_expected_responses( [ request_input(0), request_output(0), messages.ButtonRequest(code=B.ConfirmOutput), request_output(1), messages.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_8b6db9), request_input(0, TXHASH_8b6db9), request_output(0, TXHASH_8b6db9), request_input(0), request_output(0), request_output(1), request_finished(), ] ) (signatures1, serialized_tx) = btc.sign_tx( client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API ) assert ( signatures1[0].hex() == "3045022100cc12faf18a489d8014e978ef7ca0760aa6487cdb40b49dd991bfe9c66625f5a802206088fef49ecad30679d55eaa870741bbb8b83fac08eb078872ac276c8139015d" ) assert ( serialized_tx.hex() == "0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfd0000483045022100cc12faf18a489d8014e978ef7ca0760aa6487cdb40b49dd991bfe9c66625f5a802206088fef49ecad30679d55eaa870741bbb8b83fac08eb078872ac276c8139015d4147304402202b75dbb307d2556b9a85851d27ab118b3f06344bccb6e21b0a5dfcf74e0e644f02206611c59396d44741d34fd7bb602be06ef91690b22b47c3f3c271e15e20176ac0414c6952210290cc724ccb90a6c7c1c3b291938449464ea474390183909e51bcd2807ecb779d210222f537684e2933563f737192fbf1947fd9034402e5708d10f6decd8e1f03e172210350df5cb41013d6b06581230556006b0a85ccccd205745cc10c927755193c241b53aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a914dfc8c2dda26f7151ed7df8aeeca24089e6410fdd8700000000" )
def test_one_one_fee_sapling(self, client): # prevout: e3820602226974b1dd87b7113cc8aea8c63e5ae29293991e7bfa80c126930368:0 # input 1: 3.0 TAZ inp1 = proto.TxInputType( address_n=parse_path( "m/Zcash Testnet/0h/0/0" ), # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu amount=300000000, prev_hash=TXHASH_e38206, prev_index=0, ) out1 = proto.TxOutputType( address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z", amount=300000000 - 1940, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses( [ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) details = proto.SignTx( version=4, overwintered=True, version_group_id=0x892F2085, branch_id=0x76B809BB, ) _, serialized_tx = btc.sign_tx( client, "Zcash Testnet", [inp1], [out1], details=details, prev_txes=TX_API, ) # Accepted by network: tx 0cef132c1d6d67f11cfa48f7fca3209da29cf872ac782354bedb686e61a17a78 assert ( serialized_tx.hex() == "0400008085202f890168039326c180fa7b1e999392e25a3ec6a8aec83c11b787ddb1746922020682e3000000006b483045022100f28298891f48706697a6f898ac18e39ce2c7cebe547b585d51cc22d80b1b21a602201a807b8a18544832d95d1e3ada82c0617bc6d97d3f24d1fb4801ac396647aa880121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c9be111000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000000000000000000000000000000000" )
import pytest from trezorlib import btc, messages from trezorlib.exceptions import TrezorFailure from trezorlib.tools import parse_path from .. import bip32 pytestmark = pytest.mark.skip_ui VECTORS_BITCOIN = ( # coin_name, xpub_magic, path, xpub ( "Bitcoin", 0x0488B21E, parse_path("m/44h/0h/0h"), "xpub6BiVtCpG9fQPxnPmHXG8PhtzQdWC2Su4qWu6XW9tpWFYhxydCLJGrWBJZ5H6qTAHdPQ7pQhtpjiYZVZARo14qHiay2fvrX996oEP42u8wZy", ), ( "Bitcoin", 0x0488B21E, parse_path("m/44h/0h/10h"), "xpub6BiVtCpG9fQQR6cSuFeDaSvCDgNvNme499JUGX4RHDiZVWwZy9NwNieWKXHLe8XRbdrEmY87aqztBCbRJkXWV7VJB96XBT5cpkqYMHwvLWB", ), ( "Bitcoin", 0x0488B21E, parse_path("m/44h/0h/0h/0/0"), "xpub6FVDRC1jiWNTuT3embehwSZ1buxRDyZGbTakVCkBr6w2LwpERmYqXyvtrLeJX9hqzLaucS3qJXGekeFsSVCELkbgepp7FVGeH5BYekEgT9x", ), (
def test_p2wpkh_in_p2sh_presigned(client): inp1 = proto.TxInputType( # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX amount=111145789, prev_hash=TXHASH_091446, prev_index=1, script_type=proto.InputScriptType.EXTERNAL, script_sig=bytearray.fromhex("160014d16b8c0680c61fc6ed2e407455715055e41052f5"), witness=bytes.fromhex( "02483045022100ead79ee134f25bb585b48aee6284a4bb14e07f03cc130253e83450d095515e5202201e161e9402c8b26b666f2b67e5b668a404ef7e57858ae9a6a68c3837e65fdc69012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b79" ), ) inp2 = proto.TxInputType( address_n=parse_path("84'/1'/0'/1/0"), amount=7289000, prev_hash=TXHASH_65b811, prev_index=1, script_type=proto.InputScriptType.SPENDWITNESS, ) out1 = proto.TxOutputType( address="tb1q54un3q39sf7e7tlfq99d6ezys7qgc62a6rxllc", amount=12300000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( # address_n=parse_path("44'/1'/0'/0/0"), address="2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc", script_type=proto.OutputScriptType.PAYTOADDRESS, amount=45600000, ) out3 = proto.TxOutputType( address="mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q", amount=111145789 + 7289000 - 11000 - 12300000 - 45600000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses( [ request_input(0), request_input(1), request_meta(TXHASH_65b811), request_input(0, TXHASH_65b811), request_output(0, TXHASH_65b811), request_output(1, TXHASH_65b811), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), request_output(1), proto.ButtonRequest(code=B.ConfirmOutput), request_output(2), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_091446), request_input(0, TXHASH_091446), request_output(0, TXHASH_091446), request_output(1, TXHASH_091446), request_input(0), request_input(1), request_output(0), request_output(1), request_output(2), request_input(0), request_input(1), request_finished(), ] ) _, serialized_tx = btc.sign_tx( client, "Testnet", [inp1, inp2], [out1, out2, out3], prev_txes=TX_CACHE_TESTNET, ) assert ( serialized_tx.hex() == "010000000001028a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090100000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff7b010c5faeb41cc5c253121b6bf69bf1a7c5867cd7f2d91569fea0ecd311b8650100000000ffffffff03e0aebb0000000000160014a579388225827d9f2fe9014add644487808c695d00cdb7020000000017a91491233e24a9bf8dbb19c1187ad876a9380c12e787870d859b03000000001976a914a579388225827d9f2fe9014add644487808c695d88ac02483045022100ead79ee134f25bb585b48aee6284a4bb14e07f03cc130253e83450d095515e5202201e161e9402c8b26b666f2b67e5b668a404ef7e57858ae9a6a68c3837e65fdc69012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7902463043021f585c54a84dc7326fa60e22729accd41153c7dd4725bd4c8f751aa3a8cd8d6a0220631bfd83fc312cc6d5d129572a25178696d81eaf50c8c3f16c6121be4f4c029d012103505647c017ff2156eb6da20fae72173d3b681a1d0a629f95f49e884db300689f00000000" ) # Test corrupted script hash in scriptsig. inp1.script_sig[10] ^= 1 with client: client.set_expected_responses( [ request_input(0), request_input(1), request_meta(TXHASH_65b811), request_input(0, TXHASH_65b811), request_output(0, TXHASH_65b811), request_output(1, TXHASH_65b811), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), request_output(1), proto.ButtonRequest(code=B.ConfirmOutput), request_output(2), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_091446), request_input(0, TXHASH_091446), request_output(0, TXHASH_091446), request_output(1, TXHASH_091446), proto.Failure(code=proto.FailureType.DataError), ] ) with pytest.raises(TrezorFailure, match="Invalid public key hash"): btc.sign_tx( client, "Testnet", [inp1, inp2], [out1, out2, out3], prev_txes=TX_CACHE_TESTNET, )
def get_bad_address(): btc.get_address(client, "Bitcoin", parse_path("m/44'"), show_display=True)
def test_ethereum_signtx_data(self): self.setup_mnemonic_nopin_nopassphrase() with self.client: self.client.set_expected_responses( [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.EthereumTxRequest(data_length=None), ] ) sig_v, sig_r, sig_s = ethereum.sign_tx( self.client, n=parse_path("44'/60'/0'/0/0"), nonce=0, gas_price=20, gas_limit=20, to=TO_ADDR, value=10, data=b"abcdefghijklmnop" * 16, ) assert sig_v == 27 assert ( sig_r.hex() == "e90f9e3dbfb34861d40d67570cb369049e675c6eebfdda6b08413a2283421b85" ) assert ( sig_s.hex() == "763912b8801f76cbea7792d98123a245514beeab2f3afebb4bab637888e8393a" ) with self.client: self.client.set_expected_responses( [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.EthereumTxRequest( data_length=1024, signature_r=None, signature_s=None, signature_v=None, ), proto.EthereumTxRequest(data_length=1024), proto.EthereumTxRequest(data_length=1024), proto.EthereumTxRequest(data_length=3), proto.EthereumTxRequest(), ] ) sig_v, sig_r, sig_s = ethereum.sign_tx( self.client, n=parse_path("44'/60'/0'/0/0"), nonce=123456, gas_price=20000, gas_limit=20000, to=TO_ADDR, value=12345678901234567890, data=b"ABCDEFGHIJKLMNOP" * 256 + b"!!!", ) assert sig_v == 27 assert ( sig_r.hex() == "dd96d82d791118a55601dfcede237760d2e9734b76c373ede5362a447c42ac48" ) assert ( sig_s.hex() == "60a77558f28d483d476f9507cd8a6a4bb47b86611aaff95fd5499b9ee9ebe7ee" )
def test_send_bch_change(self): self.setup_mnemonic_allallall() inp1 = proto.TxInputType( address_n=parse_path("44'/145'/0'/0/0"), # bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv amount=1995344, prev_hash=bytes.fromhex( "bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78" ), prev_index=0, script_type=proto.InputScriptType.SPENDADDRESS, ) out1 = proto.TxOutputType( address_n=parse_path("44'/145'/0'/1/0"), amount=1896050, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4", amount=73452, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(self.client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API) assert ( serialized_tx.hex() == "0100000001781a716b1e15b41b07157933e5d777392a75bf87132650cb2e7d46fb8dc237bc000000006a473044022061aee4f17abe044d5df8c52c9ffd3b84e5a29743517e488b20ecf1ae0b3e4d3a02206bb84c55e407f3b684ff8d9bea0a3409cfd865795a19d10b3d3c31f12795c34a412103a020b36130021a0f037c1d1a02042e325c0cb666d6478c1afdcd9d913b9ef080ffffffff0272ee1c00000000001976a914b1401fce7e8bf123c88a0467e0ed11e3b9fbef5488acec1e0100000000001976a914d51eca49695cdf47e7f4b55507893e3ad53fe9d888ac00000000" )
def get_bad_address(): btc.get_address(client, "Bitcoin", parse_path("m/0"))
def test_one_one_fee_overwinter(self, client): # prevout: aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc:1 # input 1: 3.0 TAZ inp1 = proto.TxInputType( address_n=parse_path( "m/Zcash Testnet/0h/0/0" ), # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu amount=300000000, prev_hash=TXHASH_aaf51e, prev_index=1, ) out1 = proto.TxOutputType( address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z", amount=300000000 - 1940, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses( [ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) details = proto.SignTx( version=3, overwintered=True, version_group_id=0x03C48270, branch_id=0x5BA81B19, ) _, serialized_tx = btc.sign_tx( client, "Zcash Testnet", [inp1], [out1], details=details, prev_txes=TX_API, ) # Accepted by network: tx eda9b772c47f0c29310759960e0081c98707aa67a0a2738bcc71439fcf360675 assert ( serialized_tx.hex() == "030000807082c40301dc754d63eff4698ee321476872519c53f14cfe58c9425c7ee464c206461ef5aa010000006a47304402207e45f303b4e42be824513855eb21653e1d2749cd94dcd0f0613d3f85d4efd1e20220699ffbdbcad889af7ede5ce9febf7a5ef8f5619b2464824529974c400cffaebc0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c9be111000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac000000000000000000" )
def test_p2wsh_external_presigned(client): inp1 = proto.TxInputType( address_n=parse_path("84'/1'/0'/0/0"), amount=12300000, prev_hash=TXHASH_091446, prev_index=0, script_type=proto.InputScriptType.SPENDWITNESS, ) inp2 = proto.TxInputType( # 1-of-2 multisig # m/84'/1'/0/0/0' for "alcohol woman abuse ..." seed. # m/84'/1'/0/0/0' for "all all ... all" seed. # tb1qpzmgzpcumztvmpu3q27wwdggqav26j9dgks92pvnne2lz9ferxgssmhzlq prev_hash=TXHASH_a345b8, prev_index=0, script_type=proto.InputScriptType.EXTERNAL, amount=100, witness=bytearray.fromhex( "030047304402206b570b99c22c841548a35a9b9c673fa3b87a9563ed64ad7d979aa3e01b2e303802201d0bebf58b7243e09798e734fc32892936c4d0c4984bec755dc951ef646e4a9a0147512103505f0d82bbdd251511591b34f36ad5eea37d3220c2b81a1189084431ddb3aa3d2103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f86252ae" ), ) out1 = proto.TxOutputType( address="2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp", amount=12300000 + 100 - 10000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses( [ request_input(0), request_meta(TXHASH_091446), request_input(0, TXHASH_091446), request_output(0, TXHASH_091446), request_output(1, TXHASH_091446), request_input(1), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(1), request_meta(TXHASH_a345b8), request_input(0, TXHASH_a345b8), request_output(0, TXHASH_a345b8), request_input(0), request_input(1), request_output(0), request_input(0), request_input(1), request_finished(), ] ) _, serialized_tx = btc.sign_tx( client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET ) assert ( serialized_tx.hex() == "010000000001028a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090000000000ffffffff48e37c58a68ab4899400dc0950a661817ea7bac3e4556044c685b35957b845a30000000000ffffffff013488bb000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c9870247304402204270cf602ec151e72b99c5048755379c368c6c7cd722e4234ad4bb7b1b87d09d02207fa59b1c2926ea6b4f0094ab77c08e50b089a199a5bc8419e1ee6674809c4fb4012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862030047304402206b570b99c22c841548a35a9b9c673fa3b87a9563ed64ad7d979aa3e01b2e303802201d0bebf58b7243e09798e734fc32892936c4d0c4984bec755dc951ef646e4a9a0147512103505f0d82bbdd251511591b34f36ad5eea37d3220c2b81a1189084431ddb3aa3d2103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f86252ae00000000" ) # Test corrupted signature in witness. inp2.witness[10] ^= 1 with client: client.set_expected_responses( [ request_input(0), request_meta(TXHASH_091446), request_input(0, TXHASH_091446), request_output(0, TXHASH_091446), request_output(1, TXHASH_091446), request_input(1), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(1), request_meta(TXHASH_a345b8), request_input(0, TXHASH_a345b8), request_output(0, TXHASH_a345b8), proto.Failure(code=proto.FailureType.DataError), ] ) with pytest.raises(TrezorFailure, match="Invalid signature"): btc.sign_tx( client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET )
def test_2_of_3(self, client): nodes = [ btc.get_public_node(client, parse_path("48'/0'/%d'" % index)).node for index in range(1, 4) ] multisig = proto.MultisigRedeemScriptType(nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2) # Let's go to sign with key 1 inp1 = proto.TxInputType( address_n=parse_path("48'/0'/1'/0/0"), prev_hash=TXHASH_c6091a, prev_index=1, script_type=proto.InputScriptType.SPENDMULTISIG, multisig=multisig, ) out1 = proto.TxOutputType( address="12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss", amount=100000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_c6091a), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_c6091a), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_c6091a), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_c6091a), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) # Now we have first signature signatures1, _ = btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API) assert ( signatures1[0].hex() == "3044022052f4a3dc5ca3e86ed66abb1e2b4d9b9ace7d96f5615944beea19e58280847c2902201bd3ff32a38366a4eed0373e27da26ebc0d2a4c2bbeffd83e8a60e313d95b9e3" ) # --------------------------------------- # Let's do second signature using 3rd key multisig = proto.MultisigRedeemScriptType( nodes=nodes, address_n=[0, 0], signatures=[ signatures1[0], b"", b"", ], # Fill signature from previous signing process m=2, ) # Let's do a second signature with key 3 inp3 = proto.TxInputType( address_n=parse_path("48'/0'/3'/0/0"), prev_hash=TXHASH_c6091a, prev_index=1, script_type=proto.InputScriptType.SPENDMULTISIG, multisig=multisig, ) with client: client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_c6091a), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_c6091a), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_c6091a), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_c6091a), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) signatures2, serialized_tx = btc.sign_tx(client, "Bitcoin", [inp3], [out1], prev_txes=TX_API) assert ( signatures2[0].hex() == "304402203828fd48540811be6a1b12967e7012587c46e6f05c78d42471e7b25c06bc7afc0220749274bc1aa698335b00400c5ba946a70b6b46c711324fbc4989279737a57f49" ) assert ( serialized_tx.hex() == "010000000152ba4dfcde9c4bed88f55479cdea03e711ae586e9a89352a98230c4cdf1a09c601000000fc00473044022052f4a3dc5ca3e86ed66abb1e2b4d9b9ace7d96f5615944beea19e58280847c2902201bd3ff32a38366a4eed0373e27da26ebc0d2a4c2bbeffd83e8a60e313d95b9e30147304402203828fd48540811be6a1b12967e7012587c46e6f05c78d42471e7b25c06bc7afc0220749274bc1aa698335b00400c5ba946a70b6b46c711324fbc4989279737a57f49014c6952210203ed6187880ae932660086e55d4561a57952dd200aa3ed2aa66b73e5723a0ce7210360e7f32fd3c8dee27a166f6614c598929699ee66acdcbda5fb24571bf2ae1ca021037c4c7e5d3293ab0f97771dcfdf83caadab341f427f54713da8b2c590a834f03b53aeffffffff01a0860100000000001976a91412e8391ad256dcdc023365978418d658dfecba1c88ac00000000" )
def test_send_bch_multisig_wrongchange(client): nodes = [ btc.get_public_node( client, parse_path(f"48'/145'/{i}'/0'"), coin_name="Bcash" ).node for i in range(1, 4) ] def getmultisig(chain, nr, signatures): return messages.MultisigRedeemScriptType( nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2 ) correcthorse = messages.HDNodeType( depth=1, fingerprint=0, child_num=0, chain_code=bytes.fromhex( "0000000000000000000000000000000000000000000000000000000000000000" ), public_key=bytes.fromhex( "0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71" ), ) sig = bytes.fromhex( "304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae" ) inp1 = messages.TxInputType( address_n=parse_path("48'/145'/1'/0'/1/0"), multisig=getmultisig(1, 0, [b"", sig, b""]), # bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a amount=24000, prev_hash=TXHASH_f68caf, prev_index=1, script_type=messages.InputScriptType.SPENDMULTISIG, ) out1 = messages.TxOutputType( address_n=parse_path("48'/145'/1'/0'/1/1"), multisig=messages.MultisigRedeemScriptType( pubkeys=[ messages.HDNodePathType(node=nodes[0], address_n=[1, 1]), messages.HDNodePathType(node=correcthorse, address_n=[]), messages.HDNodePathType(node=correcthorse, address_n=[]), ], signatures=[b"", b"", b""], m=2, ), script_type=messages.OutputScriptType.PAYTOMULTISIG, amount=23000, ) with client: client.set_expected_responses( [ request_input(0), request_output(0), messages.ButtonRequest(code=B.ConfirmOutput), messages.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_f68caf), request_input(0, TXHASH_f68caf), request_output(0, TXHASH_f68caf), request_output(1, TXHASH_f68caf), request_input(0), request_output(0), request_finished(), ] ) (signatures1, serialized_tx) = btc.sign_tx( client, "Bcash", [inp1], [out1], prev_txes=TX_API ) assert ( signatures1[0].hex() == "304402205ce02f7bf3ef225e4a17e2b5a98dc6ca5536a6b68088f94200390a1d505c4f3e022045657781095e01422736c5541b03b014101d76e54089eda030cb016dfce10e98" ) assert ( serialized_tx.hex() == "01000000015f3d291cae106548f3be5ed0f4cbedc65668fa881d60347ab0d512df10af8cf601000000fc0047304402205ce02f7bf3ef225e4a17e2b5a98dc6ca5536a6b68088f94200390a1d505c4f3e022045657781095e01422736c5541b03b014101d76e54089eda030cb016dfce10e984147304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae414c69522102962724052105f03332ab700812afc5ca665d264b13339be1fe7f7fdd3a2a685821024364cd1fdc2aa05bc8b09874a57aa1082a47ac9062d35f22ed5f4afefb3f67fc21024d375b44804f3b0c3493ea0806eb25cc85f51e0d616d6bd6e4ef0388e71cd29e53aeffffffff01d85900000000000017a9140d5566bfc721e6c3d5ab583841d387f3939ffed38700000000" )
def test_ripple_sign_simple_tx(self): self.setup_mnemonic_allallall() msg = ripple.create_sign_tx_msg({ "TransactionType": "Payment", "Payment": { "Amount": 100000000, "Destination": "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws", }, "Flags": 0x80000000, "Fee": 100000, "Sequence": 25, }) resp = ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/0"), msg) assert ( resp.signature.hex() == "3045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c0" ) assert ( resp.serialized_tx.hex() == "12000022800000002400000019614000000005f5e1006840000000000186a0732102131facd1eab748d6cddc492f54b04e8c35658894f4add2232ebc5afe7521dbe474473045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c081148fb40e1ffa5d557ce9851a535af94965e0dd098883147148ebebf7304ccdf1676fefcf9734cf1e780826" ) msg = ripple.create_sign_tx_msg({ "TransactionType": "Payment", "Payment": { "Amount": 1, "Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H", }, "Fee": 10, "Sequence": 1, }) resp = ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/2"), msg) assert ( resp.signature.hex() == "3044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f" ) assert ( resp.serialized_tx.hex() == "1200002280000000240000000161400000000000000168400000000000000a732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed274463044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988" ) msg = ripple.create_sign_tx_msg({ "TransactionType": "Payment", "Payment": { "Amount": 100000009, "Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H", "DestinationTag": 123456, }, "Flags": 0, "Fee": 100, "Sequence": 100, "LastLedgerSequence": 333111, }) resp = ripple.sign_tx(self.client, parse_path("m/44'/144'/0'/0/2"), msg) assert ( resp.signature.hex() == "30450221008770743a472bb2d1c746a53ef131cc17cc118d538ec910ca928d221db4494cf702201e4ef242d6c3bff110c3cc3897a471fed0f5ac10987ea57da63f98dfa01e94df" ) assert ( resp.serialized_tx.hex() == "120000228000000024000000642e0001e240201b00051537614000000005f5e109684000000000000064732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed2744730450221008770743a472bb2d1c746a53ef131cc17cc118d538ec910ca928d221db4494cf702201e4ef242d6c3bff110c3cc3897a471fed0f5ac10987ea57da63f98dfa01e94df8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988" )
def test_p2wpkh_with_proof(client): inp1 = proto.TxInputType( # seed "alcohol woman abuse must during monitor noble actual mixed trade anger aisle" # 84'/1'/0'/0/0 # tb1qnspxpr2xj9s2jt6qlhuvdnxw6q55jvygcf89r2 amount=100000, prev_hash=TXHASH_e5b7e2, prev_index=0, script_type=proto.InputScriptType.EXTERNAL, ownership_proof=bytearray.fromhex( "534c001900016b2055d8190244b2ed2d46513c40658a574d3bc2deb6969c0535bb818b44d2c40002483045022100d4ad0374c922848c71d913fba59c81b9075e0d33e884d953f0c4b4806b8ffd0c022024740e6717a2b6a5aa03148c3a28b02c713b4e30fc8aeae67fa69eb20e8ddcd9012103505f0d82bbdd251511591b34f36ad5eea37d3220c2b81a1189084431ddb3aa3d" ), ) inp2 = proto.TxInputType( address_n=parse_path("84'/1'/0'/1/0"), amount=7289000, prev_hash=TXHASH_65b811, prev_index=1, script_type=proto.InputScriptType.SPENDWITNESS, ) out1 = proto.TxOutputType( address="tb1q54un3q39sf7e7tlfq99d6ezys7qgc62a6rxllc", amount=1230000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q", amount=100000 + 7289000 - 11000 - 1230000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses( [ request_input(0), request_input(1), request_meta(TXHASH_65b811), request_input(0, TXHASH_65b811), request_output(0, TXHASH_65b811), request_output(1, TXHASH_65b811), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), request_output(1), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_e5b7e2), request_input(0, TXHASH_e5b7e2), request_output(0, TXHASH_e5b7e2), request_output(1, TXHASH_e5b7e2), request_input(0), request_input(1), request_output(0), request_output(1), request_input(1), request_finished(), ] ) _, serialized_tx = btc.sign_tx( client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET, ) assert ( serialized_tx.hex() == "010000000001028abbd1cf69e00fbf60fa3ba475dccdbdba4a859ffa6bfd1ee820a75b1be2b7e50000000000ffffffff7b010c5faeb41cc5c253121b6bf69bf1a7c5867cd7f2d91569fea0ecd311b8650100000000ffffffff02b0c4120000000000160014a579388225827d9f2fe9014add644487808c695da0cf5d00000000001976a914a579388225827d9f2fe9014add644487808c695d88ac0002483045022100b17fe0eb21da96bdf9640bbe94f6198ff2ced183765753ee3d5119e661977cb20220121dfdc7a121afdcc08fae1389c7147a10bc58b2daea46799c6e6547c648ba1d012103505647c017ff2156eb6da20fae72173d3b681a1d0a629f95f49e884db300689f00000000" ) # Test corrupted ownership proof. inp1.ownership_proof[10] ^= 1 with pytest.raises(TrezorFailure, match="Invalid signature"): btc.sign_tx( client, "Testnet", [inp1, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET, )
def test_opreturn(self, client): inp1 = proto.TxInputType(address_n=parse_path("44'/0'/0'/0/2"), prev_hash=TXHASH_d5f65e, prev_index=0) out1 = proto.TxOutputType( address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1", amount=390000 - 10000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( op_return_data=b"test of the op_return data", amount=0, script_type=proto.OutputScriptType.PAYTOOPRETURN, ) with client: client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_d5f65e), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d5f65e), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_d5f65e), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d5f65e), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(client, "Bitcoin", [inp1], [out1, out2], prev_txes=TX_API) assert ( serialized_tx.hex() == "010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b483045022100bc36e1227b334e856c532bbef86d30a96823a5f2461738f4dbf969dfbcf1b40b022078c5353ec9a4bce2bb05bd1ec466f2ab379c1aad926e208738407bba4e09784b012103330236b68aa6fdcaca0ea72e11b360c84ed19a338509aa527b678a7ec9076882ffffffff0260cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000000000001c6a1a74657374206f6620746865206f705f72657475726e206461746100000000" )
def signTx(cls, tx): def int_to_big_endian(value): return value.to_bytes((value.bit_length() + 7) // 8, 'big') address_n = tools.parse_path(cls.hdpath()) msg = proto.EthereumSignTx(address_n=address_n, nonce=int_to_big_endian(tx['nonce']), gas_price=int_to_big_endian(tx['gasPrice']), gas_limit=int_to_big_endian(tx['gas']), chain_id=int(tx['chainId']), value=int_to_big_endian(tx['value'])) if tx['to']: msg.to = tx['to'] data = None if tx['data'].__class__ is str: data = bytes.fromhex(tx['data'].replace('0x', '')) elif tx['data'].__class__ is bytes: data = tx['data'] if data: msg.data_length = len(data) data, chunk = data[1024:], data[:1024] msg.data_initial_chunk = chunk try: response = cls.call_raw(msg, atomic=False) # Confused? Ask trezor why. I don't know why. # ButtonAck is a no-op afaict. But you still have to send it. # Punch the monkey. # Punch it. # Punch the monkey. # Punch the monkey. # Punch the monkey. while response.__class__.__name__ == 'ButtonRequest': response = cls.call_raw(proto.ButtonAck()) if response.__class__.__name__ == 'PinMatrixRequest': cls.matrix_request_window() raise SignTxError("Credstick needs to be unlocked") elif response.__class__.__name__ == 'PassphraseRequest': cls.passphrase_request_window() raise SignTxError("Credstick needs to be unlocked") elif response.__class__.__name__ == 'Failure': raise SignTxError except TransportException: raise SignTxError while response.data_length is not None: data_length = response.data_length data, chunk = data[data_length:], data[:data_length] response = cls.call_raw(proto.EthereumTxAck(data_chunk=chunk), atomic=False) # above, we were calling out with atomic=False to # prevent the session from being terminated. cls.transport.end_session() _v = response.signature_v _r = response.signature_r _s = response.signature_s sutx = serializable_unsigned_transaction_from_dict(tx) return cls.signed_tx(sutx, _v, int(_r.hex(), 16), int(_s.hex(), 16))
def test_p2pkh_presigned(client): inp1 = proto.TxInputType( # mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q address_n=parse_path("m/44h/1h/0h/0/0"), prev_hash=TXHASH_e5040e, prev_index=0, # amount=31000000, ) inp1ext = proto.TxInputType( # mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q # address_n=parse_path("m/44h/1h/0h/0/0"), prev_hash=TXHASH_e5040e, prev_index=0, amount=31000000, script_type=proto.InputScriptType.EXTERNAL, script_sig=bytes.fromhex( "473044022054fa66bfe1de1c850d59840f165143a66075bae78be3a6bc2809d1ac09431d380220019ecb086e16384f18cbae09b02bd2dce18763cd06454d33d93630561250965e0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0" ), ) inp2 = proto.TxInputType( # mopZWqZZyQc3F2Sy33cvDtJchSAMsnLi7b address_n=parse_path("m/44h/1h/0h/0/1"), prev_hash=TXHASH_d830b8, prev_index=1, # amount=600000000, ) inp2ext = proto.TxInputType( # mopZWqZZyQc3F2Sy33cvDtJchSAMsnLi7b # address_n=parse_path("m/44h/1h/0h/0/1"), prev_hash=TXHASH_d830b8, prev_index=1, amount=600000000, script_type=proto.InputScriptType.EXTERNAL, script_sig=bytearray.fromhex( "463043021f3a0a7fdf27b340358ddf8b4e6e3e6cc0be728d6f1d9d3413ae59741f57599002204809d59a9432a2c7fcb10639c5efa82935d8c3cc21b185ff5e44f0e1a80e635401210294e3e5e77e22eea0e4c0d30d89beb4db7f69b4bf1ae709e411d6a06618b8f852" ), ) out1 = proto.TxOutputType( address="tb1qnspxpr2xj9s2jt6qlhuvdnxw6q55jvygcf89r2", amount=620000000, script_type=proto.OutputScriptType.PAYTOWITNESS, ) out2 = proto.TxOutputType( address_n=parse_path("44h/1h/0h/1/0"), amount=31000000 + 600000000 - 620000000 - 10000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) # Test with first input as pre-signed external. with client: _, serialized_tx = btc.sign_tx( client, "Testnet", [inp1ext, inp2], [out1, out2], prev_txes=TX_CACHE_TESTNET, ) expected_tx = "0100000002cd3b93f5b24ae190ce5141235091cd93fbb2908e24e5b9ff6776aec11b0e04e5000000006a473044022054fa66bfe1de1c850d59840f165143a66075bae78be3a6bc2809d1ac09431d380220019ecb086e16384f18cbae09b02bd2dce18763cd06454d33d93630561250965e0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff747b11157ff1d871f6d2efa282c21aa06d295a8288be680a7a23d9c377b830d80100000069463043021f3a0a7fdf27b340358ddf8b4e6e3e6cc0be728d6f1d9d3413ae59741f57599002204809d59a9432a2c7fcb10639c5efa82935d8c3cc21b185ff5e44f0e1a80e635401210294e3e5e77e22eea0e4c0d30d89beb4db7f69b4bf1ae709e411d6a06618b8f852ffffffff020073f424000000001600149c02608d469160a92f40fdf8c6ccced029493088b0b1a700000000001976a9143d3cca567e00a04819742b21a696a67da796498b88ac00000000" assert serialized_tx.hex() == expected_tx # Test with second input as pre-signed external. with client: _, serialized_tx = btc.sign_tx( client, "Testnet", [inp1, inp2ext], [out1, out2], prev_txes=TX_CACHE_TESTNET, ) assert serialized_tx.hex() == expected_tx # Test corrupted signature in scriptsig. inp2ext.script_sig[10] ^= 1 with pytest.raises(TrezorFailure, match="Invalid signature"): _, serialized_tx = btc.sign_tx( client, "Testnet", [inp1, inp2ext], [out1, out2], prev_txes=TX_CACHE_TESTNET, )
def test_send_multisig_1(self, client): nodes = [ btc.get_public_node( client, parse_path(f"49'/156'/{i}'"), coin_name="Bgold" ).node for i in range(1, 4) ] multisig = proto.MultisigRedeemScriptType( nodes=nodes, address_n=[1, 0], signatures=[b"", b"", b""], m=2 ) inp1 = proto.TxInputType( address_n=parse_path("49'/156'/1'/1/0"), prev_hash=TXHASH_25526b, prev_index=0, script_type=proto.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1252382934, ) out1 = proto.TxOutputType( address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe", amount=1252382934 - 1000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses( [ request_input(0), request_meta(TXHASH_25526b), request_input(0, TXHASH_25526b), request_output(0, TXHASH_25526b), request_output(1, TXHASH_25526b), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(0), request_output(0), request_input(0), request_finished(), ] ) signatures, _ = btc.sign_tx( client, "Bgold", [inp1], [out1], prev_txes=TX_API ) # store signature inp1.multisig.signatures[0] = signatures[0] # sign with third key inp1.address_n[2] = H_(3) client.set_expected_responses( [ request_input(0), request_meta(TXHASH_25526b), request_input(0, TXHASH_25526b), request_output(0, TXHASH_25526b), request_output(1, TXHASH_25526b), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(0), request_output(0), request_input(0), request_finished(), ] ) _, serialized_tx = btc.sign_tx( client, "Bgold", [inp1], [out1], prev_txes=TX_API ) assert ( btc_hash(serialized_tx)[::-1].hex() == "efa5b21916ac7ea5316c38b2d7d5520d80cbe563c58304f956ea6ddb241001d1" )
def test_show_multisig_xpubs(self, client): nodes = [ btc.get_public_node(client, tools.parse_path(f"48h/0h/{i}h"), coin_name="Bitcoin") for i in range(3) ] multisig = messages.MultisigRedeemScriptType( nodes=[n.node for n in nodes], signatures=[b"", b"", b""], address_n=[0, 0], m=2, ) xpubs = [[n.xpub[i * 16:(i + 1) * 16] for i in range(5)] for n in nodes] for i in range(3): def input_flow(): yield # show address assert client.debug.wait_layout().lines == [ "Multisig 2 of 3", "34yJV2b2GtbmxfZNw", "jPyuyUYkUbUnogqa8", ] client.debug.press_no() yield # show QR code assert client.debug.wait_layout().text.startswith("Qr") client.debug.press_no() yield # show XPUB#1 lines = client.debug.wait_layout().lines assert lines[0] == "XPUB #1 " + ("(yours)" if i == 0 else "(others)") assert lines[1:] == xpubs[0] # just for UI test client.debug.swipe_up() client.debug.press_no() yield # show XPUB#2 lines = client.debug.wait_layout().lines assert lines[0] == "XPUB #2 " + ("(yours)" if i == 1 else "(others)") assert lines[1:] == xpubs[1] # just for UI test client.debug.swipe_up() client.debug.press_no() yield # show XPUB#3 lines = client.debug.wait_layout().lines assert lines[0] == "XPUB #3 " + ("(yours)" if i == 2 else "(others)") assert lines[1:] == xpubs[2] # just for UI test client.debug.swipe_up() client.debug.press_yes() with client: client.set_input_flow(input_flow) btc.get_address( client, "Bitcoin", tools.parse_path(f"48h/0h/{i}h/0/0"), show_display=True, multisig=multisig, script_type=messages.InputScriptType.SPENDMULTISIG, )
def test_one_one_rewards_claim(self, client): # prevout: 7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1:0 # input 1: 10.9997 KMD inp1 = proto.TxInputType( address_n=parse_path( "44'/141'/0'/0/0"), # R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi amount=1099970000, prev_hash=TXHASH_7b28bd, prev_index=0, ) out1 = proto.TxOutputType( address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi", amount=1099970000 - 10000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) # kmd interest, vout sum > vin sum out2 = proto.TxOutputType( address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi", amount=79605, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: er = [ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), ] if TREZOR_VERSION != 1: # extra screen for lock_time er += [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx) ] er += [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] client.set_expected_responses(er) details = proto.SignTx( version=4, overwintered=True, version_group_id=0x892F2085, branch_id=0x76B809BB, lock_time=0x5D2AF1F2, ) _, serialized_tx = btc.sign_tx( client, "Komodo", [inp1], [out1, out2], details=details, prev_txes=TX_API, ) # Accepted by network: tx c775678ceb18277729b427c7acf2f8ce63ac02fc2366f47ce08a3f443ff0e059 assert ( serialized_tx.hex() == "0400008085202f8901b134cddb4951fe1acd7744bf9b828a816501570ed8ebd4f076979e1191bd287b000000006a4730440220483a58f5be3a147c773c663008c992a7fcea4d03bdf4c1d4bc0535c0d98ddf0602207b19d69140dd00c7a94f048c712aeaed55dfd27f581c7212d9cc5e476fe1dc9f012102a87aef7b1a8f676e452d6240767699719cd58b0261c822472c25df146938bca5ffffffff02c00e9041000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acf5360100000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acf2f12a5d000000000000000000000000000000" )
def test_send_bch_multisig_change(self): self.setup_mnemonic_allallall() nodes = [ btc.get_public_node(self.client, parse_path("48'/145'/%d'" % i)).node for i in range(1, 4) ] def getmultisig(chain, nr, signatures=[b"", b"", b""], nodes=nodes): return proto.MultisigRedeemScriptType(nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2) inp1 = proto.TxInputType( address_n=parse_path("48'/145'/3'/0/0"), multisig=getmultisig(0, 0), amount=48490, prev_hash=bytes.fromhex( "8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0" ), prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, ) out1 = proto.TxOutputType( address="bitcoincash:qqq8gx2j76nw4dfefumxmdwvtf2tpsjznusgsmzex9", amount=24000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address_n=parse_path("48'/145'/3'/1/0"), multisig=getmultisig(1, 0), script_type=proto.OutputScriptType.PAYTOMULTISIG, amount=24000, ) with self.client: self.client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) (signatures1, serialized_tx) = btc.sign_tx(self.client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API) assert ( signatures1[0].hex() == "3045022100a05f77bb39515c21c43e6c4ba401f39ed5d409dc3cfcd90f9a8345a08cc4bc8202205faf8f3b0775748278495324fdd60f370460452e4995e546450209ec4804a0f3" ) inp1 = proto.TxInputType( address_n=parse_path("48'/145'/1'/0/0"), multisig=getmultisig(0, 0, [b"", b"", signatures1[0]]), # bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw amount=48490, prev_hash=bytes.fromhex( "8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0" ), prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, ) out2.address_n[2] = H_(1) with self.client: self.client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) (signatures1, serialized_tx) = btc.sign_tx(self.client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API) assert ( signatures1[0].hex() == "3044022006f239ef1f065a70873ab9d2c81a623a04ec7a37a0ec5299d3c585668f441f49022032b2f9ef13bc61230d14f6d79b9ad1bbebdf47b95e4757e9af1b1dcdf520d3ab" ) assert ( serialized_tx.hex() == "0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfd0000473044022006f239ef1f065a70873ab9d2c81a623a04ec7a37a0ec5299d3c585668f441f49022032b2f9ef13bc61230d14f6d79b9ad1bbebdf47b95e4757e9af1b1dcdf520d3ab41483045022100a05f77bb39515c21c43e6c4ba401f39ed5d409dc3cfcd90f9a8345a08cc4bc8202205faf8f3b0775748278495324fdd60f370460452e4995e546450209ec4804a0f3414c69522102f8ca0d9665af03de32a7c19a167a4f6e97e4e0ed9505f75d11f7a45ab60b1f4d2103263d87cefd687bc15b4ef7801f9f538267b66d46f18e9fccc41d54071cfdd1ce210388568bf42f02298308eb6fa2fa4b446d544600253b4409be27e2c0c1a71c424853aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a91478574751407449b97f8054be2e40e684ad07d3738700000000" )
def test_one_one_fee_sapling(self, client): # prevout: 2807c5b126ec8e2b078cab0f12e4c8b4ce1d7724905f8ebef8dca26b0c8e0f1d:0 # input 1: 10.9998 KMD inp1 = proto.TxInputType( address_n=parse_path( "44'/141'/0'/0/0"), # R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi amount=1099980000, prev_hash=TXHASH_2807c, prev_index=0, ) out1 = proto.TxOutputType( address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi", amount=1099980000 - 10000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: er = [ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), ] if TREZOR_VERSION != 1: # extra screen for lock_time er += [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx) ] er += [ proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] client.set_expected_responses(er) details = proto.SignTx( version=4, overwintered=True, version_group_id=0x892F2085, branch_id=0x76B809BB, lock_time=0x5D2A30B8, ) _, serialized_tx = btc.sign_tx(client, "Komodo", [inp1], [out1], details=details, prev_txes=TX_API) # Accepted by network: tx 7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1 assert ( serialized_tx.hex() == "0400008085202f89011d0f8e0c6ba2dcf8be8e5f9024771dceb4c8e4120fab8c072b8eec26b1c50728000000006a4730440220158c970ca2fc6bcc33026eb5366f0342f63b35d178f7efb334b1df78fe90b67202207bc4ff69f67cf843b08564a5adc77bf5593e28ab4d5104911824ac13fe885d8f012102a87aef7b1a8f676e452d6240767699719cd58b0261c822472c25df146938bca5ffffffff01d0359041000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acb8302a5d000000000000000000000000000000" )
def test_attack_amount(self): self.setup_mnemonic_allallall() inp1 = proto.TxInputType( address_n=parse_path("44'/145'/0'/1/0"), # bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw amount=300, prev_hash=bytes.fromhex( "502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c" ), prev_index=0, script_type=proto.InputScriptType.SPENDADDRESS, ) inp2 = proto.TxInputType( address_n=parse_path("44'/145'/0'/0/1"), # bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4 amount=70, prev_hash=bytes.fromhex( "502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c" ), prev_index=1, script_type=proto.InputScriptType.SPENDADDRESS, ) out1 = proto.TxOutputType( address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4", amount=200, script_type=proto.OutputScriptType.PAYTOADDRESS, ) # test if passes without modifications with self.client: self.client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) btc.sign_tx(self.client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API) run_attack = True def attack_processor(msg): nonlocal run_attack if run_attack and msg.tx.inputs and msg.tx.inputs[0] == inp1: # 300 is lowered to 280 at the first run # the user confirms 280 but the transaction # is spending 300 => larger fee without the user knowing msg.tx.inputs[0].amount = 280 run_attack = False return msg # now fails self.client.set_filter(proto.TxAck, attack_processor) with self.client: self.client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.Failure(), ]) with pytest.raises(CallException) as exc: btc.sign_tx(self.client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API) assert exc.value.args[0] in ( proto.FailureType.ProcessError, proto.FailureType.DataError, ) assert exc.value.args[1].endswith( "Transaction has changed during signing")
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the License along with this library. # If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>. import pytest from trezorlib import eos from trezorlib.messages import EosSignedTx from trezorlib.tools import parse_path from ..common import MNEMONIC12 CHAIN_ID = "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f" ADDRESS_N = parse_path("m/44'/194'/0'/0/0") @pytest.mark.altcoin @pytest.mark.eos @pytest.mark.skip_t1 @pytest.mark.setup_client(mnemonic=MNEMONIC12) class TestMsgEosSignTx: @pytest.mark.setup_client(uninitialized=True) def input_flow(self, debug, pages): # confirm number of actions yield debug.press_yes() # swipe through pages yield
def test_attack_change_input(self): self.setup_mnemonic_allallall() inp1 = proto.TxInputType( address_n=parse_path("44'/145'/10'/0/0"), amount=1995344, prev_hash=bytes.fromhex( "bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78" ), prev_index=0, script_type=proto.InputScriptType.SPENDADDRESS, ) out1 = proto.TxOutputType( address_n=parse_path("44'/145'/10'/1/0"), amount=1896050, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4", amount=73452, script_type=proto.OutputScriptType.PAYTOADDRESS, ) run_attack = False def attack_processor(msg): nonlocal run_attack if msg.tx.inputs and msg.tx.inputs[0] == inp1: if not run_attack: run_attack = True else: msg.tx.inputs[0].address_n[2] = H_(1) return msg self.client.set_filter(proto.TxAck, attack_processor) with self.client: self.client.set_expected_responses([ proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.Failure(code=proto.FailureType.ProcessError), ]) with pytest.raises(CallException): btc.sign_tx(self.client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API)