def test_send_bch_multisig_change(self): self.setup_mnemonic_allallall() self.client.set_tx_api(TxApiBcash) xpubs = [] for n in map( lambda index: btc.get_public_node( self.client, parse_path("44'/145'/%d'" % index)), range(1, 4), ): xpubs.append(n.xpub) def getmultisig(chain, nr, signatures=[b"", b"", b""], xpubs=xpubs): return proto.MultisigRedeemScriptType( pubkeys=list( map( lambda xpub: proto.HDNodePathType( node=deserialize(xpub), address_n=[chain, nr]), xpubs, )), signatures=signatures, m=2, ) inp1 = proto.TxInputType( address_n=parse_path("44'/145'/3'/0/0"), multisig=getmultisig(0, 0), # bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw 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("44'/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]) assert ( signatures1[0].hex() == "3045022100bcb1a7134a13025a06052546ee1c6ac3640a0abd2d130190ed13ed7fcb43e9cd02207c381478e2ee123c850425bfbf6d3c691230eb37e333832cb32a1ed3f2cd9e85" ) inp1 = proto.TxInputType( address_n=parse_path("44'/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]) assert ( signatures1[0].hex() == "3045022100f1153636371ba1f84389460e1265a8fa296569bc18e117c31f4e8f0fc0650c01022022932cc84766ff0c0f65ed9633ad311ae90d4c8fe71f5e1890b1e8f74dd516fa" ) assert ( serialized_tx.hex() == "0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfe0000483045022100f1153636371ba1f84389460e1265a8fa296569bc18e117c31f4e8f0fc0650c01022022932cc84766ff0c0f65ed9633ad311ae90d4c8fe71f5e1890b1e8f74dd516fa41483045022100bcb1a7134a13025a06052546ee1c6ac3640a0abd2d130190ed13ed7fcb43e9cd02207c381478e2ee123c850425bfbf6d3c691230eb37e333832cb32a1ed3f2cd9e85414c69522102fcf63419c319ce1a42d69120a3599d6da8c5dd4caf2888220eccde5a1ff7c5d021036d7d5ef79370b7fabe2c058698a20219e97fc70868e65ecdd6b37cc18e8a88bd2103505dc649dab8cd1655a4c0daf0ec5f955881c9d7011478ea881fac11cab1e49953aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a914756c06d7e77de3950a6124f026d8e1a2464b3ecf8700000000" )
def test_ethereum_getaddress(self): self.setup_mnemonic_nopin_nopassphrase() assert ( ethereum.get_address(self.client, [H_(44), H_(60)]).hex() == "e025dfbe2c53638e547c6487ded34add7b8aafc1" ) assert ( ethereum.get_address(self.client, [H_(44), H_(60), 1]).hex() == "ed46c856d0c79661cf7d40ffe0c0c5077c00e898" ) assert ( ethereum.get_address(self.client, [H_(44), H_(60), 0, H_(1)]).hex() == "6682fa7f3ec58581b1e576268b5463b4b5c93839" ) assert ( ethereum.get_address(self.client, [H_(44), H_(60), H_(9), 0]).hex() == "fb3be0f9717ff5fcf3c58eb49a9ed67f1bd89d4e" ) assert ( ethereum.get_address(self.client, [H_(44), H_(60), 0, 9999999]).hex() == "6b909b50d88c9a8e02453a87b3662e3e7a5e0cf1" )
def test_send_btg_multisig_change(self): self.setup_mnemonic_allallall() xpubs = [] for n in map( lambda index: btc.get_public_node( self.client, parse_path("48'/156'/%d'" % index)), range(1, 4), ): xpubs.append(n.xpub) def getmultisig(chain, nr, signatures=[b"", b"", b""], xpubs=xpubs): return proto.MultisigRedeemScriptType( nodes=[deserialize(xpub) for xpub in xpubs], 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=48490, prev_hash=bytes.fromhex( "25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985" ), 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=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), ]) signatures, serialized_tx = btc.sign_tx(self.client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API) assert ( signatures[0].hex() == "3045022100d954f341ddd3ec96e4bc6cdb90f2df9b2032723f85e4a0187346dd743130bfca0220105ce08b795c70dc09a55569d7874bff684a877219ec2fc37c88cdffe12f332c" ) inp1 = proto.TxInputType( address_n=parse_path("48'/156'/1'/0/0"), multisig=getmultisig(0, 0, [b"", b"", signatures[0]]), amount=48490, prev_hash=bytes.fromhex( "25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985" ), 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), ]) signatures, serialized_tx = btc.sign_tx(self.client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API) assert ( signatures[0].hex() == "30440220614f9a18695365a2edba0d930404a77cae970d3430ad86c5b5239a96fd54bf84022030bc76a322e3b2b1c987622b5eb6da23ac1e6c905ee9b3b6405a4e4edd5bbb87" ) assert ( serialized_tx.hex() == "010000000185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b522500000000fdfd00004730440220614f9a18695365a2edba0d930404a77cae970d3430ad86c5b5239a96fd54bf84022030bc76a322e3b2b1c987622b5eb6da23ac1e6c905ee9b3b6405a4e4edd5bbb8741483045022100d954f341ddd3ec96e4bc6cdb90f2df9b2032723f85e4a0187346dd743130bfca0220105ce08b795c70dc09a55569d7874bff684a877219ec2fc37c88cdffe12f332c414c695221035a8db79c0ef57a202664a3da60ca41e8865c6d86ed0aafc03f8e75173341b58021037fba152d8fca660cc49973d8bc9421ff49a75b44ea200873d70d3990f763ed4c210348cbcbd93e069416e0d5db93e86b5698852d9fd54502ad0bed9722fa83f90e4b53aeffffffff02c05d0000000000001976a914ea5f904d195079a350b534db4446433b3cec222e88acc05d00000000000017a914623c803f7fb654dac8dda7786fbf9bc38cd867f48700000000" )
def test_send_multisig_1(self): self.setup_mnemonic_allallall() nodes = map( lambda index: btc.get_public_node( self.client, parse_path("49'/1'/%d'" % index)), range(1, 4), ) multisig = proto.MultisigRedeemScriptType( nodes=[deserialize(n.xpub) for n in nodes], address_n=[1, 0], signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("49'/1'/1'/1/0"), prev_hash=bytes.fromhex( "9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be" ), prev_index=1, script_type=proto.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1610436, ) out1 = proto.TxOutputType( address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC", amount=1605000, 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) signatures, _ = btc.sign_tx(self.client, "Testnet", [inp1], [out1], prev_txes=TX_API) # store signature inp1.multisig.signatures[0] = signatures[0] # sign with third key inp1.address_n[2] = H_(3) 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(self.client, "Testnet", [inp1], [out1], prev_txes=TX_API) assert ( serialized_tx.hex() == "01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c0100000023220020cf28684ff8a6dda1a7a9704dde113ddfcf236558da5ce35ad3f8477474dbdaf7ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402203fc3fbe6cd6250d82ace4a585debc07587c07d2efc8bb56558c91e1f810fe65402206025bd9a4e80960f617b6e5bfdd568e34aa085d093471b7976e6b14c2a2402a7014730440220327abf491a57964d75c67fad204eb782fa74aa4abde40e5ad30fb0b7696102b7022049e31f2302417be0a87e2f818b93a862a7e67d4178b7cbeee680264f0882113f0169522103d54ab3c8b81cb7f8f8088df4c62c105e8acaa2fb53b180f6bc6f922faecf3fdc21036aa47994f3f18f0976d6073ca79997003c3fa29c4f93907998fefc1151b4529b2102a092580f2828272517c402da9461425c5032860ab40180e041fbbb88ea2a520453ae00000000" )
def test_send_btg_multisig_change(self, client): nodes = [ btc.get_public_node(client, parse_path(f"48'/156'/{i}'/0'"), coin_name="Bgold").node for i in range(1, 4) ] EMPTY_SIGS = [b"", b"", b""] def getmultisig(chain, nr, signatures): 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/0"), multisig=getmultisig(0, 0, EMPTY_SIGS), # 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'/0'/1/0"), multisig=getmultisig(1, 0, EMPTY_SIGS), script_type=proto.OutputScriptType.PAYTOMULTISIG, amount=1252382934 - 24000 - 1000, ) with client: client.set_expected_responses([ request_input(0), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), request_output(1), proto.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_25526b), request_input(0, TXHASH_25526b), request_output(0, TXHASH_25526b), request_output(1, TXHASH_25526b), 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() == "30440220263c427e6e889c161206edee39b9b969350c154ddd8eb76d2ab8ca8e0fc083b702200fb1d0ef430fa2d0293dcbb0b237775d4f9748222a6ed9fc3ff747837b99020a" ) inp1 = proto.TxInputType( address_n=parse_path("48'/156'/1'/0'/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_output(0), proto.ButtonRequest(code=B.ConfirmOutput), request_output(1), proto.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_25526b), request_input(0, TXHASH_25526b), request_output(0, TXHASH_25526b), request_output(1, TXHASH_25526b), 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() == "3045022100c9094b060b4b095e78403493912b0e06ca12ffbdc0f2fbeec20b02d7eaa73f8702206813e33e04a2b9c4493ecfa2024f2e9d69b5a2ab5c10433d9ab762add5bdde27" ) assert ( btc_hash(serialized_tx)[::-1].hex() == "2677130ec0c5eea2249787fe17b85770cfb35dfce550830a7fb6c6acd9375114")
def test_send_multisig_3_change(self, client): nodes = [ btc.get_public_node(client, parse_path("84'/1'/%d'" % index)) for index in range(1, 4) ] multisig = proto.MultisigRedeemScriptType( nodes=[deserialize(n.xpub) for n in nodes], address_n=[1, 0], signatures=[b"", b"", b""], m=2, ) multisig2 = proto.MultisigRedeemScriptType( nodes=[deserialize(n.xpub) for n in nodes], address_n=[1, 1], signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("84'/1'/1'/1/0"), prev_hash=bytes.fromhex( "c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc" ), prev_index=0, script_type=proto.InputScriptType.SPENDWITNESS, multisig=multisig, amount=1604000, ) out1 = proto.TxOutputType( address_n=parse_path("84'/1'/1'/1/1"), amount=1603000, multisig=multisig2, script_type=proto.OutputScriptType.PAYTOP2SHWITNESS, ) 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) signatures, _ = btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API) # store signature inp1.multisig.signatures[0] = signatures[0] # sign with third key inp1.address_n[2] = H_(3) out1.address_n[2] = H_(3) 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API) assert ( serialized_tx.hex() == "01000000000101fc7901dd033f8c02da14f3ac916b6498036b80b4a0b4dc124e02c2bb408034c90000000000ffffffff01b87518000000000017a914536250d41937e5b641082447580ff6a8e46c122a870400473044022003c26107a5a47f1f900ef8aa758977530cd13ea37a33971abae8d75cac2f9f34022039e2b8c2c1d0c24ff4fc026652e1f27ad8e3ed6c9bf485f61d9aa691cb57830801483045022100963b0dc0ab46e963a66ab6e69e5e41bac6c4fedc127cac12c560b029d54fe87402205b3bcdcf313dccd78e5dce0540e7d3c8cc1bf83f13c1f9f01811eb791fd35c8101695221039dba3a72f5dc3cad17aa924b5a03c34561465f997d0cb15993f2ca2c0be771c42103cd39f3f08bbd508dce4d307d57d0c70c258c285878bfda579fa260acc738c25d2102cd631ba95beca1d64766f5540885092d0bb384a3c13b6c3a5334d0ebacf51b9553ae00000000" )
def test_ethereum_getaddress(self, client): assert ( ethereum.get_address(client, [H_(44), H_(60)]) == "0xE025dfbE2C53638E547C6487DED34Add7b8Aafc1" ) assert ( ethereum.get_address(client, [H_(44), H_(60), 1]) == "0xeD46C856D0c79661cF7d40FFE0C0C5077c00E898" ) assert ( ethereum.get_address(client, [H_(44), H_(60), 0, H_(1)]) == "0x6682Fa7F3eC58581b1e576268b5463B4b5c93839" ) assert ( ethereum.get_address(client, [H_(44), H_(60), H_(9), 0]) == "0xFb3BE0F9717fF5fCF3C58EB49a9Ed67F1BD89D4E" ) assert ( ethereum.get_address(client, [H_(44), H_(60), 0, 9999999]) == "0x6b909b50d88c9A8E02453A87b3662E3e7a5E0CF1" ) assert ( ethereum.get_address(client, [H_(44), H_(6060), 0, 9999999]) == "0x98b8e926bd224764De2A0E4f4CBe1521474050AF" ) # Wanchain SLIP44 id assert ( ethereum.get_address(client, [H_(44), H_(5718350), H_(0)]) == "0x4d643B1b556E14A27143a38bcE61230FFf5AFca8" )
def test_send_multisig_4_change(self): self.setup_mnemonic_allallall() self.client.set_tx_api(TxApiTestnet) nodes = [ btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index)) for index in range(1, 4) ] multisig = proto.MultisigRedeemScriptType( pubkeys=list( map( lambda n: proto.HDNodePathType( node=deserialize(n.xpub), address_n=[1, 1] ), nodes, ) ), signatures=[b"", b"", b""], m=2, ) multisig2 = proto.MultisigRedeemScriptType( pubkeys=list( map( lambda n: proto.HDNodePathType( node=deserialize(n.xpub), address_n=[1, 2] ), nodes, ) ), signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("999'/1'/1'/1/1"), prev_hash=bytes.fromhex( "31bc1c88ce6ae337a6b3057a16d5bad0b561ad1dfc047d0a7fbb8814668f91e5" ), prev_index=0, script_type=proto.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1603000, ) out1 = proto.TxOutputType( address_n=parse_path("999'/1'/1'/1/2"), amount=1602000, multisig=multisig2, script_type=proto.OutputScriptType.PAYTOWITNESS, ) 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures1, _) = btc.sign_tx(self.client, "Testnet", [inp1], [out1]) # store signature inp1.multisig.signatures[0] = signatures1[0] # sign with third key inp1.address_n[2] = H_(3) out1.address_n[2] = H_(3) 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures2, serialized_tx) = btc.sign_tx( self.client, "Testnet", [inp1], [out1] ) # c0bf56060a109624b4635222696d94a7d533cacea1b3f8245417a4348c045829 assert ( serialized_tx.hex() == "01000000000101e5918f661488bb7f0a7d04fc1dad61b5d0bad5167a05b3a637e36ace881cbc3100000000232200205b9824093eaf5cdcf8247c00dc0b557a7720957828fcde8384ac11f80a91f403ffffffff01d071180000000000220020e77caf5fbef07b1e461475c02afd4aed877693263d69c81e14617304349b629a040047304402204832553b0da1009da496881e58e8e2e41010cfe5c0161623048093f1b1a817b7022020dad8bf887acf574af80bfe4b39cd24e95019fd5e6b8ae967471e21ddc67354014830450221009e5d60847e7275edcf4619ed8ee462c56a042eef75d17da2d44e6b13d78e50e50220665195492900ef87a5eb8a924fa0ac9afc4fc75ca704ff356dc3a213979970c80169522103f4040006e3561b3e76c6d4113225c84748ab9d55ffd23f9578ab4c18fb0c3b9721020975f2e6922897ff6b80da6412a8d6ebd67e33c9611d081656a53ef967964e5021026b0546f23a6ce6b756c2c30b4176ce6f1c3268744f7aca82668d5116c4f764e453ae00000000" )
def test_send_bch_multisig_change(self, 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 proto.MultisigRedeemScriptType(nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2) inp1 = proto.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=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'/0'/1/0"), multisig=getmultisig(1, 0, EMPTY_SIGNATURES), script_type=proto.OutputScriptType.PAYTOMULTISIG, amount=24000, ) with client: client.set_expected_responses([ request_input(0), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), request_output(1), proto.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 = proto.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=proto.InputScriptType.SPENDMULTISIG, ) out2.address_n[2] = H_(1) with client: client.set_expected_responses([ request_input(0), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), request_output(1), proto.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_send_multisig_2(self): self.setup_mnemonic_allallall() self.client.set_tx_api(TxApiTestnet) nodes = [ btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index)) for index in range(1, 4) ] multisig = proto.MultisigRedeemScriptType( pubkeys=list( map( lambda n: proto.HDNodePathType( node=deserialize(n.xpub), address_n=[2, 1] ), nodes, ) ), signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("999'/1'/2'/2/1"), prev_hash=bytes.fromhex( "f41cbedd8becee05a830f418d13aa665125464547db5c7a6cd28f21639fe1228" ), prev_index=0, script_type=proto.InputScriptType.SPENDWITNESS, multisig=multisig, amount=1605000, ) out1 = proto.TxOutputType( address="tb1qr6xa5v60zyt3ry9nmfew2fk5g9y3gerkjeu6xxdz7qga5kknz2ssld9z2z", amount=1604000, 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures1, _) = btc.sign_tx(self.client, "Testnet", [inp1], [out1]) # store signature inp1.multisig.signatures[1] = signatures1[0] # sign with first key inp1.address_n[2] = H_(1) 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures2, serialized_tx) = btc.sign_tx( self.client, "Testnet", [inp1], [out1] ) # c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc assert ( serialized_tx.hex() == "010000000001012812fe3916f228cda6c7b57d5464541265a63ad118f430a805eeec8bddbe1cf40000000000ffffffff01a0791800000000002200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a10400483045022100cc97f21a7cabc543a9b4ac52424e8f7e420622903f2417a1c08a6af68058ec4a02200baca0b222fc825078d94e8e1b55f174c4828bed16697e4281cda2a0c799eecf01473044022009b8058dc30fa7a13310dd8f1a99c4341c4cd95f771c5a41c4381f956e2344c102205e829c560c0184fd4b4db8971f99711e2a87409afa4df0840b4f12a87b2c8afc0169522102740ec30d0af8591a0dd4a3e3b274e57f3f73bdc0638a9603f9ee6ade0475ba57210311aada919974e882abf0c67b5c0fba00000b26997312ca00345027d22359443021029382591271a79d4b12365fa27c67fad3753150d8eaa987e5a12dc5ba1bb2fa1653ae00000000" )
def test_send_multisig_3_change(self): self.setup_mnemonic_allallall() self.client.set_tx_api(TxApiTestnet) nodes = [ btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index)) for index in range(1, 4) ] multisig = proto.MultisigRedeemScriptType( pubkeys=list( map( lambda n: proto.HDNodePathType( node=deserialize(n.xpub), address_n=[2, 0] ), nodes, ) ), signatures=[b"", b"", b""], m=2, ) multisig2 = proto.MultisigRedeemScriptType( pubkeys=list( map( lambda n: proto.HDNodePathType( node=deserialize(n.xpub), address_n=[1, 1] ), nodes, ) ), signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("999'/1'/1'/2/0"), prev_hash=bytes.fromhex( "c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc" ), prev_index=0, script_type=proto.InputScriptType.SPENDWITNESS, multisig=multisig, amount=1604000, ) out1 = proto.TxOutputType( address_n=parse_path("999'/1'/1'/1/1"), amount=1603000, multisig=multisig2, script_type=proto.OutputScriptType.PAYTOP2SHWITNESS, ) 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures1, _) = btc.sign_tx(self.client, "Testnet", [inp1], [out1]) # store signature inp1.multisig.signatures[0] = signatures1[0] # sign with third key inp1.address_n[2] = H_(3) out1.address_n[2] = H_(3) 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures2, serialized_tx) = btc.sign_tx( self.client, "Testnet", [inp1], [out1] ) # 31bc1c88ce6ae337a6b3057a16d5bad0b561ad1dfc047d0a7fbb8814668f91e5 assert ( serialized_tx.hex() == "01000000000101fc7901dd033f8c02da14f3ac916b6498036b80b4a0b4dc124e02c2bb408034c90000000000ffffffff01b87518000000000017a914a8655acf68f785125561158b0f4db9b5d0044047870400473044022057b571986c07f8ccb231811334ad06ee6f87b722495def2e9511c1da46f3433202207b6e95bdd99e7fc7d319486437cb930d40a4af3cd753c4cb960b330badbf7f35014730440220517ecc6d0a2544276921d8fc2077aec4285ab83b1b21f5eb73cdb6187a0583e4022043fb5ab942f8981c04a54c66a57c4d291fad8514d4a8afea09f01f2db7a8f32901695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000" )
def test_send_multisig_1(self): self.setup_mnemonic_allallall() self.client.set_tx_api(TxApiTestnet) nodes = [ btc.get_public_node(self.client, parse_path("999'/1'/%d'" % index)) for index in range(1, 4) ] multisig = proto.MultisigRedeemScriptType( pubkeys=list( map( lambda n: proto.HDNodePathType( node=deserialize(n.xpub), address_n=[2, 0] ), nodes, ) ), signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("999'/1'/1'/2/0"), prev_hash=bytes.fromhex( "9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be" ), prev_index=1, script_type=proto.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1610436, ) out1 = proto.TxOutputType( address="tb1qch62pf820spe9mlq49ns5uexfnl6jzcezp7d328fw58lj0rhlhasge9hzy", amount=1605000, 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures1, _) = btc.sign_tx(self.client, "Testnet", [inp1], [out1]) # store signature inp1.multisig.signatures[0] = signatures1[0] # sign with third key inp1.address_n[2] = H_(3) 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures2, serialized_tx) = btc.sign_tx( self.client, "Testnet", [inp1], [out1] ) # f41cbedd8becee05a830f418d13aa665125464547db5c7a6cd28f21639fe1228 assert ( serialized_tx.hex() == "01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d180000000000220020c5f4a0a4ea7c0392efe0a9670a73264cffa90b19107cd8a8e9750ff93c77fdfb0400483045022100a9b681f324ff4cf419ab06820d07248cc4e359c77334bf448ae7b5cdf3995ddf022039811f91f55b602368b4ba08a217b82bfd62d1a97dc635deb1457e7cfcc1550b0147304402201ad86a795c3d26881d696fa0a0619c24c4d505718132a82965cc2a609c9d8798022067cd490ce1366cde77e307ced5b13040bbc04991619ea6f49e06cece9a83268b01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000" )
def test_send_multisig_1(self): self.setup_mnemonic_allallall() self.client.set_tx_api(TxApiTestnet) nodes = map( lambda index: btc.get_public_node( self.client, parse_path("999'/1'/%d'" % index) ), range(1, 4), ) multisig = proto.MultisigRedeemScriptType( pubkeys=list( map( lambda n: proto.HDNodePathType( node=deserialize(n.xpub), address_n=[2, 0] ), nodes, ) ), signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("999'/1'/1'/2/0"), prev_hash=bytes.fromhex( "9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be" ), prev_index=1, script_type=proto.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1610436, ) out1 = proto.TxOutputType( address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC", amount=1605000, 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures1, _) = btc.sign_tx(self.client, "Testnet", [inp1], [out1]) # store signature inp1.multisig.signatures[0] = signatures1[0] # sign with third key inp1.address_n[2] = H_(3) 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ] ) (signatures2, serialized_tx) = btc.sign_tx( self.client, "Testnet", [inp1], [out1] ) assert ( serialized_tx.hex() == "01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402205b44c20cf2681690edaaf7cd2e30d4704124dd8b7eb1fb7f459d3906c3c374a602205ca359b6544ce2c101c979899c782f7d141c3b0454ea69202b1fb4c09d3b715701473044022052fafa64022554ae436dbf781e550bf0d326fef31eea1438350b3ff1940a180102202851bd19203b7fe8582a9ef52e82aa9f61cd52d4bcedfe6dcc0cf782468e6a8e01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000" )
nodes=[NODE_EXT1, NODE_EXT2, NODE_INT], address_n=[0, 1], signatures=[b"", b"", b""], m=2, ) multisig_in3 = messages.MultisigRedeemScriptType( nodes=[NODE_EXT1, NODE_EXT3, NODE_INT], address_n=[0, 1], signatures=[b"", b"", b""], m=2, ) # 2N9W4z9AhAPaHghtqVQPbaTAGHdbrhKeBQw INP1 = messages.TxInputType( address_n=[H_(45), 0, 0, 0], amount=50000000, prev_hash=TXHASH_16c6c8, prev_index=1, script_type=messages.InputScriptType.SPENDMULTISIG, multisig=multisig_in1, ) # 2NDBG6QXQLtnQ3jRGkrqo53BiCeXfQXLdj4 INP2 = messages.TxInputType( address_n=[H_(45), 0, 0, 1], amount=34500000, prev_hash=TXHASH_d80c34, prev_index=0, script_type=messages.InputScriptType.SPENDMULTISIG, multisig=multisig_in2,
def test_send_multisig_1(self, client): nodes = [ btc.get_public_node(client, parse_path("49'/1'/%d'" % index)) for index in range(1, 4) ] multisig = proto.MultisigRedeemScriptType( nodes=[deserialize(n.xpub) for n in nodes], address_n=[0, 0], signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("49'/1'/1'/0/0"), prev_hash=bytes.fromhex( "9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be" ), prev_index=1, script_type=proto.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1610436, ) out1 = proto.TxOutputType( address= "tb1qch62pf820spe9mlq49ns5uexfnl6jzcezp7d328fw58lj0rhlhasge9hzy", amount=1605000, 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) signatures, _ = btc.sign_tx(client, "Testnet", [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([ 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API) assert ( serialized_tx.hex() == "01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200208d398cfb58a1d9cdb59ccbce81559c095e8c6f4a3e64966ca385078d9879f95effffffff01887d180000000000220020c5f4a0a4ea7c0392efe0a9670a73264cffa90b19107cd8a8e9750ff93c77fdfb0400483045022100dd6342c65197af27d7894d8b8b88b16b568ee3b5ebfdc55fdfb7caa9650e3b4c02200c7074a5bcb0068f63d9014c7cd2b0490aba75822d315d41aad444e9b86adf5201483045022100e7e6c2d21109512ba0609e93903e84bfb7731ac3962ee2c1cad54a7a30ff99a20220421497930226c39fc3834e8d6da3fc876516239518b0e82e2dc1e3c46271a17c01695221021630971f20fa349ba940a6ba3706884c41579cd760c89901374358db5dd545b92102f2ff4b353702d2bb03d4c494be19d77d0ab53d16161b53fbcaf1afeef4ad0cb52103e9b6b1c691a12ce448f1aedbbd588e064869c79fbd760eae3b8cd8a5f1a224db53ae00000000" )
def test_ethereum_signtx_eip155(self): # chain_id, nonce, sig_v, sig_r, sig_s, value, gas_limit, data VECTORS = [ ( 3, 0, 41, b"a90d0bc4f8d63be69453dd62f2bb5fff53c610000abf956672564d8a654d401a", b"544a2e57bc8b4da18660a1e6036967ea581cc635f5137e3ba97a750867c27cf2", 100000000000000000, 21000, None, ), ( 3, 1, 42, b"699428a6950e23c6843f1bf3754f847e64e047e829978df80d55187d19a401ce", b"087343d0a3a2f10842218ffccb146b59a8431b6245ab389fde22dc833f171e6e", 100000000000000000, 21000, None, ), ( 3, 2, 42, b"ba85b622a8bb82606ba96c132e81fa8058172192d15bc41d7e57c031bca17df4", b"6473b75997634b6f692f8d672193591d299d5bf1c2d6e51f1a14ed0530b91c7d", 100000000000000000, 21004, b"\0", ), ( 3, 3, 42, b"d021c98f92859c8db5e4de2f0e410a8deb0c977eb1a631e323ebf7484bd0d79a", b"2c0e9defc9b1e895dc9520ff25ba3c635b14ad70aa86a5ad6c0a3acb82b569b6", 100000000000000000, 299732, b"ABCDEFGHIJKLMNOP" * 256 + b"!!!", ), ( 3, 4, 42, b"dd52f026972a83c56b7dea356836fcfc70a68e3b879cdc8ef2bb5fea23e0a7aa", b"079285fe579c9a2da25c811b1c5c0a74cd19b6301ee42cf20ef7b3b1353f7242", 0, 21004, b"\0", ), ( 1, 1, 37, b"bae6198fdc87ccad6256e543617a34d052bfd17ae3be0bec7fbf8ea34bf9c930", b"7d12f625f3e54700b6ed14ab669f45a8a2b5552c39f0781b0ab3796f19e6b4d1", 0, 21004, b"\0", ), ( 255, 1, 546, b"7597a40719509ae3850d2eba808b7b2f7d272fda316e1321e5ebcc911e9f1b0d", b"269dd69248273820f65b43d8824bb7aff1aa4e35ee663a5433a5df8f0c47dc31", 0, 21004, b"\0", ), ( 256, 1, 547, b"64e9821db2001ff5dff13c9d8c7fb0701ff860f5f95155d378fb9fcc06088f28", b"4d03f339afed717e2155f044a6b0a895b5ac98343f1745e7525870c2046c36bc", 0, 21004, b"\0", ), ( 65535, 1, 131106, b"6f2275808dc328184d7aa019d0a68f8dd8234969576a477670934145bb358969", b"2be1ff9045bccff9ba3d6d5c7789a52c52c9679526dd3ec349caa318c3d055ff", 0, 21004, b"\0", ), ( 65536, 1, 131107, b"e16e35afe534a46e3e4cf09f355cbf02edc01937c2b444238162c2aca79037b8", b"1083b84e21b1cbad95c7ea9792818c18fa716aa25951c5341b48732d611a396a", 0, 21004, b"\0", ), ( 16777215, 1, 33554466, b"f9753ee68cf2af20638cc753945d157039504f82d6d6fe0ec98806b64366c551", b"056b57a69d88a4b71fba993c580d8bbf04f2c857f97a8b7d4b2892b5dafa9114", 0, 21004, b"\0", ), ( 16777216, 1, 33554468, b"23a5399650c6efa46a25a0a966a29119830d9c587b6b93da43cb0be6d3c69059", b"5a6eddffc62317a6a3801608071655a9c43423aef9705b2f5df4212942265c37", 0, 21004, b"\0", ), ( 2147483629, 1, 4294967294, b"6a996586f1ea19afe9cb0ca44dec6bb8643cdf53b5cf148323c94a32a04b087d", b"0d086b208df6826657edf98010972b2649b323466a7ea4b67e7285fb9e829481", 0, 21004, b"\0", ), ( 2147483630, 1, 4294967296, b"fd0377ff429a51ae284c4b09b7d7c26c78944c86bb311b5988d70be4fc59eeba", b"2ad183858ac6b1efa820b9ee2c2dbf6659a73cc5b714d32c380b263d024f2ee9", 0, 21004, None, ), ( 2147483631, 1, 4294967298, b"a4e89720285b179f679ecec1c79e4948b18ee4cf08f76b11d701cbead5e81a70", b"094b32d3e53833c8085dadfe169782db4d32856d7b556f832f64dfdcfa1dd3b8", 100000000000000000, 21000, None, ), ( 3125659152, 1, 6251318340, b"a39e51d16cb10c81a9c1d9b071b714c4ecf112702407f1cc7aae35c85eced3d3", b"0b0654665e4677c77510fc2a43026ee66c13261d3d893895bc49e6f4eaa5c8bd", 1, 21005, None, ), ( 4294967295, 1, 8589934625, b"3367230b5f506426f075f3137f4fd6a5fc4198326dd4936bbc38bf0c5ff43a5e", b"6e48c3c95b3a534f7853a3b5dd72cdeffe9b7e93503eb7a793c9d5fdc14c4e99", 100000000000000000, 21000, None, ), ] self.setup_mnemonic_allallall() for ci, n, sv, sr, ss, v, gl, d in VECTORS: sig_v, sig_r, sig_s = ethereum.sign_tx( self.client, n=[H_(44), H_(1), H_(0), 0, 0], nonce=n, gas_price=20000000000, gas_limit=gl, to=unhexlify("8ea7a3fccc211ed48b763b4164884ddbcf3b0a98"), value=v, chain_id=ci, data=d, ) assert sig_v == sv assert hexlify(sig_r) == sr assert hexlify(sig_s) == ss
def test_send_multisig_2(self, client): nodes = [ btc.get_public_node(client, parse_path("84'/1'/%d'" % index)) for index in range(1, 4) ] multisig = proto.MultisigRedeemScriptType( nodes=[deserialize(n.xpub) for n in nodes], address_n=[0, 1], signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("84'/1'/2'/0/1"), prev_hash=bytes.fromhex( "f41cbedd8becee05a830f418d13aa665125464547db5c7a6cd28f21639fe1228" ), prev_index=0, script_type=proto.InputScriptType.SPENDWITNESS, multisig=multisig, amount=1605000, ) out1 = proto.TxOutputType( address= "tb1qr6xa5v60zyt3ry9nmfew2fk5g9y3gerkjeu6xxdz7qga5kknz2ssld9z2z", amount=1604000, 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) signatures, _ = btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API) # store signature inp1.multisig.signatures[1] = signatures[0] # sign with first key inp1.address_n[2] = H_(1) 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API) assert ( serialized_tx.hex() == "010000000001012812fe3916f228cda6c7b57d5464541265a63ad118f430a805eeec8bddbe1cf40000000000ffffffff01a0791800000000002200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a10400473044022001b7f4f21a8ddcd5e0faaaee3b95515bf8b84f2a7cbfdf66996c64123617a5cf02202fc6a776a7225420dbca759ad4ac83a61d15bf8d2883b6bf1aa31de7437f9b6e0147304402206c4125c1189a3b3e93a77cdf54c60c0538b80e5a03ec74e6ac776dfa77706ee4022035be14de76259b9d8a24863131a06a65b95df02f7d3ace90d52b37e8d94b167f0169522103bab8ecdd9ae2c51a0dc858f4c751b27533143bf6013ba1725ba8a4ecebe7de8c21027d5e55696c875308b03f2ca3d8637f51d3e35da9456a5187aa14b3de8a89534f2103b78eabaea8b3a4868be4f4bb96d6f66973f7081faa7f1cafba321444611c241e53ae00000000" )
class TestMultisigChange: node_ext1 = bip32.deserialize( "xpub69qexv5TppjJQtXwSGeGXNtgGWyUzvsHACMt4Rr61Be4CmCf55eFcuXX828aySNuNR7hQYUCvUgZpioNxfs2HTAZWUUSFywhErg7JfTPv3Y" ) # m/1 => 02c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e # m/2 => 0375b9dfaad928ce1a7eed88df7c084e67d99e9ab74332419458a9a45779706801 node_ext2 = bip32.deserialize( "xpub69qexv5TppjJRiLLK2K1FZNCFcErkXprCo3jabCXMiqX5CFF4LHedwcXvXkTuBL9tFLWVxuGWrdeerXjiWpC1gynTNUaySDsr8SU5xMpj5R" ) # m/1 => 0388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1 # m/2 => 03a04f945d5a3685729dde697d574076de4bdf38e904f813b22a851548e1110fc0 node_ext3 = bip32.deserialize( "xpub69qexv5TppjJVYtxFKSBFxcVGyaC8VJDa1RugAYwEDLVUBuaXrVgznvQB44piM8MRerfVf1pNCBK1L1NzhyKd4Ay25BVZX3S8twWfZDxmz7" ) # m/1 => 02e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648 # m/2 => 03928301ffb8c0d7a364b794914c716ba3107cc78a6fe581028b0d8638b22e8573 node_int = bip32.deserialize( "xpub69qexv5TppjJNEK5bfX8vQ6ASXDUQ5PohSajrHgeknHZ4SJipn7edmpRmiiBLLDtPur71mekZFazhgas8rkUMnS7quk5qp64TLLV8ShrxZJ" ) # m/1 => 03f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff35 # m/2 => 038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3 # ext1 + ext2 + int # redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae # multisig address: 2N9W4z9AhAPaHghtqVQPbaTAGHdbrhKeBQw # tx: 16c6c8471b8db7a628f2b2bb86bfeefae1766463ce8692438c7fd3fce3f43ce5 # input 0: 0.5 BTC # ext1 + int + ext2 # redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c153ae # multisig address: 2NDBG6QXQLtnQ3jRGkrqo53BiCeXfQXLdj4 # tx: d80c34ee14143a8bf61125102b7ef594118a3796cad670fa8ee15080ae155318 # input 0: 0.345 BTC # ext1 + ext3 + int # redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e2102e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae # multisig address: 2MvwPWfp2XPU3S1cMwgEMKBPUw38VP5SBE4 # tx: b0946dc27ba308a749b11afecc2018980af18f79e89ad6b080b58220d856f739 # input 1: 0.555 BTC multisig_in1 = proto.MultisigRedeemScriptType( nodes=[node_ext2, node_ext1, node_int], address_n=[0, 0], signatures=[b"", b"", b""], m=2, ) multisig_in2 = proto.MultisigRedeemScriptType( nodes=[node_ext1, node_ext2, node_int], address_n=[0, 1], signatures=[b"", b"", b""], m=2, ) multisig_in3 = proto.MultisigRedeemScriptType( nodes=[node_ext1, node_ext3, node_int], address_n=[0, 1], signatures=[b"", b"", b""], m=2, ) # 2N9W4z9AhAPaHghtqVQPbaTAGHdbrhKeBQw inp1 = proto.TxInputType( address_n=[H_(45), 0, 0, 0], amount=50000000, prev_hash=TXHASH_16c6c8, prev_index=1, script_type=proto.InputScriptType.SPENDMULTISIG, multisig=multisig_in1, ) # 2NDBG6QXQLtnQ3jRGkrqo53BiCeXfQXLdj4 inp2 = proto.TxInputType( address_n=[H_(45), 0, 0, 1], amount=34500000, prev_hash=TXHASH_d80c34, prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, multisig=multisig_in2, ) # 2MvwPWfp2XPU3S1cMwgEMKBPUw38VP5SBE4 inp3 = proto.TxInputType( address_n=[H_(45), 0, 0, 1], amount=55500000, prev_hash=TXHASH_b0946d, prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, multisig=multisig_in3, ) def _responses(self, inp1, inp2, change=0): resp = [ request_input(0), request_input(1), request_output(0), ] if change != 1: resp.append(proto.ButtonRequest(code=B.ConfirmOutput)) resp.append(request_output(1)) if change != 2: resp.append(proto.ButtonRequest(code=B.ConfirmOutput)) resp += [ proto.ButtonRequest(code=B.SignTx), request_input(0), request_meta(inp1.prev_hash), request_input(0, inp1.prev_hash), request_output(0, inp1.prev_hash), request_output(1, inp1.prev_hash), request_input(1), request_meta(inp2.prev_hash), request_input(0, inp2.prev_hash), request_output(0, inp2.prev_hash), request_output(1, inp2.prev_hash), request_input(0), request_input(1), request_output(0), request_output(1), request_input(0), request_input(1), request_output(0), request_output(1), request_output(0), request_output(1), request_finished(), ] return resp # both outputs are external @pytest.mark.multisig @pytest.mark.setup_client(mnemonic=MNEMONIC12) def test_external_external(self, client): out1 = proto.TxOutputType( address="1F8yBZB2NZhPZvJekhjTwjhQRRvQeTjjXr", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="1H7uXJQTVwXca2BXF2opTrvuZapk8Cm8zY", amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses(self._responses( self.inp1, self.inp2)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [self.inp1, self.inp2], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000" ) # first external, second internal @pytest.mark.multisig @pytest.mark.setup_client(mnemonic=MNEMONIC12) def test_external_internal(self, client): out1 = proto.TxOutputType( address="1F8yBZB2NZhPZvJekhjTwjhQRRvQeTjjXr", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address_n=parse_path("45'/0/1/1"), amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses( self._responses(self.inp1, self.inp2, change=2)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [self.inp1, self.inp2], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000" ) # first internal, second external @pytest.mark.multisig @pytest.mark.setup_client(mnemonic=MNEMONIC12) def test_internal_external(self, client): out1 = proto.TxOutputType( address_n=parse_path("45'/0/1/0"), amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="1H7uXJQTVwXca2BXF2opTrvuZapk8Cm8zY", amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses( self._responses(self.inp1, self.inp2, change=1)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [self.inp1, self.inp2], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000" ) # both outputs are external @pytest.mark.multisig @pytest.mark.setup_client(mnemonic=MNEMONIC12) def test_multisig_external_external(self, client): out1 = proto.TxOutputType( address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg", amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses(self._responses( self.inp1, self.inp2)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [self.inp1, self.inp2], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" ) # inputs match, change matches (first is change) @pytest.mark.multisig @pytest.mark.setup_client(mnemonic=MNEMONIC12) def test_multisig_change_match_first(self, client): multisig_out1 = proto.MultisigRedeemScriptType( nodes=[self.node_ext2, self.node_ext1, self.node_int], address_n=[1, 0], signatures=[b"", b"", b""], m=2, ) out1 = proto.TxOutputType( address_n=[H_(45), 0, 1, 0], multisig=multisig_out1, amount=40000000, script_type=proto.OutputScriptType.PAYTOMULTISIG, ) out2 = proto.TxOutputType( address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg", amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses( self._responses(self.inp1, self.inp2, change=1)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [self.inp1, self.inp2], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" ) # inputs match, change matches (second is change) @pytest.mark.multisig @pytest.mark.setup_client(mnemonic=MNEMONIC12) def test_multisig_change_match_second(self, client): multisig_out2 = proto.MultisigRedeemScriptType( nodes=[self.node_ext1, self.node_ext2, self.node_int], address_n=[1, 1], signatures=[b"", b"", b""], m=2, ) out1 = proto.TxOutputType( address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address_n=[H_(45), 0, 1, 1], multisig=multisig_out2, amount=44000000, script_type=proto.OutputScriptType.PAYTOMULTISIG, ) with client: client.set_expected_responses( self._responses(self.inp1, self.inp2, change=2)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [self.inp1, self.inp2], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" ) # inputs match, change mismatches (second tries to be change but isn't) @pytest.mark.multisig @pytest.mark.setup_client(mnemonic=MNEMONIC12) def test_multisig_mismatch_change(self, client): multisig_out2 = proto.MultisigRedeemScriptType( nodes=[self.node_ext1, self.node_int, self.node_ext3], address_n=[1, 0], signatures=[b"", b"", b""], m=2, ) out1 = proto.TxOutputType( address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address_n=[H_(45), 0, 1, 0], multisig=multisig_out2, amount=44000000, script_type=proto.OutputScriptType.PAYTOMULTISIG, ) with client: client.set_expected_responses(self._responses( self.inp1, self.inp2)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [self.inp1, self.inp2], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b40047304402207f9992cc0230527faf54ec6bd233307db82bc8fac039dcee418bc6feb4e96a3a02206bb4cb157ad27c123277328a877572563a45d70b844d9ab07cc42238112f8c2a014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b400473044022078a41bfa87d72d6ba810d84bf568b5a29acf8b851ba6c3a8dbff079b34a7feb0022037b770c776db0b6c883c38a684a121b90a59ed1958774cbf64de70e53e29639f014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914e6a3e2fbadb7f559f8d20c46aceae78c96fcf1d18700000000" ) # inputs mismatch, change matches with first input @pytest.mark.multisig @pytest.mark.setup_client(mnemonic=MNEMONIC12) def test_multisig_mismatch_inputs(self, client): multisig_out1 = proto.MultisigRedeemScriptType( nodes=[self.node_ext2, self.node_ext1, self.node_int], address_n=[1, 0], signatures=[b"", b"", b""], m=2, ) out1 = proto.TxOutputType( address_n=[H_(45), 0, 1, 0], multisig=multisig_out1, amount=40000000, script_type=proto.OutputScriptType.PAYTOMULTISIG, ) out2 = proto.TxOutputType( address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg", amount=65000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses(self._responses( self.inp1, self.inp3)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [self.inp1, self.inp3], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b500483045022100d907b9339951c96ef4515ef7aff8b3c28c4c8c5875d7421aa1de9f3a94e3508302205cdc311a6c91dfbb74f1a9a940a994a65dbfb0cf6dedcaaaeee839e0b8fd016d014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff39f756d82082b580b0d69ae8798ff10a981820ccfe1ab149a708a37bc26d94b000000000b500483045022100fdad4a47d15f47cc364fe0cbed11b1ced1f9ef210bc1bd413ec4384f630c63720220752e4f09ea4e5e6623f5ebe89b3983ec6e5702f63f9bce696f10b2d594d23532014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103b6321a1194e5cc47b6b7edc3f67a096e6f71ccb72440f84f390b6e98df0ea8ec2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948740d2df030000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" )
def test_send_multisig_4_change(self, client): nodes = [ btc.get_public_node(client, parse_path("49'/1'/%d'" % index)) for index in range(1, 4) ] multisig = proto.MultisigRedeemScriptType( nodes=[deserialize(n.xpub) for n in nodes], address_n=[1, 1], signatures=[b"", b"", b""], m=2, ) multisig2 = proto.MultisigRedeemScriptType( nodes=[deserialize(n.xpub) for n in nodes], address_n=[1, 2], signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("49'/1'/1'/1/1"), prev_hash=bytes.fromhex( "31bc1c88ce6ae337a6b3057a16d5bad0b561ad1dfc047d0a7fbb8814668f91e5" ), prev_index=0, script_type=proto.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1603000, ) out1 = proto.TxOutputType( address_n=parse_path("49'/1'/1'/1/2"), amount=1602000, multisig=multisig2, script_type=proto.OutputScriptType.PAYTOWITNESS, ) 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) signatures, _ = btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API) # store signature inp1.multisig.signatures[0] = signatures[0] # sign with third key inp1.address_n[2] = H_(3) out1.address_n[2] = H_(3) 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API) assert ( serialized_tx.hex() == "01000000000101e5918f661488bb7f0a7d04fc1dad61b5d0bad5167a05b3a637e36ace881cbc310000000023220020fa6c73de618ec134eeec0c16f6dd04d46d4347e9a4fd0a95fd7938403a4949f9ffffffff01d071180000000000220020bcea2324dacbcde5a9db90cc26b8df9cbc72010e05cb68cf034df6f0e05239a2040047304402206bbddb45f12e31e77610fd85b50a83bad4426433b1c4860b1c5ddc0a69f803720220087b0607daab14830f4b4941f16b953b38e606ad70029bac24af7267f93c4242014730440220551a0cb6b0d5b3fa0cfd0b07bb5d751494b827b1c6a08702186696cfbc18278302204f37c382876c4117cca656654599b508f2d55fc3b083dc938e3cd8491b29719601695221036a5ec3abd10501409092246fe59c6d7a15fff1a933479483c3ba98b866c5b9742103559be875179d44e438db2c74de26e0bc9842cbdefd16018eae8a2ed989e474722103067b56aad037cd8b5f569b21f9025b76470a72dc69457813d2b76e98dc0cd01a53ae00000000" )
def test_ethereum_signtx_eip155(self): # chain_id, nonce, sig_v, sig_r, sig_s, value, gas_limit, data VECTORS = [ ( 3, 0, 42, "cde31d8ab07d423d5e52aeb148180528ea54974cdb4c5578499c0137ec24d892", "41fc58955b3b3e3f3b2aced65e11e8a3cb6339027f943bec3d504d6398b69dd2", 100000000000000000, 21000, None, ), ( 3, 1, 41, "57951fed170f3765dea164d65acd31373799db32ec572e213b1d9a1209956b98", "0971f8830c0e2e89919309f217ed2eadb0c63d647e016d220729ce79d27c24a0", 100000000000000000, 21000, None, ), ( 3, 2, 42, "73744f66231690edd9eed2ab3c2b56ec4f6c4b9aabc633ae7f3f4ea94223d52c", "7f500afbe2b2b4e4e57f22511e3a42b3596b85cad7fe1eca700cdae1905d3555", 100000000000000000, 21004, b"\0", ), ( 3, 3, 42, "1a4fc1ec5f98bf874d5336aaf1fa9069ce68dc36c3f77e93465c9ac2c8b4b741", "13007c9b1df6a0d2f2ffa9d0ebcdec189122a5e781eb64967eb0d6a6def95b7a", 100000000000000000, 299732, b"ABCDEFGHIJKLMNOP" * 256 + b"!!!", ), ( 3, 4, 42, "8da0358d780df542f767d977f99ad034b6d9fa808fe50997141be2a1b93542c0", "2dafe1ead8aae1051e6662c5d553b34067bda9c8fa7314ae8693ec61ddfc96d4", 0, 21004, b"\0", ), ( 1, 1, 38, "b72707f0f5a38339c9dd0359720312c739a8ac6554659c7af48456f06ba33374", "75a431c046046942f9c1f3305cd08f34302164811c675ac0a0ac0b73cb30a90e", 0, 21004, b"\0", ), ( 255, 1, 545, "529172fb644a6d29b7218fb783f3d666021fc29cc4bf9bffbcfb3b84ab8d6181", "30980c6102a12872ef9cd888f2bf90c81bbbdc8878ff7d1d1382f8983b0d0c49", 0, 21004, b"\0", ), ( 256, 1, 548, "db53c05c679bdfdf3ded787ce9607d3f109ae46c87b1dcc9ab34053e5ed0eace", "39645dd48118d369b588dbf279f1a8c01051fabf65bf8eaa633c6433ff120cce", 0, 21004, b"\0", ), ( 65535, 1, 131105, "b520fa77767cdf07b6014d4a8fb35eebe5ed7c0edab97132b0dc74e3e1f13ed9", "78735b2db4cf95fb651c5c1f5529e60542019e456c6cb7a9f4bd9bbb83418d99", 0, 21004, b"\0", ), ( 65536, 1, 131107, "4b6122ba875b57ce084bd5f08e9ae1944e998726a4056c9b7746432d8f46ba99", "6812c2668ac9c9927b69ef7cf9baec54436f7319ccc14f0f664e1e94e6109e06", 0, 21004, b"\0", ), ( 16777215, 1, 33554465, "68a8c6f2336a8e3296f17a307d84a1e6d3ab1383fdcc62611c2e8426f2e2777e", "2d4ce900077ab40aac26064945998dbac5a014baadae2d3cb629cdeb9452db61", 0, 21004, b"\0", ), ( 16777216, 1, 33554468, "b6c42c584ef69621a2e5f3e1ab9dad890dbff3c92a599230dd0e394cd29d1c68", "497eec05ea52773d0f05e7fdf4f7993b3a06ef958804b39af699ef09ed0f5d7e", 0, 21004, b"\0", ), ( 2147483629, 1, 4294967294, "1a31f886c0bba527e622a731270dc29e62a607ff63558fca38745e5b9a672686", "0f3fce8a70598bbb54387cde7e8f957a27e4a816cbc9408717b27d8666222bd9", 0, 21004, b"\0", ), ( 2147483630, 1, 4294967296, "ba6cb6e2ebbac3726db9a3e4a939454009108f6515330e567aeada14ecebe074", "2bbfba1154cae32e3e6c6bbf3ce41cba6cc8c6b764245ba6026605506838e690", 0, 21004, None, ), ( 2147483631, 1, 4294967298, "3c743528e9ce315db02e487de93f2b2cfc93421e43f1d519f77a2f05bd2ce190", "16c1fec1495fe5da89d1a026f1a575ff354e18ff0fb9d04a6cfb0413267ab2bc", 100000000000000000, 21000, None, ), ( 3125659152, 1, 6251318340, "82cde0c9e1a94c1305791b09e1bcd021a49b036a16d9733acbc1a08bb30f3410", "472c8897519ba410b86f80993236d992e18e94d1f59c3d8760d2d7c90914dfc6", 1, 21005, None, ), ( 4294967295, 1, 8589934625, "67788e892fb372bba16823e16d3186f67494d7b1128555248f3661ad87e9d7ef", "2faf9f06dfdf23ceca2796cf0d55c88187f199e98a94dfb15722824b244d81a1", 100000000000000000, 21000, None, ), ] self.setup_mnemonic_allallall() for ci, n, sv, sr, ss, v, gl, d in VECTORS: sig_v, sig_r, sig_s = ethereum.sign_tx( self.client, n=[H_(44), H_(60), H_(0), 0, 0], nonce=n, gas_price=20000000000, gas_limit=gl, to=bytes.fromhex("8ea7a3fccc211ed48b763b4164884ddbcf3b0a98"), value=v, chain_id=ci, data=d, ) assert sig_v == sv assert sig_r.hex() == sr assert sig_s.hex() == ss
from trezorlib.messages import BackupType from trezorlib.tools import H_ from ..click_tests import recovery from ..common import MNEMONIC_SLIP39_BASIC_20_3of6, MNEMONIC_SLIP39_BASIC_20_3of6_SECRET from ..device_handler import BackgroundDeviceHandler from ..emulators import ALL_TAGS, EmulatorWrapper from . import SELECTED_GENS MINIMUM_FIRMWARE_VERSION["1"] = (1, 0, 0) MINIMUM_FIRMWARE_VERSION["T"] = (2, 0, 0) # **** COMMON DEFINITIONS **** MNEMONIC = " ".join(["all"] * 12) PATH = [H_(44), H_(0), H_(0), 0, 0] ADDRESS = "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL" LABEL = "test" LANGUAGE = "english" STRENGTH = 128 def for_all(*args, minimum_version=(1, 0, 0)): if not args: args = ("core", "legacy") # If any gens were selected, use them. If none, select all. enabled_gens = SELECTED_GENS or args all_params = [] for gen in args:
def test_send_multisig_1(client: Client): # input: 338e2d02e0eaf8848e38925904e51546cf22e58db5b1860c4a0e72b69c56afe5 nodes = [ btc.get_public_node(client, parse_path(f"m/49h/1h/{i}h"), coin_name="Testnet").node for i in range(1, 4) ] # address: 2MuqUo9axjz6FfHjSqNMu8kbF1tCjisMrbt multisig = messages.MultisigRedeemScriptType(nodes=nodes, address_n=[1, 0], signatures=[b"", b"", b""], m=2) inp1 = messages.TxInputType( address_n=parse_path("m/49h/1h/1h/1/0"), prev_hash=TXHASH_338e2d, prev_index=0, script_type=messages.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=100_000, ) out1 = messages.TxOutputType( address="mu85iAHLpF16VyijB2wn5fcZrjT2bvrhnL", amount=100_000 - 10_000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) expected_responses = [ request_input(0), request_output(0), messages.ButtonRequest(code=B.ConfirmOutput), messages.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_338e2d), request_input(0, TXHASH_338e2d), request_output(0, TXHASH_338e2d), request_output(1, TXHASH_338e2d), request_input(0), request_output(0), request_input(0), request_finished(), ] with client: client.set_expected_responses(expected_responses) signatures, _ = btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET) # store signature inp1.multisig.signatures[0] = signatures[0] # sign with third key inp1.address_n[2] = H_(3) with client: client.set_expected_responses(expected_responses) _, serialized_tx = btc.sign_tx(client, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET) assert_tx_matches( serialized_tx, hash_link= "https://tbtc1.trezor.io/api/tx/0d5d04bffd49287d122f509bebd196b1ecba7cbc5f945c28bf8a26dea66e65de", tx_hex= "01000000000101e5af569cb6720e4a0c86b1b58de522cf4615e5045992388e84f8eae0022d8e330000000023220020cf28684ff8a6dda1a7a9704dde113ddfcf236558da5ce35ad3f8477474dbdaf7ffffffff01905f0100000000001976a914953e62552a88c235c0691ec74b362a6803a7d93e88ac040047304402203aba48b0a98194a505420633eeca5acd8244061899e0a414f1b0d2de1d721b0f022001b32486e7c443e25cdfdfb14dc183ba31f5329d0078a25f7eb74f7209f347bb014830450221009cbdf84db2585abddf79165340cc0b54037f13bbe5318ec3619d0de680ebbf5d02206a2ef69e154700202ac72330e936c073f8a86cec9443273f4d8739db1019d55a0169522103d54ab3c8b81cb7f8f8088df4c62c105e8acaa2fb53b180f6bc6f922faecf3fdc21036aa47994f3f18f0976d6073ca79997003c3fa29c4f93907998fefc1151b4529b2102a092580f2828272517c402da9461425c5032860ab40180e041fbbb88ea2a520453ae00000000", )
def test_send_multisig_1(client): nodes = [ btc.get_public_node( client, parse_path(f"49'/1'/{i}'"), coin_name="Testnet" ).node for i in range(1, 4) ] multisig = messages.MultisigRedeemScriptType( nodes=nodes, address_n=[1, 0], signatures=[b"", b"", b""], m=2 ) inp1 = messages.TxInputType( address_n=parse_path("49'/1'/1'/1/0"), prev_hash=TXHASH_9c3192, prev_index=1, script_type=messages.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1610436, ) out1 = messages.TxOutputType( address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC", amount=1605000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) 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_9c3192), request_input(0, TXHASH_9c3192), request_output(0, TXHASH_9c3192), request_output(1, TXHASH_9c3192), request_input(0), request_output(0), request_input(0), request_finished(), ] ) signatures, _ = btc.sign_tx(client, "Testnet", [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_output(0), messages.ButtonRequest(code=B.ConfirmOutput), messages.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_9c3192), request_input(0, TXHASH_9c3192), request_output(0, TXHASH_9c3192), request_output(1, TXHASH_9c3192), request_input(0), request_output(0), request_input(0), request_finished(), ] ) _, serialized_tx = btc.sign_tx( client, "Testnet", [inp1], [out1], prev_txes=TX_API ) assert ( serialized_tx.hex() == "01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c0100000023220020cf28684ff8a6dda1a7a9704dde113ddfcf236558da5ce35ad3f8477474dbdaf7ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402203fc3fbe6cd6250d82ace4a585debc07587c07d2efc8bb56558c91e1f810fe65402206025bd9a4e80960f617b6e5bfdd568e34aa085d093471b7976e6b14c2a2402a7014730440220327abf491a57964d75c67fad204eb782fa74aa4abde40e5ad30fb0b7696102b7022049e31f2302417be0a87e2f818b93a862a7e67d4178b7cbeee680264f0882113f0169522103d54ab3c8b81cb7f8f8088df4c62c105e8acaa2fb53b180f6bc6f922faecf3fdc21036aa47994f3f18f0976d6073ca79997003c3fa29c4f93907998fefc1151b4529b2102a092580f2828272517c402da9461425c5032860ab40180e041fbbb88ea2a520453ae00000000" )
def test_send_bch_multisig_change(self, client): nodes = [ btc.get_public_node(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=TXHASH_8b6db9, 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 client: client.set_expected_responses([ request_input(0), 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(), ]) (signatures1, serialized_tx) = btc.sign_tx(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=TXHASH_8b6db9, prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, ) out2.address_n[2] = H_(1) with client: client.set_expected_responses([ request_input(0), 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(), ]) (signatures1, serialized_tx) = btc.sign_tx(client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API) assert ( signatures1[0].hex() == "3044022006f239ef1f065a70873ab9d2c81a623a04ec7a37a0ec5299d3c585668f441f49022032b2f9ef13bc61230d14f6d79b9ad1bbebdf47b95e4757e9af1b1dcdf520d3ab" ) assert ( serialized_tx.hex() == "0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfd0000473044022006f239ef1f065a70873ab9d2c81a623a04ec7a37a0ec5299d3c585668f441f49022032b2f9ef13bc61230d14f6d79b9ad1bbebdf47b95e4757e9af1b1dcdf520d3ab41483045022100a05f77bb39515c21c43e6c4ba401f39ed5d409dc3cfcd90f9a8345a08cc4bc8202205faf8f3b0775748278495324fdd60f370460452e4995e546450209ec4804a0f3414c69522102f8ca0d9665af03de32a7c19a167a4f6e97e4e0ed9505f75d11f7a45ab60b1f4d2103263d87cefd687bc15b4ef7801f9f538267b66d46f18e9fccc41d54071cfdd1ce210388568bf42f02298308eb6fa2fa4b446d544600253b4409be27e2c0c1a71c424853aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a91478574751407449b97f8054be2e40e684ad07d3738700000000" )
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_output(0), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_25526b), request_input(0, TXHASH_25526b), request_output(0, TXHASH_25526b), request_output(1, TXHASH_25526b), 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_output(0), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_25526b), request_input(0, TXHASH_25526b), request_output(0, TXHASH_25526b), request_output(1, TXHASH_25526b), 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_send_btg_multisig_change(self): self.setup_mnemonic_allallall() xpubs = [] for n in map( lambda index: btc.get_public_node( self.client, parse_path("44'/156'/%d'" % index)), range(1, 4), ): xpubs.append(n.xpub) def getmultisig(chain, nr, signatures=[b"", b"", b""], xpubs=xpubs): return proto.MultisigRedeemScriptType( pubkeys=list( map( lambda xpub: proto.HDNodePathType( node=deserialize(xpub), address_n=[chain, nr]), xpubs, )), signatures=signatures, m=2, ) inp1 = proto.TxInputType( address_n=parse_path("44'/156'/3'/0/0"), multisig=getmultisig(0, 0), # 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R amount=48490, prev_hash=bytes.fromhex( "25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985" ), 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("44'/156'/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), ]) signatures, serialized_tx = btc.sign_tx(self.client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API) assert ( signatures[0].hex() == "3045022100b1594f3b186d0dedbf61e53a1c407b1e0747098b7375941df85af045040f578e022013ba1893eb9e2fd854dd07073a83b261cf4beba76f66b07742e462b4088a7e4a" ) inp1 = proto.TxInputType( address_n=parse_path("44'/156'/1'/0/0"), multisig=getmultisig(0, 0, [b"", b"", signatures[0]]), # 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R amount=48490, prev_hash=bytes.fromhex( "25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985" ), 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), ]) signatures, serialized_tx = btc.sign_tx(self.client, "Bgold", [inp1], [out1, out2], prev_txes=TX_API) assert ( signatures[0].hex() == "3044022006da8dbd14e6656ac8dcb956f4c0498574e88680eaeceb2cbafd8d2b2329d8cc02200972d076d444c5ff8f2ab18e14d8249ab661cb9c53335039bedcde037a40d747" ) assert ( serialized_tx.hex() == "010000000185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b522500000000fdfd0000473044022006da8dbd14e6656ac8dcb956f4c0498574e88680eaeceb2cbafd8d2b2329d8cc02200972d076d444c5ff8f2ab18e14d8249ab661cb9c53335039bedcde037a40d74741483045022100b1594f3b186d0dedbf61e53a1c407b1e0747098b7375941df85af045040f578e022013ba1893eb9e2fd854dd07073a83b261cf4beba76f66b07742e462b4088a7e4a414c69522102290e6649574d17938c1ecb959ae92954f9ee48e1bd5b73f35ea931a3ab8a6087210379e0107b173e2c143426760627128c5eea3f862e8df92f3c2558eeeae4e347842103ff1746ca7dcf9e5c2eea9a73779b7c5bafed549f45cf3638a94cdf1e89c7f28f53aeffffffff02c05d0000000000001976a914ea5f904d195079a350b534db4446433b3cec222e88acc05d00000000000017a91445e917e46815d2b38d3f1cf072e63dd4f3b7a7e38700000000" )
class TestMultisigChange(TrezorTest): def setup_method(self, method): super(TestMultisigChange, self).setup_method(method) self.client.set_tx_api(TxApiTestnet) node_ext1 = bip32.deserialize( "tpubDADHV9u9Y6gkggintTdMjJE3be58zKNLhpxBQyuEM6Pwx3sN9JVLmMCMN4DNVwL9AKec27z5TaWcWuHzMXiGAtcra5DjwWbvppGX4gaEGVN" ) # m/1 => 02c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e # m/2 => 0375b9dfaad928ce1a7eed88df7c084e67d99e9ab74332419458a9a45779706801 node_ext2 = bip32.deserialize( "tpubDADHV9u9Y6gkhWXBmDJ6TUhZajLWjvKukRe2w9FfhdbQpUux8Z8jnPHNAZqFRgHPg9sR7YR93xThM32M7NfRu8S5WyDtext7S62sqxeJNkd" ) # m/1 => 0388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1 # m/2 => 03a04f945d5a3685729dde697d574076de4bdf38e904f813b22a851548e1110fc0 node_ext3 = bip32.deserialize( "tpubDADHV9u9Y6gkmM5ohWRGTswrc6fr7soH7e2D2ic5a86PDUaHc5Ln9EbER69cEr5bDZPa7EXguJ1MhWVzPZpZWVdG5fvoF3hfirXvRbpCCBg" ) # m/1 => 02e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648 # m/2 => 03928301ffb8c0d7a364b794914c716ba3107cc78a6fe581028b0d8638b22e8573 node_int = bip32.deserialize( "tpubDADHV9u9Y6gke2Vw3rWE8KRXmeK8PTtsF5B3Cqjo6h3SoiyRtzxjnDVG1knxrqB8BpP1dMAd6MR3Ps5UXibiFDtQuWVPXLkJ3HvttZYbH12" ) # m/1 => 03f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff35 # m/2 => 038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3 # ext1 + ext2 + int # redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae # multisig address: 3Gj7y1FdTppx2JEDqYqAEZFnKCA4GRysKF # tx: d1d08ea63255af4ad16b098e9885a252632086fa6be53301521d05253ce8a73d # input 0: 0.001 BTC # ext1 + int + ext2 # redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c153ae # multisig address: 3QsvfB6d1LzYcpm8xyhS1N1HBRrzHTgLHB # tx: a6e2829d089cee47e481b1a753a53081b40738cc87e38f1d9b23ab57d9ad4396 # input 0: 0.001 BTC # ext1 + ext3 + int # redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e2102e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae # multisig address: 37LvC1Q5CyKbMbKMncEJdXxqGhHxrBEgPE # tx: e4bc1ae5e5007a08f2b3926fe11c66612e8f73c6b00c69c7027213b84d259be3 # input 1: 0.001 BTC multisig_in1 = proto.MultisigRedeemScriptType( pubkeys=[ proto.HDNodePathType(node=node_ext2, address_n=[0, 0]), proto.HDNodePathType(node=node_ext1, address_n=[0, 0]), proto.HDNodePathType(node=node_int, address_n=[0, 0]), ], signatures=[b"", b"", b""], m=2, ) multisig_in2 = proto.MultisigRedeemScriptType( pubkeys=[ proto.HDNodePathType(node=node_ext1, address_n=[0, 1]), proto.HDNodePathType(node=node_ext2, address_n=[0, 1]), proto.HDNodePathType(node=node_int, address_n=[0, 1]), ], signatures=[b"", b"", b""], m=2, ) multisig_in3 = proto.MultisigRedeemScriptType( pubkeys=[ proto.HDNodePathType(node=node_ext1, address_n=[0, 1]), proto.HDNodePathType(node=node_ext3, address_n=[0, 1]), proto.HDNodePathType(node=node_int, address_n=[0, 1]), ], signatures=[b"", b"", b""], m=2, ) # 2N9W4z9AhAPaHghtqVQPbaTAGHdbrhKeBQw inp1 = proto.TxInputType( address_n=[H_(45), 0, 0, 0], prev_hash=unhexlify( "16c6c8471b8db7a628f2b2bb86bfeefae1766463ce8692438c7fd3fce3f43ce5" ), prev_index=1, script_type=proto.InputScriptType.SPENDMULTISIG, multisig=multisig_in1, ) # 2NDBG6QXQLtnQ3jRGkrqo53BiCeXfQXLdj4 inp2 = proto.TxInputType( address_n=[H_(45), 0, 0, 1], prev_hash=unhexlify( "d80c34ee14143a8bf61125102b7ef594118a3796cad670fa8ee15080ae155318" ), prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, multisig=multisig_in2, ) # 2MvwPWfp2XPU3S1cMwgEMKBPUw38VP5SBE4 inp3 = proto.TxInputType( address_n=[H_(45), 0, 0, 1], prev_hash=unhexlify( "b0946dc27ba308a749b11afecc2018980af18f79e89ad6b080b58220d856f739" ), prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, multisig=multisig_in3, ) def _responses(self, inp1, inp2, change=0): resp = [ 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=inp1.prev_hash), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=inp1.prev_hash), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=inp1.prev_hash), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=inp1.prev_hash), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1), ), proto.TxRequest( request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=inp2.prev_hash), ), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=inp2.prev_hash), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=inp2.prev_hash), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1, tx_hash=inp2.prev_hash), ), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0), ), ] if change != 1: resp.append( proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput)) resp.append( proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), )) if change != 2: resp.append( proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput)) resp += [ 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.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=1), ), 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.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), ] return resp # both outputs are external def test_external_external(self): self.setup_mnemonic_nopin_nopassphrase() out1 = proto.TxOutputType( address="muevUcG1Bb8eM2nGUGhqmeujHRX7YXjSEu", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="mwdrpMVSJxxsM8f8xbnCHn9ERaRT1NG1UX", amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses( self._responses(self.inp1, self.inp2)) (_, serialized_tx) = btc.sign_tx(self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]) assert ( hexlify(serialized_tx) == b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000" ) # first external, second internal def test_external_internal(self): self.setup_mnemonic_nopin_nopassphrase() out1 = proto.TxOutputType( address="muevUcG1Bb8eM2nGUGhqmeujHRX7YXjSEu", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address_n=parse_path("45'/0/1/1"), amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses( self._responses(self.inp1, self.inp2, change=2)) (_, serialized_tx) = btc.sign_tx(self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]) assert ( hexlify(serialized_tx) == b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000" ) # first internal, second external def test_internal_external(self): self.setup_mnemonic_nopin_nopassphrase() out1 = proto.TxOutputType( address_n=parse_path("45'/0/1/0"), amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="mwdrpMVSJxxsM8f8xbnCHn9ERaRT1NG1UX", amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses( self._responses(self.inp1, self.inp2, change=1)) (_, serialized_tx) = btc.sign_tx(self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]) assert ( hexlify(serialized_tx) == b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000" ) # both outputs are external def test_multisig_external_external(self): self.setup_mnemonic_nopin_nopassphrase() out1 = proto.TxOutputType( address="2N2aFoogGntQFFwdUVPfRmutXD22ThcNTsR", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address="2NFJjQcU8mw4Z3ywpbek8HL1VoJ27GDrkHw", amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses( self._responses(self.inp1, self.inp2)) (_, serialized_tx) = btc.sign_tx(self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]) assert ( hexlify(serialized_tx) == b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" ) # inputs match, change matches (first is change) def test_multisig_change_match_first(self): self.setup_mnemonic_nopin_nopassphrase() multisig_out1 = proto.MultisigRedeemScriptType( pubkeys=[ proto.HDNodePathType(node=self.node_ext2, address_n=[1, 0]), proto.HDNodePathType(node=self.node_ext1, address_n=[1, 0]), proto.HDNodePathType(node=self.node_int, address_n=[1, 0]), ], signatures=[b"", b"", b""], m=2, ) out1 = proto.TxOutputType( address_n=[H_(45), 0, 1, 0], multisig=multisig_out1, amount=40000000, script_type=proto.OutputScriptType.PAYTOMULTISIG, ) out2 = proto.TxOutputType( address="2NFJjQcU8mw4Z3ywpbek8HL1VoJ27GDrkHw", amount=44000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses( self._responses(self.inp1, self.inp2, change=1)) (_, serialized_tx) = btc.sign_tx(self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]) assert ( hexlify(serialized_tx) == b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" ) # inputs match, change matches (second is change) def test_multisig_change_match_second(self): self.setup_mnemonic_nopin_nopassphrase() multisig_out2 = proto.MultisigRedeemScriptType( pubkeys=[ proto.HDNodePathType(node=self.node_ext1, address_n=[1, 1]), proto.HDNodePathType(node=self.node_ext2, address_n=[1, 1]), proto.HDNodePathType(node=self.node_int, address_n=[1, 1]), ], signatures=[b"", b"", b""], m=2, ) out1 = proto.TxOutputType( address="2N2aFoogGntQFFwdUVPfRmutXD22ThcNTsR", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address_n=[H_(45), 0, 1, 1], multisig=multisig_out2, amount=44000000, script_type=proto.OutputScriptType.PAYTOMULTISIG, ) with self.client: self.client.set_expected_responses( self._responses(self.inp1, self.inp2, change=2)) (_, serialized_tx) = btc.sign_tx(self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]) assert ( hexlify(serialized_tx) == b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" ) # inputs match, change mismatches (second tries to be change but isn't) def test_multisig_mismatch_change(self): self.setup_mnemonic_nopin_nopassphrase() multisig_out2 = proto.MultisigRedeemScriptType( pubkeys=[ proto.HDNodePathType(node=self.node_ext1, address_n=[1, 0]), proto.HDNodePathType(node=self.node_int, address_n=[1, 0]), proto.HDNodePathType(node=self.node_ext3, address_n=[1, 0]), ], signatures=[b"", b"", b""], m=2, ) out1 = proto.TxOutputType( address="2N2aFoogGntQFFwdUVPfRmutXD22ThcNTsR", amount=40000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( address_n=[H_(45), 0, 1, 0], multisig=multisig_out2, amount=44000000, script_type=proto.OutputScriptType.PAYTOMULTISIG, ) with self.client: self.client.set_expected_responses( self._responses(self.inp1, self.inp2)) (_, serialized_tx) = btc.sign_tx(self.client, "Testnet", [self.inp1, self.inp2], [out1, out2]) assert ( hexlify(serialized_tx) == b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b40047304402207f9992cc0230527faf54ec6bd233307db82bc8fac039dcee418bc6feb4e96a3a02206bb4cb157ad27c123277328a877572563a45d70b844d9ab07cc42238112f8c2a014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b400473044022078a41bfa87d72d6ba810d84bf568b5a29acf8b851ba6c3a8dbff079b34a7feb0022037b770c776db0b6c883c38a684a121b90a59ed1958774cbf64de70e53e29639f014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914e6a3e2fbadb7f559f8d20c46aceae78c96fcf1d18700000000" ) # inputs mismatch, change matches with first input def test_multisig_mismatch_inputs(self): self.setup_mnemonic_nopin_nopassphrase() multisig_out1 = proto.MultisigRedeemScriptType( pubkeys=[ proto.HDNodePathType(node=self.node_ext2, address_n=[1, 0]), proto.HDNodePathType(node=self.node_ext1, address_n=[1, 0]), proto.HDNodePathType(node=self.node_int, address_n=[1, 0]), ], signatures=[b"", b"", b""], m=2, ) out1 = proto.TxOutputType( address_n=[H_(45), 0, 1, 0], multisig=multisig_out1, amount=40000000, script_type=proto.OutputScriptType.PAYTOMULTISIG, ) out2 = proto.TxOutputType( address="2NFJjQcU8mw4Z3ywpbek8HL1VoJ27GDrkHw", amount=65000000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses( self._responses(self.inp1, self.inp3)) (_, serialized_tx) = btc.sign_tx(self.client, "Testnet", [self.inp1, self.inp3], [out1, out2]) assert ( hexlify(serialized_tx) == b"0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b500483045022100d907b9339951c96ef4515ef7aff8b3c28c4c8c5875d7421aa1de9f3a94e3508302205cdc311a6c91dfbb74f1a9a940a994a65dbfb0cf6dedcaaaeee839e0b8fd016d014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff39f756d82082b580b0d69ae8798ff10a981820ccfe1ab149a708a37bc26d94b000000000b500483045022100fdad4a47d15f47cc364fe0cbed11b1ced1f9ef210bc1bd413ec4384f630c63720220752e4f09ea4e5e6623f5ebe89b3983ec6e5702f63f9bce696f10b2d594d23532014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103b6321a1194e5cc47b6b7edc3f67a096e6f71ccb72440f84f390b6e98df0ea8ec2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948740d2df030000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" )
def test_send_multisig_1(self): self.setup_mnemonic_allallall() nodes = map( lambda index: btc.get_public_node( self.client, parse_path("999'/1'/%d'" % index)), range(1, 4), ) multisig = proto.MultisigRedeemScriptType( pubkeys=list( map( lambda n: proto.HDNodePathType(node=deserialize(n.xpub), address_n=[2, 0]), nodes, )), signatures=[b"", b"", b""], m=2, ) inp1 = proto.TxInputType( address_n=parse_path("999'/1'/1'/2/0"), prev_hash=bytes.fromhex( "25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985" ), prev_index=1, script_type=proto.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1610436, ) out1 = proto.TxOutputType( address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe", amount=1605000, 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) signatures, _ = btc.sign_tx(self.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) 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(self.client, "Bgold", [inp1], [out1], prev_txes=TX_API) assert ( serialized_tx.hex() == "0100000000010185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b522501000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac0400483045022100e728485c8337f9a09ebbf36edc0fef10f8bcf5c1ba601b7d8ba43a9250a898f002206b9e3401c297f9ab9afb7f1be59bb342db53b5b65aff7c557e3109679697df0f41473044022062ea69ecdc07d0dadc1971fbda50a629a56dd30f431db26327428f4992601ce602204a1c8ab9c7d81c36cb6f819109a26f9baaa9607b8d37bff5e24eee6fab4a04e441695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000" )
def test_send_multisig_1(self): self.setup_mnemonic_allallall() nodes = map( lambda index: btc.get_public_node( self.client, parse_path("49'/156'/%d'" % index)), range(1, 4), ) multisig = proto.MultisigRedeemScriptType( nodes=[deserialize(n.xpub) for n in 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=bytes.fromhex( "25526bf06c76ad3082bba930cf627cdd5f1b3cd0b9907dd7ff1a07e14addc985" ), prev_index=1, script_type=proto.InputScriptType.SPENDP2SHWITNESS, multisig=multisig, amount=1610436, ) out1 = proto.TxOutputType( address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe", amount=1605000, 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.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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) signatures, _ = btc.sign_tx(self.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) 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.TXINPUT, details=proto.TxRequestDetailsType(request_index=0), ), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) _, serialized_tx = btc.sign_tx(self.client, "Bgold", [inp1], [out1], prev_txes=TX_API) assert ( serialized_tx.hex() == "0100000000010185c9dd4ae1071affd77d90b9d03c1b5fdd7c62cf30a9bb8230ad766cf06b52250100000023220020ea9ec48498c451286c2ebaf9e19255e2873b0fb517d67b2f2005298c7e437829ffffffff01887d1800000000001976a914ea5f904d195079a350b534db4446433b3cec222e88ac0400473044022077cb8b2a534f79328810ca8c330539ae9ffa086c359ddb7da11026557b04eef202201d95be0dd1da0aa01720953e52d5dabffd19a998d1490c13a21b8e52e4ead2e041483045022100e41cbd6a501ba8fe6f65554420e23e950d35af0da9b052da54a087463b0717ca02206c695c8d1f74f9535b5d89a2fd1f9326a0ef20e5400137f1e1daeee992b62b594169522103279aea0b253b144d1b2bb8532280001a996dcddd04f86e5e13df1355032cbc1321032c6465c956c0879663fa8be974c912d229c179a5cdedeb29611a1bec1f951eb22103494480a4b72101cbd2eadac8e18c7a3a7589a7f576bf46b8971c38c51e5eceeb53ae00000000" )
def test_ethereum_getaddress(self): self.setup_mnemonic_nopin_nopassphrase() assert (ethereum.get_address( self.client, [H_(44), H_(60)]) == "0xE025dfbE2C53638E547C6487DED34Add7b8Aafc1") assert (ethereum.get_address( self.client, [H_(44), H_(60), 1 ]) == "0xeD46C856D0c79661cF7d40FFE0C0C5077c00E898") assert (ethereum.get_address( self.client, [H_(44), H_(60), 0, H_(1) ]) == "0x6682Fa7F3eC58581b1e576268b5463B4b5c93839") assert (ethereum.get_address( self.client, [H_(44), H_(60), H_(9), 0 ]) == "0xFb3BE0F9717fF5fCF3C58EB49a9Ed67F1BD89D4E") assert (ethereum.get_address( self.client, [H_(44), H_(60), 0, 9999999 ]) == "0x6b909b50d88c9A8E02453A87b3662E3e7a5E0CF1") assert (ethereum.get_address( self.client, [H_(44), H_(6060), 0, 9999999 ]) == "0x98b8e926bd224764De2A0E4f4CBe1521474050AF")