Exemplo n.º 1
0
def test():
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="threebot_record_update")'
    """

    cleanup("dev_unittest_client")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("dev_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    explorer_client.hash_add(
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"066c03b5cf6db18edd6013591ae6292e8a04f1cc18fc6f0a0f3946d40bb087b3","height":3628,"parent":"761af2728b6f07bbccf4ddaf330c0bb1465246f6fe25fbfb9989129b69fbd899","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"670045cf43421b21577c27613569b65ba0cec613ae5437ee15dc0eea95241cbc","fulfillment":{"type":1,"data":{"publickey":"ed25519:bdea9aff09bcdc66529f6e2ef1bb763a3bab83ce542e8673d97aeaed0581ad97","signature":"e5a47b166eb6724ca7a72b5ddaeff287ebdde09751ed10e8850d320744afc5f45e59aa66e2cc4dc45ff593a0eea696c4e780b81636a1ce748c7149a9ee0ba807"}}},{"parentid":"1d686b8dfe44dfbfea55f327a52d9701a52938cb2c829f709dfb8059bc0e5f87","fulfillment":{"type":1,"data":{"publickey":"ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa","signature":"5ce7a10373214d269837e9c176ec806469d2b80f200f9ee961c63553b6ee200f88958293a571889f26b2b52664f3c9ff2441eaf8ed61830b51d640003b06fb00"}}}],"coinoutputs":[{"value":"501000000000","condition":{"type":1,"data":{"unlockhash":"0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55"}}},{"value":"198000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"}},"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"},{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}},"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}],"coinoutputids":["4b43906584620e8a13d98a917d424fb154dd1222a72b886a887c416b2a9120f5","19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376"],"coinoutputunlockhashes":["0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55","014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"0b5d7509e467b943af12db2d73ddb78a5ec8cfdf64c3c6ecacb2de4af68bdc4d","height":33,"parent":"40e281daee6f113b788d64b8247381c36fe4885233a7475c9be2cce852e1696e","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"a3c8f44d64c0636018a929d2caeec09fb9698bfdcbfa3a8225585a51e09ee563","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"e5b69be3b385f0a33f7978e0d6af30cf37c975bbb99d0f3d06f199cd579d3e6854f6cb398c88082e438c89d11d04de0e7d3b2876e250d4ba8ae457f88547f605"}}}],"coinoutputs":[{"value":"1000000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99998999000000000","condition":{"type":1,"data":{"unlockhash":"01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"100000000000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"coinoutputids":["75f297550acfa48490c21490f82c3c308326c16f950e17ef3a286486065a51b8","6d157a1eb23cadde122192869bc51e2a0fe44a2d8aba898cbdda8b7218a0f8cb"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"1b144b89c4b65cc67416e27286e802c50f78bc7326b4b0e5f6f967f99cc39419","height":200,"parent":"68e3886c9a4c59dea8c7a0eb138ede0e83716b995fd8ebfa5dfc766bfb349565","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"6d157a1eb23cadde122192869bc51e2a0fe44a2d8aba898cbdda8b7218a0f8cb","fulfillment":{"type":1,"data":{"publickey":"ed25519:00bde9571b30e1742c41fcca8c730183402d967df5b17b5f4ced22c677806614","signature":"05c72055d4cca6d8620fd7453c89ac8deaf92c38e366604dc6405cb097321b74e2e5f7ece15b440f4af5721b8aa6ea1f57f4fce44d2a2c6c0fb7a1e068a0480d"}}}],"coinoutputs":[{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99998498000000000","condition":{"type":1,"data":{"unlockhash":"0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99998999000000000","condition":{"type":1,"data":{"unlockhash":"01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"}},"unlockhash":"01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"}],"coinoutputids":["1d686b8dfe44dfbfea55f327a52d9701a52938cb2c829f709dfb8059bc0e5f87","e27ed8bbe45177fafdfd7d21394ff483b8bde24f551dd927a046a0b7c37ec228"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"5ab2604c7d54dd9ea39d829724e46deb8bbf2889d8627a3bb3b57907c6f4dff4","height":1433,"parent":"6b9fdad35096c5a84dcdb6e3e9ec2a8c7562f567e05b1207a7f9330ed51582bb","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"e27ed8bbe45177fafdfd7d21394ff483b8bde24f551dd927a046a0b7c37ec228","fulfillment":{"type":1,"data":{"publickey":"ed25519:41e84f3b0f6a06dd7e45ded4d0e227869725355b73906b82d9e3ffc0b6b01416","signature":"47a4d1a6aeb7403ea5c2cbcc26f84bb1964aadcb8765696db4a623694991f794663b860898db53401dd4324477c43f9fff177b74909201a03e131c2cd885cc0d"}}}],"coinoutputs":[{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99997997000000000","condition":{"type":1,"data":{"unlockhash":"0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99998498000000000","condition":{"type":1,"data":{"unlockhash":"0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"}},"unlockhash":"0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"}],"coinoutputids":["b90422bad2dffde79f0a46bd0a41055cf7974b080e115d76f69891ca31d31f11","f386312779f382f16fa836038b3d25536b928ba88ae1afa1f8c0e8dc25c0ba16"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"81d81b413fc8af3e528478e639d5a6e999e5e96611593cd2458b4d2d7abc3880","height":1433,"parent":"6b9fdad35096c5a84dcdb6e3e9ec2a8c7562f567e05b1207a7f9330ed51582bb","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"f386312779f382f16fa836038b3d25536b928ba88ae1afa1f8c0e8dc25c0ba16","fulfillment":{"type":1,"data":{"publickey":"ed25519:4e42a2fcfc0963d6fa7bb718fd088d9b6544331e8562d2743e730cdfbedeb55a","signature":"4abae694cf6a6408eca6f034ea2ec6930b9a73303c3e70d3444cf36a9966b0c4cc1b65168c23640affb5bdeae539ea583d42da52c58d21f59b71c288b3faef0e"}}}],"coinoutputs":[{"value":"2000000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99995996000000000","condition":{"type":1,"data":{"unlockhash":"0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"}}}],"minerfees":["1000000000"],"arbitrarydata":"Zm9vYmFy"}},"coininputoutputs":[{"value":"99997997000000000","condition":{"type":1,"data":{"unlockhash":"0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"}},"unlockhash":"0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"}],"coinoutputids":["d1f74e90eba8095e78f08a6284c7b76d4cda86b06ac742062d6e0e02dc4607eb","1edccdb04100ffd05d97431b6798533fa57dc7ed1ea58c75f0f445fb64442d6e"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":["039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a"],"unconfirmed":false}',
    )
    explorer_client.hash_add(
        "018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"066c03b5cf6db18edd6013591ae6292e8a04f1cc18fc6f0a0f3946d40bb087b3","height":3628,"parent":"761af2728b6f07bbccf4ddaf330c0bb1465246f6fe25fbfb9989129b69fbd899","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"670045cf43421b21577c27613569b65ba0cec613ae5437ee15dc0eea95241cbc","fulfillment":{"type":1,"data":{"publickey":"ed25519:bdea9aff09bcdc66529f6e2ef1bb763a3bab83ce542e8673d97aeaed0581ad97","signature":"e5a47b166eb6724ca7a72b5ddaeff287ebdde09751ed10e8850d320744afc5f45e59aa66e2cc4dc45ff593a0eea696c4e780b81636a1ce748c7149a9ee0ba807"}}},{"parentid":"1d686b8dfe44dfbfea55f327a52d9701a52938cb2c829f709dfb8059bc0e5f87","fulfillment":{"type":1,"data":{"publickey":"ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa","signature":"5ce7a10373214d269837e9c176ec806469d2b80f200f9ee961c63553b6ee200f88958293a571889f26b2b52664f3c9ff2441eaf8ed61830b51d640003b06fb00"}}}],"coinoutputs":[{"value":"501000000000","condition":{"type":1,"data":{"unlockhash":"0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55"}}},{"value":"198000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"}},"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"},{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}},"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}],"coinoutputids":["4b43906584620e8a13d98a917d424fb154dd1222a72b886a887c416b2a9120f5","19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376"],"coinoutputunlockhashes":["0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55","014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"d0d290dccddaf086708e4163eacd420bfbaa7acb77deea97c6a8792a139f6e7e","height":3583,"parent":"ca746d80740ff45f6e7f0d6c8b6278b35b1040b4e21baaf41bd03cd3a7a176be","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"1edccdb04100ffd05d97431b6798533fa57dc7ed1ea58c75f0f445fb64442d6e","fulfillment":{"type":1,"data":{"publickey":"ed25519:7469d51063cdb690cc8025db7d28faadc71ff69f7c372779bf3a1e801a923e02","signature":"6f38467bb4ca23900e424d5ac2066a09b61fe9d9ae84a4231755063f591d04711f0a5ab11b60b42c2c32a8e7f73fc1cc1cb0073b036bc417ed504a8ef5f25402"}}}],"coinoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"}}},{"value":"99995795000000000","condition":{"type":1,"data":{"unlockhash":"01f706dcbb9f0cb1e97d891ada3a133f68612ebff948c5bbae7851108a65dab7782907eecd86be"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99995996000000000","condition":{"type":1,"data":{"unlockhash":"0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"}},"unlockhash":"0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"}],"coinoutputids":["670045cf43421b21577c27613569b65ba0cec613ae5437ee15dc0eea95241cbc","984555e190d58dc752aad81b0a6cf6194fa5bf89b8614efcd9604d138a8953bc"],"coinoutputunlockhashes":["018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd","01f706dcbb9f0cb1e97d891ada3a133f68612ebff948c5bbae7851108a65dab7782907eecd86be"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.chain_info = '{"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1}'
    explorer_client.hash_add(
        "552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e",
        '{"hashtype":"blockid","block":{"minerpayoutids":["468db689f752414702ef3a5aa06238f03a4539434a61624b3b8a0fb5dc38a211"],"transactions":[{"id":"2396f8e57bbb9b22bd1d749d5de3fd532ea6886e9660a556a13571d701d83e27","height":3644,"parent":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["f683e7319659c61f54e93546bc41b57c5bffe79de26c06ec7371034465804c81"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"47db4274551b0372564f8d1ab89c596428f00e460c0b416327e53983c8765198","timestamp":1549012665,"pobsindexes":{"BlockHeight":3643,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.hash_add(
        "039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"4c70a0406f36cf354edf87642df3f34568fd0a89c052a81d11cc6e4f8fbf685e","height":45,"parent":"f7b78b17d581ff9e58ffbcce1701d4dcadb0781590ca68e839def0dc98b0360a","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"7d4a100fc3bc08b2bdd1284c17260dd2bd6b55fd6c1429dbbd683bf362d92b50","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"c34b8ca1ab08930bc68d61026af504d62d8a8bbda9b79ae01a387560fba22d39b12021e16566732b742ea686f997b3c19c807523797cdc0d74a4d25123691004"}}},{"parentid":"83503f9cea00d562e0460eace93159a4c4dd00df4703c96947e81885b46da04c","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f6eea681a259baf14433ac55b4293b22ca2056810ee8fed2129039224d14558f54ca58c6d96e9885cb20ecdf7e64ba81d1a83c6e9a42bf9464287fa6359d360c"}}},{"parentid":"578aa43de72b42b4f4547c5ddc7f61736b1cac206e1789bc89fcd9333cf3d1f3","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"a0521d14dfe4a0c9b8b57ed361d738b48b6a8346097246effe0b4ee67b6fecbc3a90e4671ddc0b164f6c2839df249bb5998f10216a4a674ba8d24b8ad6bdf808"}}},{"parentid":"5a1454762e6895431e1b9e4e435e4d0ad60a3881843ac46b88e220771055ca87","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"900e7868780e67bcb68af3ec6976e84289850d0db59210d4689b1c0e2deb3164b9e93eb9ee5a38850f2319463b0845163e1eee443d7b645c59485c2aa0837707"}}},{"parentid":"c04ebebe17a1759457eecaf4d5d33f5ddbe8d154b0be1606f05bc8fd02ab9cd4","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"e992b1cd3347b5362e820166d5929de7c682130c7143fc4c9ff3156f5d44110753687697a0154a2043290b3f022e2537f3e3a6807caf9150f8c255d74e386d0a"}}}],"coinoutputs":[{"value":"42000000000","condition":{"type":4,"data":{"unlockhashes":["01ffd7c884aa869056bfb832d957bb71a0005fee13c19046cebec84b3a5047ee8829eab070374b","014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"],"minimumsignaturecount":1}}},{"value":"7000000000","condition":{"type":1,"data":{"unlockhash":"01972837ee396f22f96846a0c700f9cf7c8fa83ab4110da91a1c7d02f94f28ff03e45f1470df82"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"coinoutputids":["29152fe03a2c8782fcbd670579686088c52be83fa3870f5f0788073d97fb5fb2","0fc9b16bb180cd8f8a7144d65e6c8fca66994a4ccaee42e324289d4039ab2841"],"coinoutputunlockhashes":["039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a","01972837ee396f22f96846a0c700f9cf7c8fa83ab4110da91a1c7d02f94f28ff03e45f1470df82"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # add threebot record:
    explorer_client.threebot_record_add(
        ThreeBotRecord(
            identifier=3,
            names=[BotName(value=s) for s in ["chatbot.example"]],
            addresses=[NetworkAddress(address=s) for s in ["example.org", "127.0.0.1"]],
            public_key=PublicKey.from_json("ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa"),
            expiration=1549012664,
        )
    )
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # the devnet genesis seed is the seed of the wallet,
    # which receives all block stakes and coins in the genesis block of the tfchain devnet
    DEVNET_GENESIS_SEED = "image orchard airport business cost work mountain obscure flee alpha alert salmon damage engage trumpet route marble subway immune short tide young cycle attract"

    # create a new devnet wallet
    w = c.wallets.new("mywallet", seed=DEVNET_GENESIS_SEED)
    # we create a new wallet using an existing seed,
    # such that our seed is used and not a new randomly generated seed

    # a tfchain (JS) wallet uses the underlying tfchain client for all its
    # interaction with the tfchain network
    assert w.network_type == "DEV"

    # getting the balance of a wallet is as easy as getting the 'balance' property
    balance = w.balance

    # the available and locked tokens can be easily checked
    assert str(balance.available) == "3698"
    assert str(balance.locked) == "0"

    # if a 3Bot is inactive, at least one month has to be added to make it active again,
    # and reset the expiration time, otherwise the j.clients.tfchain.errors.ThreeBotInactive error will be raised
    with pytest.raises(j.clients.tfchain.errors.ThreeBotInactive):
        w.threebot.record_update(3, addresses_to_add=["bot.example.org"])
    with pytest.raises(j.clients.tfchain.errors.ThreeBotInactive):
        w.threebot.record_update(3, months=0, addresses_to_add=["bot.example.org"])

    # updating a record is as simple as:
    result = w.threebot.record_update(
        3,  # identifier of the 3Bot
        months=2,  # months to add, 0 by default
        names_to_add=["thisis.justan.example", "foobar"],  # names to add, None by default
        names_to_remove=["chatbot.example"],  # registered names to remove, None by default
        addresses_to_add=["bot.example.org"],  # addresses to add, None by default
        addresses_to_remove=["127.0.0.1", "example.org"],  # registered addresses to remove, None by default
        source=w.address,  # source address or addresses used to fund this transaction, None by default
        # in which case all the personal wallet addresses will be used
        refund=w.address,  # refund address, None by default
        # in which case either the source address is used (if only one is defined),
        # or the primary address is used
    )
    assert result.submitted  # we expect the transaction to be submitted

    expected_transaction = {
        "version": 145,
        "data": {
            "id": 3,
            "nrofmonths": 2,
            "txfee": "1000000000",
            "coininputs": [
                {
                    "parentid": "19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376",
                    "fulfillment": {
                        "type": 1,
                        "data": {
                            "publickey": "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                            "signature": "88bbef906997cf4c1346962bb2fd2f7260da751293d5b91675f16b34349dcc1e79ff7c1e9c19c47992245cbd67bf6352b25fd4376abaae24edcde68fb0115c0a",
                        },
                    },
                }
            ],
            "signature": "a51bc43e07fc28d5865cd0814e060a14a905d84896369c5eef1fe551b88c32622592e16539d406240de83d8ecc603779467de583a3bd298f50756c56e5fb7707",
            "addresses": {"add": ["bot.example.org"], "remove": ["127.0.0.1", "example.org"]},
            "names": {"add": ["thisis.justan.example", "foobar"], "remove": ["chatbot.example"]},
            "refundcoinoutput": {
                "value": "57000000000",
                "condition": {
                    "type": 1,
                    "data": {
                        "unlockhash": "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
                    },
                },
            },
        },
    }
    # ensure our transaction is as expected
    assert result.transaction.json() == expected_transaction

    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    # if no data is given to update, a ValueError exception will be raised
    with pytest.raises(j.exceptions.Value):
        w.threebot.record_update(3)

    # if data is given to update,
    # but the 3Bot doesn't exist (linked to the given identifier)
    # an j.clients.tfchain.errors.ThreeBotNotFound exception will be raised
    with pytest.raises(j.clients.tfchain.errors.ThreeBotNotFound):
        w.threebot.record_update(2, months=1)

    c.wallets.delete()
    c.delete()
Exemplo n.º 2
0
def test():
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="wallet_coins_send")'
    """

    cleanup("dev_unittest_client")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("dev_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    # set the current block chain info
    explorer_client.chain_info = '{"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1}'
    explorer_client.hash_add(
        "552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e",
        '{"hashtype":"blockid","block":{"minerpayoutids":["468db689f752414702ef3a5aa06238f03a4539434a61624b3b8a0fb5dc38a211"],"transactions":[{"id":"2396f8e57bbb9b22bd1d749d5de3fd532ea6886e9660a556a13571d701d83e27","height":3644,"parent":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["f683e7319659c61f54e93546bc41b57c5bffe79de26c06ec7371034465804c81"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"47db4274551b0372564f8d1ab89c596428f00e460c0b416327e53983c8765198","timestamp":1549012665,"pobsindexes":{"BlockHeight":3643,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add initial condition
    explorer_client.mint_condition_add(
        condition=j.clients.tfchain.types.conditions.from_recipient(
            "01a006599af1155f43d687635e9680650003a6c506934996b90ae84d07648927414046f9f0e936"
        ),
        height=0,
    )
    # overwrite the explorer get/post logic
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # the devnet genesis seed is the seed of the wallet,
    # which receives all block stakes and coins in the genesis block of the tfchain devnet
    DEVNET_GENESIS_SEED = "image orchard airport business cost work mountain obscure flee alpha alert salmon damage engage trumpet route marble subway immune short tide young cycle attract"

    # create a new devnet wallet
    w = c.wallets.new("mywallet", seed=DEVNET_GENESIS_SEED)
    # we create a new wallet using an existing seed,
    # such that our seed is used and not a new randomly generated seed

    # a tfchain (JS) wallet uses the underlying tfchain client for all its
    # interaction with the tfchain network
    assert w.network_type == "DEV"

    # balance will be fully 0 for wallet due to our stub state
    assert w.balance.available == 0
    assert w.balance.unconfirmed == 0
    assert w.balance.locked == 0

    # (1) if the wallet has no powers to mint coins,
    # the transaction will be not be submitted as the transaction won't be fulfilled
    result = w.minter.coins_new(
        recipient=
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
        amount=100)
    assert not result.submitted
    assert not result.transaction.is_fulfilled()
    assert not result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)

    # define the current mint condition to be ours
    explorer_client.mint_condition_add(
        condition=j.clients.tfchain.types.conditions.from_recipient(
            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
        ),
        height=3643,
    )

    # (2) creating coins and sending it to a personal wallet on the used tfchain network can be done as follows:
    result = w.minter.coins_new(
        recipient=
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
        amount="108.24",  # the amount of TFT to send
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # (3) creating coins and sending it to a personal wallet with a lock and data is possible as well
    result = w.minter.coins_new(
        recipient=
        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
        amount=200,  # the amount of TFT to send
        lock=
        "07/12/2020 14:35",  # a lock can be a timestamp, data-time str, duration str, or block height
        data="maximum 83 bytes can be used as optional data",
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # (4) one can also send to a full multi-sig wallet, when creating coins
    result = w.minter.coins_new(
        recipient=[
            "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
        ],
        amount="50 TFT",  # the amount of TFT to send
        lock=
        1550665225,  # a lock can be a timestamp, data-time str, duration str, or block height
        data=b"binary data can be added as well",
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # (5) one can also send to a x-out-of-n multisig wallet, when creating coins
    result = w.minter.coins_new(
        recipient=(
            1,
            [
                "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
                "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
            ],
        ),
        amount="300.0",  # the amount of TFT to send
        lock=
        35000,  # a lock can be a timestamp, data-time str, duration str, or block height
        data=bytearray(b"binary data can be added as well"),
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # define the minter condition as multi-sig
    explorer_client.mint_condition_add(
        condition=j.clients.tfchain.types.conditions.from_recipient((
            1,
            [
                "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
                "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f",
            ],
        )),
        height=3643,
        force=True,
    )

    # (6) creating coins and sending works the same if the condition is multi-sig,
    #     the only difference is that it might be possible that the transaction is not submitted yet,
    #     should more signatures be required in order to fulfill the mint fulfillment
    result = w.minter.coins_new(
        recipient=
        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
        amount="108.24",  # the amount of TFT to send
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentMultiSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "039481e77f55a2a4aee707c07d69a11b1d9dc4100ccc50b9f82d56b411826014e5ea1f477be065"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    c.wallets.delete()
    c.delete()
Exemplo n.º 3
0
def main(self):
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="wallet_coins_send")'
    """

    cleanup("dev_unitest_client")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("dev_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    explorer_client.hash_add(
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"066c03b5cf6db18edd6013591ae6292e8a04f1cc18fc6f0a0f3946d40bb087b3","height":3628,"parent":"761af2728b6f07bbccf4ddaf330c0bb1465246f6fe25fbfb9989129b69fbd899","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"670045cf43421b21577c27613569b65ba0cec613ae5437ee15dc0eea95241cbc","fulfillment":{"type":1,"data":{"publickey":"ed25519:bdea9aff09bcdc66529f6e2ef1bb763a3bab83ce542e8673d97aeaed0581ad97","signature":"e5a47b166eb6724ca7a72b5ddaeff287ebdde09751ed10e8850d320744afc5f45e59aa66e2cc4dc45ff593a0eea696c4e780b81636a1ce748c7149a9ee0ba807"}}},{"parentid":"1d686b8dfe44dfbfea55f327a52d9701a52938cb2c829f709dfb8059bc0e5f87","fulfillment":{"type":1,"data":{"publickey":"ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa","signature":"5ce7a10373214d269837e9c176ec806469d2b80f200f9ee961c63553b6ee200f88958293a571889f26b2b52664f3c9ff2441eaf8ed61830b51d640003b06fb00"}}}],"coinoutputs":[{"value":"501000000000","condition":{"type":1,"data":{"unlockhash":"0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55"}}},{"value":"198000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"}},"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"},{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}},"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}],"coinoutputids":["4b43906584620e8a13d98a917d424fb154dd1222a72b886a887c416b2a9120f5","19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376"],"coinoutputunlockhashes":["0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55","014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"0b5d7509e467b943af12db2d73ddb78a5ec8cfdf64c3c6ecacb2de4af68bdc4d","height":33,"parent":"40e281daee6f113b788d64b8247381c36fe4885233a7475c9be2cce852e1696e","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"a3c8f44d64c0636018a929d2caeec09fb9698bfdcbfa3a8225585a51e09ee563","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"e5b69be3b385f0a33f7978e0d6af30cf37c975bbb99d0f3d06f199cd579d3e6854f6cb398c88082e438c89d11d04de0e7d3b2876e250d4ba8ae457f88547f605"}}}],"coinoutputs":[{"value":"1000000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99998999000000000","condition":{"type":1,"data":{"unlockhash":"01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"100000000000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"coinoutputids":["75f297550acfa48490c21490f82c3c308326c16f950e17ef3a286486065a51b8","6d157a1eb23cadde122192869bc51e2a0fe44a2d8aba898cbdda8b7218a0f8cb"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"1b144b89c4b65cc67416e27286e802c50f78bc7326b4b0e5f6f967f99cc39419","height":200,"parent":"68e3886c9a4c59dea8c7a0eb138ede0e83716b995fd8ebfa5dfc766bfb349565","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"6d157a1eb23cadde122192869bc51e2a0fe44a2d8aba898cbdda8b7218a0f8cb","fulfillment":{"type":1,"data":{"publickey":"ed25519:00bde9571b30e1742c41fcca8c730183402d967df5b17b5f4ced22c677806614","signature":"05c72055d4cca6d8620fd7453c89ac8deaf92c38e366604dc6405cb097321b74e2e5f7ece15b440f4af5721b8aa6ea1f57f4fce44d2a2c6c0fb7a1e068a0480d"}}}],"coinoutputs":[{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99998498000000000","condition":{"type":1,"data":{"unlockhash":"0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99998999000000000","condition":{"type":1,"data":{"unlockhash":"01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"}},"unlockhash":"01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"}],"coinoutputids":["1d686b8dfe44dfbfea55f327a52d9701a52938cb2c829f709dfb8059bc0e5f87","e27ed8bbe45177fafdfd7d21394ff483b8bde24f551dd927a046a0b7c37ec228"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"5ab2604c7d54dd9ea39d829724e46deb8bbf2889d8627a3bb3b57907c6f4dff4","height":1433,"parent":"6b9fdad35096c5a84dcdb6e3e9ec2a8c7562f567e05b1207a7f9330ed51582bb","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"e27ed8bbe45177fafdfd7d21394ff483b8bde24f551dd927a046a0b7c37ec228","fulfillment":{"type":1,"data":{"publickey":"ed25519:41e84f3b0f6a06dd7e45ded4d0e227869725355b73906b82d9e3ffc0b6b01416","signature":"47a4d1a6aeb7403ea5c2cbcc26f84bb1964aadcb8765696db4a623694991f794663b860898db53401dd4324477c43f9fff177b74909201a03e131c2cd885cc0d"}}}],"coinoutputs":[{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99997997000000000","condition":{"type":1,"data":{"unlockhash":"0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99998498000000000","condition":{"type":1,"data":{"unlockhash":"0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"}},"unlockhash":"0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"}],"coinoutputids":["b90422bad2dffde79f0a46bd0a41055cf7974b080e115d76f69891ca31d31f11","f386312779f382f16fa836038b3d25536b928ba88ae1afa1f8c0e8dc25c0ba16"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"81d81b413fc8af3e528478e639d5a6e999e5e96611593cd2458b4d2d7abc3880","height":1433,"parent":"6b9fdad35096c5a84dcdb6e3e9ec2a8c7562f567e05b1207a7f9330ed51582bb","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"f386312779f382f16fa836038b3d25536b928ba88ae1afa1f8c0e8dc25c0ba16","fulfillment":{"type":1,"data":{"publickey":"ed25519:4e42a2fcfc0963d6fa7bb718fd088d9b6544331e8562d2743e730cdfbedeb55a","signature":"4abae694cf6a6408eca6f034ea2ec6930b9a73303c3e70d3444cf36a9966b0c4cc1b65168c23640affb5bdeae539ea583d42da52c58d21f59b71c288b3faef0e"}}}],"coinoutputs":[{"value":"2000000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99995996000000000","condition":{"type":1,"data":{"unlockhash":"0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"}}}],"minerfees":["1000000000"],"arbitrarydata":"Zm9vYmFy"}},"coininputoutputs":[{"value":"99997997000000000","condition":{"type":1,"data":{"unlockhash":"0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"}},"unlockhash":"0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"}],"coinoutputids":["d1f74e90eba8095e78f08a6284c7b76d4cda86b06ac742062d6e0e02dc4607eb","1edccdb04100ffd05d97431b6798533fa57dc7ed1ea58c75f0f445fb64442d6e"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":["039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a"],"unconfirmed":false}',
    )
    explorer_client.hash_add(
        "018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"066c03b5cf6db18edd6013591ae6292e8a04f1cc18fc6f0a0f3946d40bb087b3","height":3628,"parent":"761af2728b6f07bbccf4ddaf330c0bb1465246f6fe25fbfb9989129b69fbd899","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"670045cf43421b21577c27613569b65ba0cec613ae5437ee15dc0eea95241cbc","fulfillment":{"type":1,"data":{"publickey":"ed25519:bdea9aff09bcdc66529f6e2ef1bb763a3bab83ce542e8673d97aeaed0581ad97","signature":"e5a47b166eb6724ca7a72b5ddaeff287ebdde09751ed10e8850d320744afc5f45e59aa66e2cc4dc45ff593a0eea696c4e780b81636a1ce748c7149a9ee0ba807"}}},{"parentid":"1d686b8dfe44dfbfea55f327a52d9701a52938cb2c829f709dfb8059bc0e5f87","fulfillment":{"type":1,"data":{"publickey":"ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa","signature":"5ce7a10373214d269837e9c176ec806469d2b80f200f9ee961c63553b6ee200f88958293a571889f26b2b52664f3c9ff2441eaf8ed61830b51d640003b06fb00"}}}],"coinoutputs":[{"value":"501000000000","condition":{"type":1,"data":{"unlockhash":"0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55"}}},{"value":"198000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"}},"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"},{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}},"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}],"coinoutputids":["4b43906584620e8a13d98a917d424fb154dd1222a72b886a887c416b2a9120f5","19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376"],"coinoutputunlockhashes":["0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55","014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"d0d290dccddaf086708e4163eacd420bfbaa7acb77deea97c6a8792a139f6e7e","height":3583,"parent":"ca746d80740ff45f6e7f0d6c8b6278b35b1040b4e21baaf41bd03cd3a7a176be","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"1edccdb04100ffd05d97431b6798533fa57dc7ed1ea58c75f0f445fb64442d6e","fulfillment":{"type":1,"data":{"publickey":"ed25519:7469d51063cdb690cc8025db7d28faadc71ff69f7c372779bf3a1e801a923e02","signature":"6f38467bb4ca23900e424d5ac2066a09b61fe9d9ae84a4231755063f591d04711f0a5ab11b60b42c2c32a8e7f73fc1cc1cb0073b036bc417ed504a8ef5f25402"}}}],"coinoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"}}},{"value":"99995795000000000","condition":{"type":1,"data":{"unlockhash":"01f706dcbb9f0cb1e97d891ada3a133f68612ebff948c5bbae7851108a65dab7782907eecd86be"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99995996000000000","condition":{"type":1,"data":{"unlockhash":"0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"}},"unlockhash":"0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"}],"coinoutputids":["670045cf43421b21577c27613569b65ba0cec613ae5437ee15dc0eea95241cbc","984555e190d58dc752aad81b0a6cf6194fa5bf89b8614efcd9604d138a8953bc"],"coinoutputunlockhashes":["018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd","01f706dcbb9f0cb1e97d891ada3a133f68612ebff948c5bbae7851108a65dab7782907eecd86be"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.chain_info = '{"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1}'
    explorer_client.hash_add(
        "552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e",
        '{"hashtype":"blockid","block":{"minerpayoutids":["468db689f752414702ef3a5aa06238f03a4539434a61624b3b8a0fb5dc38a211"],"transactions":[{"id":"2396f8e57bbb9b22bd1d749d5de3fd532ea6886e9660a556a13571d701d83e27","height":3644,"parent":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["f683e7319659c61f54e93546bc41b57c5bffe79de26c06ec7371034465804c81"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"47db4274551b0372564f8d1ab89c596428f00e460c0b416327e53983c8765198","timestamp":1549012665,"pobsindexes":{"BlockHeight":3643,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.hash_add(
        "039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"4c70a0406f36cf354edf87642df3f34568fd0a89c052a81d11cc6e4f8fbf685e","height":45,"parent":"f7b78b17d581ff9e58ffbcce1701d4dcadb0781590ca68e839def0dc98b0360a","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"7d4a100fc3bc08b2bdd1284c17260dd2bd6b55fd6c1429dbbd683bf362d92b50","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"c34b8ca1ab08930bc68d61026af504d62d8a8bbda9b79ae01a387560fba22d39b12021e16566732b742ea686f997b3c19c807523797cdc0d74a4d25123691004"}}},{"parentid":"83503f9cea00d562e0460eace93159a4c4dd00df4703c96947e81885b46da04c","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f6eea681a259baf14433ac55b4293b22ca2056810ee8fed2129039224d14558f54ca58c6d96e9885cb20ecdf7e64ba81d1a83c6e9a42bf9464287fa6359d360c"}}},{"parentid":"578aa43de72b42b4f4547c5ddc7f61736b1cac206e1789bc89fcd9333cf3d1f3","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"a0521d14dfe4a0c9b8b57ed361d738b48b6a8346097246effe0b4ee67b6fecbc3a90e4671ddc0b164f6c2839df249bb5998f10216a4a674ba8d24b8ad6bdf808"}}},{"parentid":"5a1454762e6895431e1b9e4e435e4d0ad60a3881843ac46b88e220771055ca87","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"900e7868780e67bcb68af3ec6976e84289850d0db59210d4689b1c0e2deb3164b9e93eb9ee5a38850f2319463b0845163e1eee443d7b645c59485c2aa0837707"}}},{"parentid":"c04ebebe17a1759457eecaf4d5d33f5ddbe8d154b0be1606f05bc8fd02ab9cd4","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"e992b1cd3347b5362e820166d5929de7c682130c7143fc4c9ff3156f5d44110753687697a0154a2043290b3f022e2537f3e3a6807caf9150f8c255d74e386d0a"}}}],"coinoutputs":[{"value":"42000000000","condition":{"type":4,"data":{"unlockhashes":["01ffd7c884aa869056bfb832d957bb71a0005fee13c19046cebec84b3a5047ee8829eab070374b","014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"],"minimumsignaturecount":1}}},{"value":"7000000000","condition":{"type":1,"data":{"unlockhash":"01972837ee396f22f96846a0c700f9cf7c8fa83ab4110da91a1c7d02f94f28ff03e45f1470df82"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"coinoutputids":["29152fe03a2c8782fcbd670579686088c52be83fa3870f5f0788073d97fb5fb2","0fc9b16bb180cd8f8a7144d65e6c8fca66994a4ccaee42e324289d4039ab2841"],"coinoutputunlockhashes":["039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a","01972837ee396f22f96846a0c700f9cf7c8fa83ab4110da91a1c7d02f94f28ff03e45f1470df82"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # the devnet genesis seed is the seed of the wallet,
    # which receives all block stakes and coins in the genesis block of the tfchain devnet
    DEVNET_GENESIS_SEED = "image orchard airport business cost work mountain obscure flee alpha alert salmon damage engage trumpet route marble subway immune short tide young cycle attract"

    # create a new devnet wallet
    w = c.wallets.new("mywallet", seed=DEVNET_GENESIS_SEED)
    # we create a new wallet using an existing seed,
    # such that our seed is used and not a new randomly generated seed

    # a tfchain (JS) wallet uses the underlying tfchain client for all its
    # interaction with the tfchain network
    assert w.network_type == "DEV"

    # getting the balance of a wallet is as easy as getting the 'balance' property
    balance = w.balance

    # the available and locked tokens can be easily checked
    assert balance.available == "3698 TFT"
    assert balance.locked == 0

    # (1) sending coins to a personal wallet on the used tfchain network can be done as follows:
    result = w.coins_send(
        recipient="015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
        amount="108.24",  # the amount of TFT to send
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate the transaction is as expected
    expected_transaction = {
        "version": 1,
        "data": {
            "coininputs": [
                {
                    "parentid": "19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376",
                    "fulfillment": {
                        "type": 1,
                        "data": {
                            "publickey": "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                            "signature": "781c886bd135ee068c407fc80c639530579e422dc4e006383eb9fa3b25a1091f3d31836b52254a8fb0f4ab031effff9ba5cc77949215e06ac6b7c934bd9d470c",
                        },
                    },
                }
            ],
            "coinoutputs": [
                {
                    "value": "108240000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash": "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"
                        },
                    },
                },
                {
                    "value": "88760000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash": "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
                        },
                    },
                },
            ],
            "minerfees": ["1000000000"],
        },
    }
    assert result.transaction.json() == expected_transaction
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    # (2) sending coins to a personal wallet with a lock and data is possible as well
    result = w.coins_send(
        recipient="015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
        amount=200,  # the amount of TFT to send
        lock="07/12/2020 14:35",  # a lock can be a timestamp, data-time str, duration str, or block height
        data="maximum 83 bytes can be used as optional data",
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate the transaction is as expected
    expected_transaction = {
        "version": 1,
        "data": {
            "coininputs": [
                {
                    "parentid": "b90422bad2dffde79f0a46bd0a41055cf7974b080e115d76f69891ca31d31f11",
                    "fulfillment": {
                        "type": 1,
                        "data": {
                            "publickey": "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                            "signature": "4b9ad9b6937a4818141bee70c6785af0eea12f0dbe8e3e784bb5cc36d5c6acd00270e9963f5547ec4c36509a728941d32cb5d15fa1131476ea31d6ca21149b03",
                        },
                    },
                }
            ],
            "coinoutputs": [
                {
                    "value": "200000000000",
                    "condition": {
                        "type": 3,
                        "data": {
                            "locktime": 1607351700,
                            "condition": {
                                "type": 1,
                                "data": {
                                    "unlockhash": "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"
                                },
                            },
                        },
                    },
                },
                {
                    "value": "299000000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash": "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
                        },
                    },
                },
            ],
            "minerfees": ["1000000000"],
            "arbitrarydata": "bWF4aW11bSA4MyBieXRlcyBjYW4gYmUgdXNlZCBhcyBvcHRpb25hbCBkYXRh",
        },
    }
    assert result.transaction.json() == expected_transaction
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    # (3) one can also send to full multi-sig wallet
    result = w.coins_send(
        recipient=[
            "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
            "010d22cf70053432d70ea08c6940c9e84c4c89e67ad24c3ff9f0444dd2d03bf77c91b3e02c30a1",
        ],
        amount="50 TFT",  # the amount of TFT to send
        lock=1550665225,  # a lock can be a timestamp, data-time str, duration str, or block height
        data=b"binary data can be added as well",
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate the transaction is as expected
    expected_transaction = {
        "version": 1,
        "data": {
            "coininputs": [
                {
                    "parentid": "19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376",
                    "fulfillment": {
                        "type": 1,
                        "data": {
                            "publickey": "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                            "signature": "5d51a67cfd93e1960553c8281a27a047c6b505800efb3106014baf4eea59188c43c993bac4af0a1b789a8054872a07b3137982c584dce42d8477700c4ae77a0a",
                        },
                    },
                }
            ],
            "coinoutputs": [
                {
                    "value": "50000000000",
                    "condition": {
                        "type": 3,
                        "data": {
                            "locktime": 1550665225,
                            "condition": {
                                "type": 4,
                                "data": {
                                    "minimumsignaturecount": 2,
                                    "unlockhashes": [
                                        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
                                        "010d22cf70053432d70ea08c6940c9e84c4c89e67ad24c3ff9f0444dd2d03bf77c91b3e02c30a1",
                                    ],
                                },
                            },
                        },
                    },
                },
                {
                    "value": "147000000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash": "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
                        },
                    },
                },
            ],
            "minerfees": ["1000000000"],
            "arbitrarydata": "YmluYXJ5IGRhdGEgY2FuIGJlIGFkZGVkIGFzIHdlbGw=",
        },
    }
    assert result.transaction.json() == expected_transaction
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    # (4) one can also send to a x-out-of-n multisig wallet
    result = w.coins_send(
        recipient=(
            1,
            [
                "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
                "010d22cf70053432d70ea08c6940c9e84c4c89e67ad24c3ff9f0444dd2d03bf77c91b3e02c30a1",
            ],
        ),
        amount="300.0",  # the amount of TFT to send
        lock=35000,  # a lock can be a timestamp, data-time str, duration str, or block height
        data=bytearray(b"binary data can be added as well"),
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate the transaction is as expected
    expected_transaction = {
        "version": 1,
        "data": {
            "coininputs": [
                {
                    "parentid": "b90422bad2dffde79f0a46bd0a41055cf7974b080e115d76f69891ca31d31f11",
                    "fulfillment": {
                        "type": 1,
                        "data": {
                            "publickey": "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                            "signature": "027d44a7d16fa29c0ae9bfdbfbd18bf029864b14c4a0444b6d2e16145175e1df2c446ff77105731a76bbd40e8bc9e36439949e1f8311d997b4bb3273ed2b7e03",
                        },
                    },
                }
            ],
            "coinoutputs": [
                {
                    "value": "300000000000",
                    "condition": {
                        "type": 3,
                        "data": {
                            "locktime": 35000,
                            "condition": {
                                "type": 4,
                                "data": {
                                    "minimumsignaturecount": 1,
                                    "unlockhashes": [
                                        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
                                        "010d22cf70053432d70ea08c6940c9e84c4c89e67ad24c3ff9f0444dd2d03bf77c91b3e02c30a1",
                                    ],
                                },
                            },
                        },
                    },
                },
                {
                    "value": "199000000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash": "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
                        },
                    },
                },
            ],
            "minerfees": ["1000000000"],
            "arbitrarydata": "YmluYXJ5IGRhdGEgY2FuIGJlIGFkZGVkIGFzIHdlbGw=",
        },
    }
    assert result.transaction.json() == expected_transaction
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    # ensure we have the multi-sig wallet that we think we have
    mw = w.balance.wallets["039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a"]
    assert mw.owners == [
        "01ffd7c884aa869056bfb832d957bb71a0005fee13c19046cebec84b3a5047ee8829eab070374b",
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
    ]
    assert mw.signature_count == 1
    assert mw.available == "42 TFT"
    assert mw.unconfirmed == "0 TFT"
    assert mw.locked == "0 TFT"

    # (5) spending from a multi-sig wallet can be done as follows
    result = w.coins_send(
        recipient="015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
        amount=20,  # the amount of TFT to send
        lock=None,  # a lock can be a timestamp, data-time str, duration str, or block height
        data="some data",
        source="039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a",
    )
    assert result.submitted  # it is expected the transaction is submitted, as it is a 1-of-2 signature wallet

    # validate the transaction is as expected
    expected_transaction = {
        "version": 1,
        "data": {
            "coininputs": [
                {
                    "parentid": "29152fe03a2c8782fcbd670579686088c52be83fa3870f5f0788073d97fb5fb2",
                    "fulfillment": {
                        "type": 3,
                        "data": {
                            "pairs": [
                                {
                                    "publickey": "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                                    "signature": "c8efb66be71f7b991148bb479620d93dc909ea6982d640f304655969a7f22265134bd46f7e33868bbbe8a4a2451a68c18ae8380b45bb524c46cc76b1bac0780b",
                                }
                            ]
                        },
                    },
                }
            ],
            "coinoutputs": [
                {
                    "value": "20000000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash": "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"
                        },
                    },
                },
                {
                    "value": "21000000000",
                    "condition": {
                        "type": 4,
                        "data": {
                            "minimumsignaturecount": 1,
                            "unlockhashes": [
                                "01ffd7c884aa869056bfb832d957bb71a0005fee13c19046cebec84b3a5047ee8829eab070374b",
                                "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
                            ],
                        },
                    },
                },
            ],
            "minerfees": ["1000000000"],
            "arbitrarydata": "c29tZSBkYXRh",
        },
    }
    assert result.transaction.json() == expected_transaction
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    c.wallets.delete()
    c.delete()
def test():
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="atomicswap_verify_receiver")'
    """

    cleanup("test_unittest_client")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("test_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c",
        '{"hashtype":"blockid","block":{"minerpayoutids":["c8f3f82e4c5be07c667f140456e188336dc5c86319260ad9964c1b2a553d7031"],"transactions":[{"id":"9d8823855c59ac903238849e2f31600a9bec2c27d36071402815046dbf8000e7","height":17384,"parent":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["be4408fecfa7fb88831d6ff1ff2d32377c25ac6cdafcdec1a16644ef3540d0ea"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","timestamp":1549705757,"pobsindexes":{"BlockHeight":17383,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to initiate an atomic swap contract
    w = c.wallets.new(
        "mytestwallet",
        seed=
        "remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )

    # one can verify that its transaction is sent as receiver,
    # usually done when someone is the receiver of an intiation contract,
    # such that all details can be verified prior to the creation of the
    # participation contract on the other chain

    # verification will fail if the contract could not be found
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractNotFound):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486")

    # add the coin output info of the submitted atomic swap contract
    explorer_client.hash_add(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"fd583a124677a3ea7ed7981d008ca79bd9f93cedbee97af2bcfd28b3f31093cc","height":17383,"parent":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511","fulfillment":{"type":1,"data":{"publickey":"ed25519:cf87843f9c9014700eaa2dc28a80e4a54587d8cca0baa717805ce117cecd9bb4","signature":"b9ce44b1e0f9e3fae9f21111ddc08333f6ba32675fc971893f6ab7ca3e5ab664883794fd3a35aef59ba54242d9be92fbcf65cefb5eede3709dd57226203b6601"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b88206a3300dea3dd5f6cd73568ac5797b078910c78cbce6a71fcd0837a3ea5a4f2ed9fc70a1","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}}},{"value":"99994136000000000","condition":{"type":1,"data":{"unlockhash":"017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}},"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}],"coinoutputids":["dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","75bbe54aca26d5a5afbc442c0e033a3ad18efa1e130f0776a9e4b68cdbe24fb7"],"coinoutputunlockhashes":["02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d","017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )

    # one can verify it all manually
    contract = w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486")
    assert contract.outputid == "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486"
    assert contract.amount == "50 TFT"
    assert contract.refund_timestamp == 1549878527
    assert contract.sender == "01b88206a3300dea3dd5f6cd73568ac5797b078910c78cbce6a71fcd0837a3ea5a4f2ed9fc70a1"
    assert contract.receiver == "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"
    assert contract.secret_hash == "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1"

    # the amount can however be verified automatically
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        amount=50)
    # which will fail if the amount is wrong
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            amount=42)

    # the secret hash can be verified as well, very important
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        secret_hash=
        "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1",
    )
    # which will fail if the secret hash is wrong
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            secret_hash=
            "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c2",
        )

    # a minimum duration can also be defined, where the duration defines how long it takes until the
    # contract becomes refundable, 0 if already assumed to be refundable
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        min_refund_time="+1d12h")
    # which will fail if assumed wrong
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            min_refund_time="+2d")

    # if one is assumed to be the receiver, it can also be verified automatically
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        receiver=True)
    # if one assumed its position wrong, it will however fail
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            sender=True)

    # all can be verified at once of course
    contract = w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        amount=50,
        secret_hash=
        "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1",
        min_refund_time="+1d12h",
        receiver=True,
    )

    # once the expected min duration has been surpassed, validation will fail
    explorer_client.hash_add(
        "5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c",
        '{"hashtype":"blockid","block":{"minerpayoutids":["c8f3f82e4c5be07c667f140456e188336dc5c86319260ad9964c1b2a553d7031"],"transactions":[{"id":"9d8823855c59ac903238849e2f31600a9bec2c27d36071402815046dbf8000e7","height":17384,"parent":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["be4408fecfa7fb88831d6ff1ff2d32377c25ac6cdafcdec1a16644ef3540d0ea"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","timestamp":1549791703,"pobsindexes":{"BlockHeight":17383,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    # our initial hope would be wrong now
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            amount=50,
            secret_hash=
            "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1",
            min_refund_time="+1d12h",
            receiver=True,
        )
    # it is still not refundable however,
    # and for multiple checks one can pass the contract that was already fetched
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        amount=50,
        secret_hash=
        "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1",
        min_refund_time="+1d",
        receiver=True,
        contract=contract,
    )

    c.wallets.delete()
    c.delete()
def test():
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="atomicswap_refund")'
    """

    cleanup("test_unittest_client")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("test_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c",
        '{"hashtype":"blockid","block":{"minerpayoutids":["c8f3f82e4c5be07c667f140456e188336dc5c86319260ad9964c1b2a553d7031"],"transactions":[{"id":"9d8823855c59ac903238849e2f31600a9bec2c27d36071402815046dbf8000e7","height":17384,"parent":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["be4408fecfa7fb88831d6ff1ff2d32377c25ac6cdafcdec1a16644ef3540d0ea"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","timestamp":1549705757,"pobsindexes":{"BlockHeight":17383,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add the coin output info of the submitted atomic swap contract
    explorer_client.hash_add(
        "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"298b0a1d2da4ba13b3a787daea96da9e50ae6c299f6e3bea5ec3d50ee131c381","height":17740,"parent":"fa81bd33c4115e6a51f6f80107493a1b7e7591001d61948e88ef3cbb660e6fbe","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"1137db84e433980d51d66524dba5eec1c622c58099b9a1608f47293e506fa5338a0cd2d2d068506aed7de2a702025d9f7ec639ab712a1b32417677d4ab7ad50f"}}}],"coinoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}}},{"value":"28000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"],"arbitrarydata":"YSBjb250cmFjdCB0aGF0IGlzIG5vdCBhIGNvbnRyYWN0"}},"coininputoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","deb0edcd4f4971819dd07aff0ff5565a53cd939f71f0a44d43f1deac1721dcc6"],"coinoutputunlockhashes":["025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527","01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # add initial wallet info
    explorer_client.hash_add(
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"298b0a1d2da4ba13b3a787daea96da9e50ae6c299f6e3bea5ec3d50ee131c381","height":17740,"parent":"fa81bd33c4115e6a51f6f80107493a1b7e7591001d61948e88ef3cbb660e6fbe","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"1137db84e433980d51d66524dba5eec1c622c58099b9a1608f47293e506fa5338a0cd2d2d068506aed7de2a702025d9f7ec639ab712a1b32417677d4ab7ad50f"}}}],"coinoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}}},{"value":"28000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"],"arbitrarydata":"YSBjb250cmFjdCB0aGF0IGlzIG5vdCBhIGNvbnRyYWN0"}},"coininputoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","deb0edcd4f4971819dd07aff0ff5565a53cd939f71f0a44d43f1deac1721dcc6"],"coinoutputunlockhashes":["025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527","01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"4a7ac7930379675c82d0462a86e6d6f4018bdb2bdabaf49f4c177b8de19b4e7c","height":16930,"parent":"c25f345403080b8372a38f66608aa5a2287bdc61b82efe5ee6503ce85e8bcd35","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b5081e41797f53233c727c344698400a73f2cdd364e241df915df413d3eeafb425ce9b51de3731bcbf830c399a706f4d24ae7066f947a4a36ae1b25415bcde00"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c","hashedsecret":"4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba","timelock":1549736249}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"],"coinoutputunlockhashes":["02fb27c67c373c2f30611e0b98bf92ed6e6eb0a69b471457b282903945180cd5c5b8068731f767"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"b147985d381bc626ef79219ca988b5b1e2d328ade10cd7f3d48b96ca67928155","height":17698,"parent":"e8656ff72f9288c9ece3f85e489389f3c77e84052db13702b03dcff266a4d844","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"4a7a15125f4e8819b4cf57dfe5f0389f45b0779b2a4bf27d885b4de8659ad363eb5be8c38ec88b33fc6fe1d18c55a9c0220f21977d36d1c8f63d582c8c126b0d","secret":"f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756"}}}],"coinoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b88206a3300dea3dd5f6cd73568ac5797b078910c78cbce6a71fcd0837a3ea5a4f2ed9fc70a1","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}},"unlockhash":"02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d"}],"coinoutputids":["b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"bca044302e018e67600bd0bd3223ae8dbb702eb528e73d6cfa9d057d4f73b03a","height":16911,"parent":"b4882a0b8632396a9c5d83a5c8684ab76736f4bff6d971795ed7334fac8aa339","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"357451c3f3a15f6150aedede9d5228ec5dfc2d32c9b62c2a46128533a7845c72","fulfillment":{"type":1,"data":{"publickey":"ed25519:fdb2e1b898dda304f748c0ff812a24729b2aafd344512079ab778eb368b18645","signature":"bd9dd36e86c08a5990ad5282d1079705c3a4b1cf3896e96791aa7db97002d5eb002c50467f45bd3ac1086292932cd2ab53c91b2e8bb74b9d9c9c0d558082ef08"}}}],"coinoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}},{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994239000000000","condition":{"type":1,"data":{"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}},"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}],"coinoutputids":["753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to redeem a contract
    w = c.wallets.new(
        "mytestwallet",
        seed=
        "remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )

    # balance should be 0 at this point
    assert w.balance.available == "28 TFT"

    # if the output identifier is wrong, the refund will fail
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractNotFound):
        w.atomicswap.refund(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d5")

    # if not authorized, refund will also fail
    fw = c.wallets.new("foo")
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapForbidden):
        fw.atomicswap.refund(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    # if not refundable yet, refund will still fail
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapForbidden):
        w.atomicswap.refund(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    # if the blockchain is updated, and the time for refund has reached, things will become possible
    explorer_client.chain_info = '{"blockid":"325adb8b1198071b0873fdf3cd14c2090ab41b1ddf04556929513ac9b993de00","difficulty":"25314","estimatedactivebs":"2473","height":17776,"maturitytimestamp":1549710377,"target":[0,2,150,191,242,114,194,147,165,155,81,115,131,110,151,69,195,82,72,171,51,207,157,226,142,254,6,122,72,56,5,109],"totalcoins":"0","arbitrarydatatotalsize":4384,"minerpayoutcount":17864,"transactioncount":18405,"coininputcount":639,"coinoutputcount":1234,"blockstakeinputcount":17776,"blockstakeoutputcount":17777,"minerfeecount":628,"arbitrarydatacount":574}'
    explorer_client.hash_add(
        "325adb8b1198071b0873fdf3cd14c2090ab41b1ddf04556929513ac9b993de00",
        '{"hashtype":"blockid","block":{"minerpayoutids":["4c506e8cf50539ebd988de20892166f8aca71038e47817e5881dfbb7b5a72d1f"],"transactions":[{"id":"e28f35ab114ba22a889b2cd7027333fc4689b2b0dde5fd459614805f0eed2677","height":17776,"parent":"325adb8b1198071b0873fdf3cd14c2090ab41b1ddf04556929513ac9b993de00","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"9827b96889c6f6e97cfea0f44602b5e4a5ce53f6769a5d8d7153348836708fba","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"51abf8ae9cf011cc9c630fb64482214a4fea5928282192ee75c597e5db415b10bbd06c276a41c45d0b20b692093ceb6afd9014b31828cbc64a68e9ae533e260a"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["79ccce665ca8bfc1c277418ebfc2c488cd545469fcdaff009edee9ac32fcb747"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"7651b16bcf6c0672a212c1846a142888b3beb1087cdc72c2c45d9c49ab55b890","timestamp":1549710522,"pobsindexes":{"BlockHeight":17775,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"9827b96889c6f6e97cfea0f44602b5e4a5ce53f6769a5d8d7153348836708fba","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"51abf8ae9cf011cc9c630fb64482214a4fea5928282192ee75c597e5db415b10bbd06c276a41c45d0b20b692093ceb6afd9014b31828cbc64a68e9ae533e260a"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"325adb8b1198071b0873fdf3cd14c2090ab41b1ddf04556929513ac9b993de00","difficulty":"25314","estimatedactivebs":"2473","height":17776,"maturitytimestamp":1549710377,"target":[0,2,150,191,242,114,194,147,165,155,81,115,131,110,151,69,195,82,72,171,51,207,157,226,142,254,6,122,72,56,5,109],"totalcoins":"0","arbitrarydatatotalsize":4384,"minerpayoutcount":17864,"transactioncount":18405,"coininputcount":639,"coinoutputcount":1234,"blockstakeinputcount":17776,"blockstakeoutputcount":17777,"minerfeecount":628,"arbitrarydatacount":574},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )

    # once the contract can be refunded and you are authorized to refund the contract,
    # you can refund the atomic swap contract as follows:
    w.atomicswap.refund(
        "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    # once it becomes registered on the chain
    explorer_client.hash_add(
        "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"298b0a1d2da4ba13b3a787daea96da9e50ae6c299f6e3bea5ec3d50ee131c381","height":17740,"parent":"fa81bd33c4115e6a51f6f80107493a1b7e7591001d61948e88ef3cbb660e6fbe","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"1137db84e433980d51d66524dba5eec1c622c58099b9a1608f47293e506fa5338a0cd2d2d068506aed7de2a702025d9f7ec639ab712a1b32417677d4ab7ad50f"}}}],"coinoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}}},{"value":"28000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"],"arbitrarydata":"YSBjb250cmFjdCB0aGF0IGlzIG5vdCBhIGNvbnRyYWN0"}},"coininputoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","deb0edcd4f4971819dd07aff0ff5565a53cd939f71f0a44d43f1deac1721dcc6"],"coinoutputunlockhashes":["025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527","01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"e9a909b0198328b38da003c31571d26eb6a0df35c31eee7fd087bc6ffcfd3501","height":17821,"parent":"c92c56e9520c63d7cb3061319eaf46d22e69e7f93d73ea73596d8651a7834fa2","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b2d98b7d6e3c3634ed1f9fb992ac4f1bfa844126d8addac8ee764ef995a656b064c674803c646fba6c7201bf0f16c44b36c0e45702cc9e66fc5ed73934eadd09","secret":"0000000000000000000000000000000000000000000000000000000000000000"}}}],"coinoutputs":[{"value":"19000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}},"unlockhash":"025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527"}],"coinoutputids":["4a3602e082b5038f72254976ec9a833300e0a87571a4956b33faf126198e579a"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    explorer_client.hash_add(
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"298b0a1d2da4ba13b3a787daea96da9e50ae6c299f6e3bea5ec3d50ee131c381","height":17740,"parent":"fa81bd33c4115e6a51f6f80107493a1b7e7591001d61948e88ef3cbb660e6fbe","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"1137db84e433980d51d66524dba5eec1c622c58099b9a1608f47293e506fa5338a0cd2d2d068506aed7de2a702025d9f7ec639ab712a1b32417677d4ab7ad50f"}}}],"coinoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}}},{"value":"28000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"],"arbitrarydata":"YSBjb250cmFjdCB0aGF0IGlzIG5vdCBhIGNvbnRyYWN0"}},"coininputoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","deb0edcd4f4971819dd07aff0ff5565a53cd939f71f0a44d43f1deac1721dcc6"],"coinoutputunlockhashes":["025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527","01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"4a7ac7930379675c82d0462a86e6d6f4018bdb2bdabaf49f4c177b8de19b4e7c","height":16930,"parent":"c25f345403080b8372a38f66608aa5a2287bdc61b82efe5ee6503ce85e8bcd35","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b5081e41797f53233c727c344698400a73f2cdd364e241df915df413d3eeafb425ce9b51de3731bcbf830c399a706f4d24ae7066f947a4a36ae1b25415bcde00"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c","hashedsecret":"4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba","timelock":1549736249}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"],"coinoutputunlockhashes":["02fb27c67c373c2f30611e0b98bf92ed6e6eb0a69b471457b282903945180cd5c5b8068731f767"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"b147985d381bc626ef79219ca988b5b1e2d328ade10cd7f3d48b96ca67928155","height":17698,"parent":"e8656ff72f9288c9ece3f85e489389f3c77e84052db13702b03dcff266a4d844","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"4a7a15125f4e8819b4cf57dfe5f0389f45b0779b2a4bf27d885b4de8659ad363eb5be8c38ec88b33fc6fe1d18c55a9c0220f21977d36d1c8f63d582c8c126b0d","secret":"f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756"}}}],"coinoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b88206a3300dea3dd5f6cd73568ac5797b078910c78cbce6a71fcd0837a3ea5a4f2ed9fc70a1","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}},"unlockhash":"02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d"}],"coinoutputids":["b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"bca044302e018e67600bd0bd3223ae8dbb702eb528e73d6cfa9d057d4f73b03a","height":16911,"parent":"b4882a0b8632396a9c5d83a5c8684ab76736f4bff6d971795ed7334fac8aa339","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"357451c3f3a15f6150aedede9d5228ec5dfc2d32c9b62c2a46128533a7845c72","fulfillment":{"type":1,"data":{"publickey":"ed25519:fdb2e1b898dda304f748c0ff812a24729b2aafd344512079ab778eb368b18645","signature":"bd9dd36e86c08a5990ad5282d1079705c3a4b1cf3896e96791aa7db97002d5eb002c50467f45bd3ac1086292932cd2ab53c91b2e8bb74b9d9c9c0d558082ef08"}}}],"coinoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}},{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994239000000000","condition":{"type":1,"data":{"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}},"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}],"coinoutputids":["753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"e9a909b0198328b38da003c31571d26eb6a0df35c31eee7fd087bc6ffcfd3501","height":17821,"parent":"c92c56e9520c63d7cb3061319eaf46d22e69e7f93d73ea73596d8651a7834fa2","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b2d98b7d6e3c3634ed1f9fb992ac4f1bfa844126d8addac8ee764ef995a656b064c674803c646fba6c7201bf0f16c44b36c0e45702cc9e66fc5ed73934eadd09","secret":"0000000000000000000000000000000000000000000000000000000000000000"}}}],"coinoutputs":[{"value":"19000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}},"unlockhash":"025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527"}],"coinoutputids":["4a3602e082b5038f72254976ec9a833300e0a87571a4956b33faf126198e579a"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    explorer_client.chain_info = '{"blockid":"e7113d9220ed1d2b9580db56900275a84cae37f4a05d114f7c2e390e5548a748","difficulty":"16357","estimatedactivebs":"2062","height":17826,"maturitytimestamp":1549711238,"target":[0,4,1,160,229,117,42,154,91,220,26,179,144,72,8,24,83,164,54,113,254,108,169,110,240,86,243,41,58,188,99,94],"totalcoins":"0","arbitrarydatatotalsize":4384,"minerpayoutcount":17915,"transactioncount":18456,"coininputcount":640,"coinoutputcount":1235,"blockstakeinputcount":17826,"blockstakeoutputcount":17827,"minerfeecount":629,"arbitrarydatacount":574}'
    explorer_client.hash_add(
        "e7113d9220ed1d2b9580db56900275a84cae37f4a05d114f7c2e390e5548a748",
        '{"hashtype":"blockid","block":{"minerpayoutids":["dbddb3ae78bd05ae1673eb3dcd13bd9df54dd0e9fead56311cb53aeca4e8fff7"],"transactions":[{"id":"568969fac665b480b364f50c42920019e27c194ed876b36093bb3a5456b99f48","height":17826,"parent":"e7113d9220ed1d2b9580db56900275a84cae37f4a05d114f7c2e390e5548a748","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"efebc1649846007eacab3d119cd42daed8a240da8f9ebd31f2472df442467adb","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"28012952f77113862a48698af74d77055dd895c60ee6b07d583c3fe6db2fc70cc8ac5a72fa9d67acb7814df1409be26e5afd24dd9658a0aca8be4ef9bbb9230d"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["ad28a30a1846d1773070ca1ab0959344673402d211403b016bcdee6e85ed6ead"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"4df6fa9d77b675b1562740d602f42fa45a9f3d9458a2fa81959acc631db1c05e","timestamp":1549711355,"pobsindexes":{"BlockHeight":17825,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"efebc1649846007eacab3d119cd42daed8a240da8f9ebd31f2472df442467adb","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"28012952f77113862a48698af74d77055dd895c60ee6b07d583c3fe6db2fc70cc8ac5a72fa9d67acb7814df1409be26e5afd24dd9658a0aca8be4ef9bbb9230d"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"e7113d9220ed1d2b9580db56900275a84cae37f4a05d114f7c2e390e5548a748","difficulty":"16357","estimatedactivebs":"2062","height":17826,"maturitytimestamp":1549711238,"target":[0,4,1,160,229,117,42,154,91,220,26,179,144,72,8,24,83,164,54,113,254,108,169,110,240,86,243,41,58,188,99,94],"totalcoins":"0","arbitrarydatatotalsize":4384,"minerpayoutcount":17915,"transactioncount":18456,"coininputcount":640,"coinoutputcount":1235,"blockstakeinputcount":17826,"blockstakeoutputcount":17827,"minerfeecount":629,"arbitrarydatacount":574},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )

    # and the contract can no longer be refunded
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractSpent):
        w.atomicswap.refund(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    # should you verify it at this point, you'll get the same exception
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractSpent):
        w.atomicswap.verify(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    c.wallets.delete()
    c.delete()
Exemplo n.º 6
0
def test():
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="balance_drain")'
    """

    cleanup("dev_unittest_clinet")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("dev_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    explorer_client.hash_add(
        "000000000000000000000000000000000000000000000000000000000000000000000000000000",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"00d1eb537582e31f86a818b32e3a8e10110c1e4348b2d1d0c6746b4b75f3ddc8","height":8887,"parent":"09548093238b2592cc88e0e834a641bf2bcc6fe85275e50d0e179f720a5157c7","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"fb0ce589309af98870f7aa1b620948f8fbca2900d0729bfe1e4f501b45ae87c3","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"d0ff7079fcf804a011c7bfc226a2d9fc3ab07fbe135abbe44ebb81d64a59cb90bd647c48747e305d8af2c13ac04b8e4eb992156beeef3f31a74566684ad0c009"}}}],"coinoutputs":[{"value":"1","condition":{}},{"value":"2999999999","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"4000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["4be59838a2baaf69afbc558e961aae584f69b74ab72321799f380d02d5adea01","1744c053787a5662fad3651c0ed6c68b8bb5584370a81c95aa15cfcf220bfe13"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"040e33a58c70e3f912b0851650ba6708c6e167b05bbe1f15fc5e870e46de435a","height":8830,"parent":"a06da42631ed8bc80ba9b383474172900fa6b804758b2f6d866d95542b4b4a28","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"0846ce4e40bd153f4b24c1131908ba87e2c99d78615c16eaac846cb3ca033562","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"90e6d2c8bb8d5ba7d5edcf38cf87d7ce1ec9d936b6939c05571f5317fd83ba495f895adc8695eedd35087c08f780eff05a74240bf1245eac920971c604892802"}}}],"coinoutputs":[{"value":"1000000000","condition":{}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"2000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["6eb896edab9539b41077a7fb540a4987d5e8b434ec77e150c1e571d2883652f2"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"3d3ef900a0c54b45430c6248cf7bfbbbf92da663c84b73b10794eb2a9b0a74f5","height":7023,"parent":"e12271a40b3959d64cdf5d3845546c568a7db9313ca7b117a03454469cd6b348","rawtransaction":{"version":129,"data":{"nonce":"kyA3WfkRL6M=","mintfulfillment":{"type":3,"data":{"pairs":[{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"fa5560db80a0dcf7676885cf3517685c18bc82d787337299179d7c06271cbf724ced43d45f7bed7364c89f5adf5231264f322dee8d851606db8fd0494b45960e"}]}},"coinoutputs":[{"value":"1000000000","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"bW9yZSBmb3IgYWxs"}},"coininputoutputs":null,"coinoutputids":["0ffc3aceee0f3f695d1173056998e49e964c72c6b9d9ce08258f51cce6d9cd18"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"422ff9ec3d34e263a9eb910c41b4c031e5ff0b8ba9dc5377518e7ed2cfda72ec","height":8872,"parent":"2b465d727d65da5c2986ed8b9b1a3211cd27f7b99f4bc887c801f7bbfb05f884","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b4c0b5d51891608fc2bf0c93c001325ee5048ffdaf6239bca99b9cf46cbe6932","fulfillment":{"type":3,"data":{"pairs":[{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"7303e9e048ee66def55305fb069d9a75cc15e96168bd85ca102dfdea2c26a4e3776adcae341610e85217508cf24a3a82f711f12286d1de37fc248b375556fd08"},{"publickey":"ed25519:9e310aa31e236f4f1da9c5384138674dc68323da2d8d6cf6e8ee5055b88b61e3","signature":"acd50c4825e639e6423b07022b5b69125ee04014adc6b870e358222dc4a7b2733200ad68aa4f978fba2e306acb06912ae625cfd697f42d9d20bdac3e7faf5f0f"}]}}}],"coinoutputs":[{"value":"42000000000","condition":{}},{"value":"390999999534","condition":{"type":4,"data":{"unlockhashes":["0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab","01822fd5fefd2748972ea828a5c56044dec9a2b2275229ce5b212f926cd52fba015846451e4e46"],"minimumsignaturecount":2}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"433999999534","condition":{"type":4,"data":{"unlockhashes":["0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab","01822fd5fefd2748972ea828a5c56044dec9a2b2275229ce5b212f926cd52fba015846451e4e46"],"minimumsignaturecount":2}},"unlockhash":"03e9dbb15388d815ecb1d898bf94cc60e37053d12c7fe97bba2578c8b6a7dbdfb0b3caff77c6c6"}],"coinoutputids":["170815e3fd93f34e5b40644dd116efcfa27fd3e4f6992a68759978336a16fe5e","8ffb6836d68e12a9eb99b8b312399832cdfcbe461d75c3ceca6256b5afabe29e"],"coinoutputunlockhashes":["","03e9dbb15388d815ecb1d898bf94cc60e37053d12c7fe97bba2578c8b6a7dbdfb0b3caff77c6c6"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"617c2fd23b25a55c688e0cdb97c456b51bda09fdac24bc08e20196c25a3f4f95","height":6825,"parent":"7798fefb7ff9d07672c10028b1e26c1fe44865bbf47c150cb7dabb539dce8cb3","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"d5b4eddf4472bb5014b132ec331fd5e09421917d183ce31a58fa7a272b01b25d","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"f15072fedb61b6526c65f8dc0bee871bf51fe413de8bddf6a74edc0985aec41784cb54c4d756f0bc36e871a981e46ce23361345d8d092c9212ea92a995897c06"}}}],"coinoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214"}}},{"value":"89000000000","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"ZnJvbSBtZSAoMik="}},"coininputoutputs":[{"value":"100000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["b910bb831df2454bc739f90a9854649f0f6a6be215497e14205a8e25d159d551","445579891a0c84b3b362f5266204c7b34cebe50b9d55ea6c9a05048baf7b5bf2"],"coinoutputunlockhashes":["01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214",""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"7273cb1475fe04ea9f0ba1fd3e201fc39b416a580a5d0b3b8444e2e49b75bd95","height":8766,"parent":"c7db16c052e7899b03ff2e31d1dbd176420f816199c884a5ca080a328b028965","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"d3446e886a480405f74a78bc8347f5b822abc58622fa0ef102f4f4272dede799","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"5206f05fe42b4ba41658284dab74ab7f70ef47513d4ef4e0e9a9f361df8eee16d524ffdb311593d1373fa838447c7a36434568c833ed5820224b64334fd6ab0c"}}}],"coinoutputs":[{"value":"1000000000","condition":{}},{"value":"2000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"4000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["4f524b591aea65c5b36c8ef18102f2a69d6a7e07c54e3cedbd6fc85ac8ed2611","0846ce4e40bd153f4b24c1131908ba87e2c99d78615c16eaac846cb3ca033562"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"8603ede968d434a5c61cf6cc8bf474aa6225823e72d500ad20b90293408a2694","height":11264,"parent":"ff6d7607ae89047482eb647ba915a1e305fcc5d0115686ab69d6cbf35f6b82b6","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"e2a567179c6e9fda9d30d5476a74cbc297829852afc23c644b566555a71e2a3b","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"77b026caf2cb18ccd628043e9f8728a064036d1ee845eb638b9dc44a4c7a7171e2513d2161172b574341268d7c142d78e20af978576265c1c0bd37a2327b250e"}}},{"parentid":"996d4956f5de5354a63ff644bcac26c30f3fe1f2a18ae17a457cd999bd8e9447","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"658dc60c13bd677679a904b0e7dc847b471841648679de40586aa2542a2b235c3dd3ece8e6b7b74678107d782c7608db4c6695f18ab1192a6048d1a9c423da09"}}}],"coinoutputs":[{"value":"100000000000","condition":{}},{"value":"15000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"31000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"},{"value":"85000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["ea75d01b64a05e1652bbc334a9fabf8ec0fa11f02c7d3657b4be3f3270a927d5","cf83f6453aaa7a49db8c448a86bf5e26715075a5b608e15d1628df5d2e1ed4ae"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"972482a9407b16272b6f79e7df27d1ebe29587ab76081c8569f098fc33998768","height":11264,"parent":"ff6d7607ae89047482eb647ba915a1e305fcc5d0115686ab69d6cbf35f6b82b6","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"1744c053787a5662fad3651c0ed6c68b8bb5584370a81c95aa15cfcf220bfe13","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"9085545b4884a0724925ad88e311199961a51e018f985ba262d7516a0293c416e774ead5f1de44012e784522b12cc43bc3ba1680b4df1bf25785ab2e7094c200"}}}],"coinoutputs":[{"value":"1000000000","condition":{}},{"value":"999999999","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"2999999999","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["4834fadc322aa9cfdef0294e98624424c1f972523d335f8ae45175b1035f8958","de7ce2184e2a5c6f2f0d643a1ea08902459c2ee983127051f240a6819ae4bc35"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"9e537af0eb87f6820341a7b435195ed89f0b3e003bb4c3715f30d6a713645bb7","height":7055,"parent":"fd5cfca2da14430c6e42ae65d15af9268addc469258cdb62d14553c8f05757a3","rawtransaction":{"version":129,"data":{"nonce":"IBKoTH6nDgM=","mintfulfillment":{"type":1,"data":{"publickey":"ed25519:32b9bdde2a079a4e0b75ab38b281ed67baabeff5dc27b1792190a0be900f6d90","signature":"e679cbddecb145d3d79fc4604c1ddd1443f59340e0e2f968623713b1d540615cd253a305bd456cb0f0cc125d3a2a2aa60408518927233884c53b3dba045a1e02"}},"coinoutputs":[{"value":"1000000000","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"bW9yZSBmb3IgYWxs"}},"coininputoutputs":null,"coinoutputids":["ebd166582e892cdbbc01b71c29b9a0e64f0f69eb91e7a1d99ffde99307ecaa2e"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"9fcf663997809994acf89899f029e9e1eccb4ee64390af3797f771a61ea14575","height":6805,"parent":"ef827bb13a75e61126fe75d9a6fd1956a10a5feb824259c03fe04e1dc9a57968","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"47e816e82e699e4e15c2d03d1a69d24a8c49933a4fc09f2d28d23c3fbf3b8c90","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"99904e9745db92a8ac155ac9b4a59de8fde2757269ce76ed2640f010cc9b6235774115193fc55c96cdced3997f6688ffad7a4db56a2809c41cc591b46d746b02"}}}],"coinoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214"}}},{"value":"475999999500","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"ZnJvbSBtZSgxKQ=="}},"coininputoutputs":[{"value":"486999999500","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["d4d8124abbecf29f965dc4186bbaa4c42758202775310522e9168609e85952ad","28bcc4bdef67f304b64b4525443c5257f775ea89122a6b9f2f4526af701aaeff"],"coinoutputunlockhashes":["01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214",""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"c15ccc0e6120d156104b9b2fa64adf6688a4d6b9bfaa56b87215b5d1b92c076a","height":12165,"parent":"231f22fab108316d06bd3c33a8189560ea5e7322dfb62dcaf6f21ea437ceedfc","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"8908d1b7af0ed9d9a16c00dcbccd583c027c737df4233cd70c5c94abf6f177ff","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"bb0cef5bef645b4a8cd77986bf5923dbb54415157bb113615da71fdded9109f8e30e04264066381c3d2782f1733063076974596d9c9faf76e420fc9dcd763704"}}}],"coinoutputs":[{"value":"1000000000","condition":{"type":3,"data":{"locktime":1609412400,"condition":{}}}},{"value":"11000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"],"arbitrarydata":"aGFwcHkgZWFybHkgbmV3IHllYXI="}},"coininputoutputs":[{"value":"13000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["ed1a8a793203d59c9a43483a78fc0143f5cab3881e94c928ecc46443127ae14f","efc235db4100bc88a01bf48cb15df0ac5f3efc2aa634c563dc7b61b9c837e083"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"c1faca5dbf14484df8ea5ee9555946d34853f1af154fb2ecf45802af3fd58390","height":7011,"parent":"97e2632ca8941a04ceaf688aec591926726a5786adba5887d3372bf98c5c3bd0","rawtransaction":{"version":129,"data":{"nonce":"Q9QjsC/7ixI=","mintfulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"8e0fd7a3f710b6bece93e9fcdf0da742512bd3010f068348f242cda97f914dad3fac922f7225023d501c42e3a944910d5baa4df5b0e23f777332f86b329b3408"}},"coinoutputs":[{"value":"1000000000000000","condition":{"type":3,"data":{"locktime":42,"condition":{}}}}],"minerfees":["1000000000"],"arbitrarydata":"Y29pbnMgZm9yIGFsbCB0aGUgcGVvcGxl"}},"coininputoutputs":null,"coinoutputids":["5cc1cdcd0962403ee112509033c87eca5e07468f3c996f1f1e3240a6e806a920"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"c4c17978c29e4fbc1c202c9b46b641efad059250f0fa4009d19ff252425f7e40","height":12181,"parent":"1cae514a987b8d5d5f13ee9d22998146c75bc633078f43df3540ab8f8ad1f7a4","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"e4691377980ad92560769a1ae7161f7e4cceec065542ae72000a66fbb3154232","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"aa489200decf5b2c7b9623f0c5819d9ece8cbd8115e71b65e5965ddd10521ab28a5a12d829010d88524a46783bd04ab60de21e5d7f85f057b2290c32b06aa009"}}}],"coinoutputs":[{"value":"1000000000","condition":{}},{"value":"2000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"],"arbitrarydata":"bW9yZSBmcmVlIG1vbmV5"}},"coininputoutputs":[{"value":"4000000000","condition":{"type":3,"data":{"locktime":1262300400,"condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["126e7a270a3548a67e7756497506a4a53e578d5b818d7dec28117f92f8b74a6d","e04651829ae0e4636a958057c1426c4fc63569ccb04406b54bce472c3322af86"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"ce1b49ec09d52e18b8e9038f6fc4a51627f1a417cfc044d995cce416f06b7802","height":6827,"parent":"dbd1bc09dd3c501a8674a699c297cd1dd50bf3d0d87a2c79a80c313f85375361","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"fe236bf66b542be84d50e0445449f6eddb11ffd93aa044040a73e35a3b33d8d9","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"116602636fa757b92b1ac06837cbcfecb7e0ceb553cc07ef819b557b872cc671ec27971171ba180595fa4d35bc748d6be9e899d0802179a355c07f2d9739100e"}}}],"coinoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214"}}},{"value":"89000000000","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"ZnJvbSBtZSAoMyk="}},"coininputoutputs":[{"value":"100000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["de63dc7d73748cb41909688a29f52e7eb32aef37c30738d1e5c993bab26c7066","5ff190d50ea0d63ecfdd1500aa146344864c82512e1492947405552e1689d31a"],"coinoutputunlockhashes":["01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214",""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"ce8f3ee3835afb7f587ab2473bf9eaacda7dbd27f8f36761ca62f9f12af68ecc","height":7026,"parent":"b38334513e11a5b93988af07b6ea8f39c808be6a3b0478f9f8a6bd7728a5f235","rawtransaction":{"version":129,"data":{"nonce":"Ewj99diiO6U=","mintfulfillment":{"type":3,"data":{"pairs":[{"publickey":"ed25519:9e310aa31e236f4f1da9c5384138674dc68323da2d8d6cf6e8ee5055b88b61e3","signature":"d39465e4522a08de394001160d0da5fd3dc4c2ca53ee6c571bf368786a66d137ace2b2ac927d09195ea32bd9e4cb6fc979e7994b8ea99b638f29408f41388207"},{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"d5bf7d9948d9125fdb15a17cf03c30405ebd4d4dbbbb3d86884edd5062d6ceddd7b0a54c1c2f5d80f4e6ca352a9a66c2642a89d1b9ae185face9af6c740bfe00"}]}},"coinoutputs":[{"value":"42000000000","condition":{}}],"minerfees":["1000000000"]}},"coininputoutputs":null,"coinoutputids":["63891de50dcb285689e1cd02618917ab9df4c6001f14e63532a5a75716ec0b6c"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"ffd4ebd18d71c58674b28b116fc1cf67385a71b01b43104d817488dfd7e1c4c1","height":12159,"parent":"b93a31ee0eb16200101b07a4fd962bb8a8d928682b8d252a818fd7b56ff459e3","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"cf83f6453aaa7a49db8c448a86bf5e26715075a5b608e15d1628df5d2e1ed4ae","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"59cc566ac52b46eccf63480530dede3f773f289137ae3b1b333bdb09ae2d065983828af1751b28be76c31d61e445ca0e24abda60d1403b08b9edaaeab9e91402"}}}],"coinoutputs":[{"value":"1000000000","condition":{"type":3,"data":{"locktime":1549571431,"condition":{}}}},{"value":"13000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"15000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["9a8f6b4524e07d7f0d2ece2a0d00c31fad9082ee21d4966af0ba9130c6f4eb6f","8908d1b7af0ed9d9a16c00dcbccd583c027c737df4233cd70c5c94abf6f177ff"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.chain_info = '{"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1}'
    explorer_client.hash_add(
        "552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e",
        '{"hashtype":"blockid","block":{"minerpayoutids":["468db689f752414702ef3a5aa06238f03a4539434a61624b3b8a0fb5dc38a211"],"transactions":[{"id":"2396f8e57bbb9b22bd1d749d5de3fd532ea6886e9660a556a13571d701d83e27","height":3644,"parent":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["f683e7319659c61f54e93546bc41b57c5bffe79de26c06ec7371034465804c81"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"47db4274551b0372564f8d1ab89c596428f00e460c0b416327e53983c8765198","timestamp":1549012665,"pobsindexes":{"BlockHeight":3643,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    c._explorer_get = explorer_client.explorer_get

    # you can also get the balance from an unlock hash results
    balance = c.unlockhash_get(
        "000000000000000000000000000000000000000000000000000000000000000000000000000000"
    ).balance()
    assert len(balance.outputs_spent) == 0
    assert str(balance.available) == "1000843.999999501"
    assert str(balance.locked) == "2"

    # a balance can be drained,
    # meaning all confirmed outputs are spent
    txns = balance.drain(
        recipient=
        "01ffd7c884aa869056bfb832d957bb71a0005fee13c19046cebec84b3a5047ee8829eab070374b",
        miner_fee=c.minimum_miner_fee,
        data="drain the swamp",
        lock="06/06/2018 06:58",
    )
    assert len(txns) == 1
    txn = txns[0]
    # the given miner fee is used as the only miner fee
    assert len(txn.miner_fees) == 1
    assert txn.miner_fees[0] == c.minimum_miner_fee
    # the data should be asigned
    assert txn.data.value == b"drain the swamp"
    # all inputs should be orinating from the balance's available outputs
    assert [ci.parentid for ci in txn.coin_inputs
            ] == [co.id for co in balance.outputs_available]
    assert len(txn.coin_outputs) == 1
    # the only output should be the drain output
    co = txn.coin_outputs[0]
    assert co.condition.unlockhash == "01ffd7c884aa869056bfb832d957bb71a0005fee13c19046cebec84b3a5047ee8829eab070374b"
    assert co.value == (balance.available - c.minimum_miner_fee)
    # no block stake inputs or outputs are obviously defined
    assert len(txn.blockstake_inputs) == 0
    assert len(txn.blockstake_outputs) == 0

    # NOTE: balance.drain also takes an optional parameter 'unconfirmed` which is False by default,
    # if True unconfirmed outputs will also be used when available.

    c.delete()
def test():
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="minter_condition_set")'
    """

    cleanup("dev_unittest_client")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("dev_unittest_client", network_type="DEV")
    # or simply `c = j.tfchain.clients.dev_unittest_client`, should the client already exist

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    # define current block height
    explorer_client.chain_info = '{"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1}'
    explorer_client.hash_add(
        "552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e",
        '{"hashtype":"blockid","block":{"minerpayoutids":["468db689f752414702ef3a5aa06238f03a4539434a61624b3b8a0fb5dc38a211"],"transactions":[{"id":"2396f8e57bbb9b22bd1d749d5de3fd532ea6886e9660a556a13571d701d83e27","height":3644,"parent":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["f683e7319659c61f54e93546bc41b57c5bffe79de26c06ec7371034465804c81"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"47db4274551b0372564f8d1ab89c596428f00e460c0b416327e53983c8765198","timestamp":1549012665,"pobsindexes":{"BlockHeight":3643,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add initial condition
    explorer_client.mint_condition_add(
        condition=j.clients.tfchain.types.conditions.from_recipient(
            "01a006599af1155f43d687635e9680650003a6c506934996b90ae84d07648927414046f9f0e936"
        ),
        height=0,
    )
    # overwrite get/post logic
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # the devnet genesis seed is the seed of the wallet,
    # which receives all block stakes and coins in the genesis block of the tfchain devnet
    DEVNET_GENESIS_SEED = "image orchard airport business cost work mountain obscure flee alpha alert salmon damage engage trumpet route marble subway immune short tide young cycle attract"

    # create a new devnet wallet
    w = c.wallets.new("mywallet", seed=DEVNET_GENESIS_SEED)
    # we create a new wallet using an existing seed,
    # such that our seed is used and not a new randomly generated seed

    # only if you have the correct minting powers,
    # you can set a new minter definition, otherwise an error will be raised

    # set another mint condition manually
    explorer_client.mint_condition_add(
        condition=j.clients.tfchain.types.conditions.from_recipient(
            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
        ),
        height=3643,
    )

    condition = c.minter.condition_get()
    assert condition.unlockhash == w.address

    # (1) once you have the correct powers, you can can overwrite it as follows:
    result = w.minter.definition_set(minter=(
        1,
        [
            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
            "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f",
        ],
    ))
    # check if the current transaction is submitted
    assert result.submitted  # it is expected

    # check if all is fulfilled
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # set another mint condition manually
    explorer_client.mint_condition_add(
        condition=j.clients.tfchain.types.conditions.from_recipient((
            1,
            [
                "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
                "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f",
            ],
        )),
        height=3644,
    )

    # (2) when defining a new minter definition you can also attach data if desired
    result = w.minter.definition_set(
        minter=
        "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f",  # new minter power
        data=
        "redefine minter conditions",  # optional data, can also be as binary data
    )
    assert result.submitted  # it is expected the transaction is submitted
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentMultiSignature)
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # set another mint condition manually
    explorer_client.mint_condition_add(
        condition=j.clients.tfchain.types.conditions.from_recipient(
            "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f"
        ),
        height=3645,
    )

    # if an invalid recipient is given it, a ValueError or TypeError is raised
    with pytest.raises(j.exceptions.Value):
        w.minter.definition_set(minter=None)
    with pytest.raises(j.exceptions.Value):
        w.minter.definition_set(minter="0123bla")
    with pytest.raises(j.exceptions.Value):
        w.minter.definition_set(minter=1)

    # (3) if the wallet has no powers to redefine the powers,
    # the transaction will be not be submitted as the transaction won't be fulfilled
    result = w.minter.definition_set(
        minter=
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    assert not result.submitted
    assert not result.transaction.is_fulfilled()
    assert not result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)

    c.wallets.delete()
    c.delete()
Exemplo n.º 8
0
def test():
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="atomicswap_participate")'
    """

    cleanup("test_unittest_client")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("test_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"583266f598044ebd971110bd03510e950361c22b4ed818e7644b6d59c36fd5bc","difficulty":"29305","estimatedactivebs":"2067","height":16922,"maturitytimestamp":1549649615,"target":[0,2,60,124,18,9,53,143,255,130,219,75,17,252,30,24,177,101,116,228,26,221,54,224,30,251,45,78,1,199,78,60],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17006,"transactioncount":17547,"coininputcount":635,"coinoutputcount":1228,"blockstakeinputcount":16922,"blockstakeoutputcount":16923,"minerfeecount":624,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "583266f598044ebd971110bd03510e950361c22b4ed818e7644b6d59c36fd5bc",
        '{"hashtype":"blockid","block":{"minerpayoutids":["eb538b38d8fcf7b0ef037eccf8cab1096c2b98031311453c150b2b150c483941"],"transactions":[{"id":"92132a65558684f154a56232acf9b7dd1e003d0f3ebdb2c4b44494d3c5e7f658","height":16922,"parent":"583266f598044ebd971110bd03510e950361c22b4ed818e7644b6d59c36fd5bc","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ca1da3d88904a532692ad2bb67122747eea4d91ead119043253ecb34410bbcc3","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"120c7bdf823a45fde303a725a1d757b3ece975abcd326ec036c056c6499b6de6cd798f18f8dff8c7adebcf19901e358609e675871335a71678c17de3e1dadb04"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["615f6f9d28d97082b423de7a878830b739b8fc4737c7ed20d3923a0019dbaed6"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"35879735f395c25fa7c0366bec7002f960798517e5335b5f27348c3a1b1923d4","timestamp":1549649728,"pobsindexes":{"BlockHeight":16921,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ca1da3d88904a532692ad2bb67122747eea4d91ead119043253ecb34410bbcc3","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"120c7bdf823a45fde303a725a1d757b3ece975abcd326ec036c056c6499b6de6cd798f18f8dff8c7adebcf19901e358609e675871335a71678c17de3e1dadb04"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"583266f598044ebd971110bd03510e950361c22b4ed818e7644b6d59c36fd5bc","difficulty":"29305","estimatedactivebs":"2067","height":16922,"maturitytimestamp":1549649615,"target":[0,2,60,124,18,9,53,143,255,130,219,75,17,252,30,24,177,101,116,228,26,221,54,224,30,251,45,78,1,199,78,60],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17006,"transactioncount":17547,"coininputcount":635,"coinoutputcount":1228,"blockstakeinputcount":16922,"blockstakeoutputcount":16923,"minerfeecount":624,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add the wallet info
    explorer_client.hash_add(
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"bca044302e018e67600bd0bd3223ae8dbb702eb528e73d6cfa9d057d4f73b03a","height":16911,"parent":"b4882a0b8632396a9c5d83a5c8684ab76736f4bff6d971795ed7334fac8aa339","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"357451c3f3a15f6150aedede9d5228ec5dfc2d32c9b62c2a46128533a7845c72","fulfillment":{"type":1,"data":{"publickey":"ed25519:fdb2e1b898dda304f748c0ff812a24729b2aafd344512079ab778eb368b18645","signature":"bd9dd36e86c08a5990ad5282d1079705c3a4b1cf3896e96791aa7db97002d5eb002c50467f45bd3ac1086292932cd2ab53c91b2e8bb74b9d9c9c0d558082ef08"}}}],"coinoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}},{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994239000000000","condition":{"type":1,"data":{"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}},"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}],"coinoutputids":["753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to initiate an atomic swap contract
    w = c.wallets.new(
        "mytestwallet",
        seed="remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )
    # money is required to be available in the wallet
    assert str(w.balance.available) == "51"

    # a participation atomic swap contract can be created and signed as follows:
    result = w.atomicswap.participate(
        initiator="01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c",
        amount=50,
        secret_hash="4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
        submit=False,
    )  # submit=True is the default
    assert not result.submitted
    assert result.transaction.is_fulfilled()
    # the contract is returned as part of the result
    assert str(result.contract.amount) == "50"
    assert (
        str(result.contract.sender) == "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"
    )
    assert (
        str(result.contract.receiver)
        == "01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c"
    )
    assert result.contract.refund_timestamp > 1549649728
    assert result.contract.secret_hash == "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba"
    # one would than use `w.transaction_sign(result.transaction)` to submit it for real

    # however, usually an atomic swap contract is participated as follows:
    result = w.atomicswap.participate(
        initiator="01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c",
        amount=50,
        secret_hash="4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
    )
    assert result.submitted
    # the contract is returned as part of the result
    assert str(result.contract.amount) == "50"
    assert (
        str(result.contract.sender) == "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"
    )
    assert (
        str(result.contract.receiver)
        == "01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c"
    )
    assert result.contract.refund_timestamp > 1549649728
    assert result.contract.secret_hash == "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba"

    # ensure our contract was submitted
    transaction = explorer_client.posted_transaction_get(result.transaction.id)
    contract = AtomicSwapContract(transaction.coin_outputs[0], unspent=True)
    assert contract == result.contract
    # and ensure the transaction is fully signed
    for ci in transaction.coin_inputs:
        assert len(ci.fulfillment.signature.value) == 64

    # FYI: a contract's amount has to be greater than the network's minimum miner fee,
    # while tfchain does allow it, this client will raise an exception when you
    # do try to give a value equal to or less than the networks' miner fee.
    # This because such a contract cannot be redeemed or refunded.
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapInsufficientAmountError):
        w.atomicswap.participate(
            initiator="01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c",
            amount=c.minimum_miner_fee - "0.000000001 TFT",
            secret_hash="4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
        )

    c.wallets.delete()
    c.delete()
Exemplo n.º 9
0
def test():
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="atomicswap_redeem")'
    """

    cleanup("test_unittest_client")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("test_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c",
        '{"hashtype":"blockid","block":{"minerpayoutids":["c8f3f82e4c5be07c667f140456e188336dc5c86319260ad9964c1b2a553d7031"],"transactions":[{"id":"9d8823855c59ac903238849e2f31600a9bec2c27d36071402815046dbf8000e7","height":17384,"parent":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["be4408fecfa7fb88831d6ff1ff2d32377c25ac6cdafcdec1a16644ef3540d0ea"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","timestamp":1549705757,"pobsindexes":{"BlockHeight":17383,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add the coin output info of the submitted atomic swap contract
    explorer_client.hash_add(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"fd583a124677a3ea7ed7981d008ca79bd9f93cedbee97af2bcfd28b3f31093cc","height":17383,"parent":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511","fulfillment":{"type":1,"data":{"publickey":"ed25519:cf87843f9c9014700eaa2dc28a80e4a54587d8cca0baa717805ce117cecd9bb4","signature":"b9ce44b1e0f9e3fae9f21111ddc08333f6ba32675fc971893f6ab7ca3e5ab664883794fd3a35aef59ba54242d9be92fbcf65cefb5eede3709dd57226203b6601"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}}},{"value":"99994136000000000","condition":{"type":1,"data":{"unlockhash":"017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}},"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}],"coinoutputids":["dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","75bbe54aca26d5a5afbc442c0e033a3ad18efa1e130f0776a9e4b68cdbe24fb7"],"coinoutputunlockhashes":["02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d","017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to redeem a contract
    w = c.wallets.new(
        "mytestwallet",
        seed="remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )

    # balance should be 0 at this point
    assert w.balance.available == "0 TFT"

    # if the output identifier is wrong, the redemption will fail
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractNotFound):
        w.atomicswap.redeem(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb483",
            secret="f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756",
        )

    # if the secret is wrong, the redemption will fail as well
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapInvalidSecret):
        w.atomicswap.redeem(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            secret="f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53754",
        )

    # if not authorized, redemption will also fail
    fw = c.wallets.new("foo")
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapForbidden):
        fw.atomicswap.redeem(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            secret="f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756",
        )

    # once you know the secret, and you are authorized to receive the contract,
    # you can redeem the atomic swap contract as follows:
    w.atomicswap.redeem(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        secret="f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756",
    )

    # once it becomes registered on the chain
    explorer_client.hash_add(
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"4a7ac7930379675c82d0462a86e6d6f4018bdb2bdabaf49f4c177b8de19b4e7c","height":16930,"parent":"c25f345403080b8372a38f66608aa5a2287bdc61b82efe5ee6503ce85e8bcd35","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b5081e41797f53233c727c344698400a73f2cdd364e241df915df413d3eeafb425ce9b51de3731bcbf830c399a706f4d24ae7066f947a4a36ae1b25415bcde00"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c","hashedsecret":"4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba","timelock":1549736249}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"],"coinoutputunlockhashes":["02fb27c67c373c2f30611e0b98bf92ed6e6eb0a69b471457b282903945180cd5c5b8068731f767"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"b147985d381bc626ef79219ca988b5b1e2d328ade10cd7f3d48b96ca67928155","height":17698,"parent":"e8656ff72f9288c9ece3f85e489389f3c77e84052db13702b03dcff266a4d844","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"4a7a15125f4e8819b4cf57dfe5f0389f45b0779b2a4bf27d885b4de8659ad363eb5be8c38ec88b33fc6fe1d18c55a9c0220f21977d36d1c8f63d582c8c126b0d","secret":"f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756"}}}],"coinoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}},"unlockhash":"02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d"}],"coinoutputids":["b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"bca044302e018e67600bd0bd3223ae8dbb702eb528e73d6cfa9d057d4f73b03a","height":16911,"parent":"b4882a0b8632396a9c5d83a5c8684ab76736f4bff6d971795ed7334fac8aa339","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"357451c3f3a15f6150aedede9d5228ec5dfc2d32c9b62c2a46128533a7845c72","fulfillment":{"type":1,"data":{"publickey":"ed25519:fdb2e1b898dda304f748c0ff812a24729b2aafd344512079ab778eb368b18645","signature":"bd9dd36e86c08a5990ad5282d1079705c3a4b1cf3896e96791aa7db97002d5eb002c50467f45bd3ac1086292932cd2ab53c91b2e8bb74b9d9c9c0d558082ef08"}}}],"coinoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}},{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994239000000000","condition":{"type":1,"data":{"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}},"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}],"coinoutputids":["753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.hash_add(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"b147985d381bc626ef79219ca988b5b1e2d328ade10cd7f3d48b96ca67928155","height":17698,"parent":"e8656ff72f9288c9ece3f85e489389f3c77e84052db13702b03dcff266a4d844","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"4a7a15125f4e8819b4cf57dfe5f0389f45b0779b2a4bf27d885b4de8659ad363eb5be8c38ec88b33fc6fe1d18c55a9c0220f21977d36d1c8f63d582c8c126b0d","secret":"f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756"}}}],"coinoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}},"unlockhash":"02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d"}],"coinoutputids":["b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"fd583a124677a3ea7ed7981d008ca79bd9f93cedbee97af2bcfd28b3f31093cc","height":17383,"parent":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511","fulfillment":{"type":1,"data":{"publickey":"ed25519:cf87843f9c9014700eaa2dc28a80e4a54587d8cca0baa717805ce117cecd9bb4","signature":"b9ce44b1e0f9e3fae9f21111ddc08333f6ba32675fc971893f6ab7ca3e5ab664883794fd3a35aef59ba54242d9be92fbcf65cefb5eede3709dd57226203b6601"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}}},{"value":"99994136000000000","condition":{"type":1,"data":{"unlockhash":"017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}},"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}],"coinoutputids":["dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","75bbe54aca26d5a5afbc442c0e033a3ad18efa1e130f0776a9e4b68cdbe24fb7"],"coinoutputunlockhashes":["02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d","017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    explorer_client.chain_info = '{"blockid":"5de1f56636bde6d724c717a3eda954117ad647930a55125a210cd7da8986c365","difficulty":"33956","estimatedactivebs":"2680","height":17712,"maturitytimestamp":1549709563,"target":[0,1,238,19,74,206,147,40,0,177,159,111,31,15,189,145,26,160,171,28,217,59,25,165,140,61,86,216,188,238,159,35],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17799,"transactioncount":18340,"coininputcount":638,"coinoutputcount":1232,"blockstakeinputcount":17712,"blockstakeoutputcount":17713,"minerfeecount":627,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "5de1f56636bde6d724c717a3eda954117ad647930a55125a210cd7da8986c365",
        '{"hashtype":"blockid","block":{"minerpayoutids":["f66f6bde0f026d68f7ce64cbb0ce0169a48e7abd636536ade754d152dbe64e5c"],"transactions":[{"id":"c7b2f558cd8e6ac0d94e2f0c0b025682d142b78457acfed3b89dca493451f15a","height":17712,"parent":"5de1f56636bde6d724c717a3eda954117ad647930a55125a210cd7da8986c365","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"2bbf77cb889cafc8df69293c016c03c0b10420e6ed1d83bbe6e79529ed49ba00","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"b3c41e1964f055c027437576943bce92808ff24411a0bf19a56e81b74e6f5fd5d027f8aabe836a56cc2a81837fd73cfc09473a97ac0746b319f4a906f7bc7c02"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["9830f9a00955c797289a9ab17211a05f3e393c2d8728e7fcc6c25b9fe7afce74"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"a32ed0392681c2faccffb818dd14aa92c405315f9b538500d9d4d840834d3438","timestamp":1549709657,"pobsindexes":{"BlockHeight":17711,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"2bbf77cb889cafc8df69293c016c03c0b10420e6ed1d83bbe6e79529ed49ba00","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"b3c41e1964f055c027437576943bce92808ff24411a0bf19a56e81b74e6f5fd5d027f8aabe836a56cc2a81837fd73cfc09473a97ac0746b319f4a906f7bc7c02"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5de1f56636bde6d724c717a3eda954117ad647930a55125a210cd7da8986c365","difficulty":"33956","estimatedactivebs":"2680","height":17712,"maturitytimestamp":1549709563,"target":[0,1,238,19,74,206,147,40,0,177,159,111,31,15,189,145,26,160,171,28,217,59,25,165,140,61,86,216,188,238,159,35],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17799,"transactioncount":18340,"coininputcount":638,"coinoutputcount":1232,"blockstakeinputcount":17712,"blockstakeoutputcount":17713,"minerfeecount":627,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )

    # and the contract can no longer be redeemed
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractSpent):
        w.atomicswap.redeem(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            secret="f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756",
        )

    # should you verify it at this point, you'll get the same exception
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractSpent):
        w.atomicswap.verify("dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486")

    c.wallets.delete()
    c.delete()
Exemplo n.º 10
0
def test():
    """
    to run:

    kosmos 'j.clients.tfchain.test(name="atomicswap_verify_sender")'
    """

    cleanup("test_unittest_client")

    # create a tfchain client for devnet
    c = j.clients.tfchain.new("test_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = TFChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","difficulty":"30203","estimatedactivebs":"2365","height":16639,"maturitytimestamp":1549646167,"target":[0,2,43,120,39,20,204,42,102,32,125,110,53,77,39,71,99,124,13,223,197,154,115,42,126,62,185,120,208,177,21,190],"totalcoins":"0","arbitrarydatatotalsize":4328,"minerpayoutcount":16721,"transactioncount":17262,"coininputcount":633,"coinoutputcount":1225,"blockstakeinputcount":16639,"blockstakeoutputcount":16640,"minerfeecount":622,"arbitrarydatacount":572}'
    explorer_client.hash_add(
        "5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8",
        '{"hashtype":"blockid","block":{"minerpayoutids":["84b378d60cbdd78430b39c8eddf226119b6f28256388557dd15f0b046bf3c3ed"],"transactions":[{"id":"9aec9f849e35f0bdd14c5ea9daed20c8fbfa09f5a6771bb46ce787eb7e2b00a0","height":16639,"parent":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["83aa29b3e77f703526e28fbc0d2bfcf2b66c06b665e11cb5535b9575fd0e8105"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"8485f94209bf3e01ed169244ab2072ebb0d1c5dc589c95b39a3fbab3641b7a7e","timestamp":1549646257,"pobsindexes":{"BlockHeight":16638,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","difficulty":"30203","estimatedactivebs":"2365","height":16639,"maturitytimestamp":1549646167,"target":[0,2,43,120,39,20,204,42,102,32,125,110,53,77,39,71,99,124,13,223,197,154,115,42,126,62,185,120,208,177,21,190],"totalcoins":"0","arbitrarydatatotalsize":4328,"minerpayoutcount":16721,"transactioncount":17262,"coininputcount":633,"coinoutputcount":1225,"blockstakeinputcount":16639,"blockstakeoutputcount":16640,"minerfeecount":622,"arbitrarydatacount":572},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to initiate an atomic swap contract
    w = c.wallets.new(
        "mytestwallet",
        seed=
        "remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )

    # one can verify that its transaction is sent as sender,
    # not super useful, but it does also contain an optional check to know if it is already refundable

    # verification will fail if the contract could not be found
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractNotFound):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890")

    # add the coin output info of the submitted atomic swap contract
    explorer_client.hash_add(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"4a7ac7930379675c82d0462a86e6d6f4018bdb2bdabaf49f4c177b8de19b4e7c","height":16930,"parent":"c25f345403080b8372a38f66608aa5a2287bdc61b82efe5ee6503ce85e8bcd35","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b5081e41797f53233c727c344698400a73f2cdd364e241df915df413d3eeafb425ce9b51de3731bcbf830c399a706f4d24ae7066f947a4a36ae1b25415bcde00"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c","hashedsecret":"4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba","timelock":1549736249}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"],"coinoutputunlockhashes":["02fb27c67c373c2f30611e0b98bf92ed6e6eb0a69b471457b282903945180cd5c5b8068731f767"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )

    # one can verify it all manually
    contract = w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890")
    assert contract.outputid == "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"
    assert contract.amount == "50 TFT"
    assert contract.refund_timestamp == 1549736249
    assert contract.sender == "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"
    assert contract.receiver == "01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c"
    assert contract.secret_hash == "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba"

    # the amount can however be verified automatically
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        amount=50)
    # which will fail if the amount is wrong
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
            amount=42)

    # the secret hash can be verified as well, not so important as the sender,
    # would be more used if one is the receiver, but it is possible none the less.
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        secret_hash=
        "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
    )
    # which will fail if the secret hash is wrong
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
            secret_hash=
            "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdbb",
        )

    # a minimum duration can also be defined, where the duration defines how long it takes until the
    # contract becomes refundable, 0 if already assumed to be refundable
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        min_refund_time="+1d")
    # which will fail if assumed wrong
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
            min_refund_time=0)

    # if one is assumed to be the sender, it can also be verified automatically
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        sender=True)
    # if one assumed its position wrong, it will however fail
    with pytest.raises(j.clients.tfchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
            receiver=True)

    # all can be verified at once of course
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        amount=50,
        secret_hash=
        "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
        min_refund_time="+1d",
        sender=True,
    )

    # once the refund time has been reached, it does become refundable, and min_refund_time=0 should validate correctly
    explorer_client.hash_add(
        "5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8",
        '{"hashtype":"blockid","block":{"minerpayoutids":["84b378d60cbdd78430b39c8eddf226119b6f28256388557dd15f0b046bf3c3ed"],"transactions":[{"id":"9aec9f849e35f0bdd14c5ea9daed20c8fbfa09f5a6771bb46ce787eb7e2b00a0","height":16639,"parent":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["83aa29b3e77f703526e28fbc0d2bfcf2b66c06b665e11cb5535b9575fd0e8105"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"8485f94209bf3e01ed169244ab2072ebb0d1c5dc589c95b39a3fbab3641b7a7e","timestamp":1549791703,"pobsindexes":{"BlockHeight":16638,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","difficulty":"30203","estimatedactivebs":"2365","height":16639,"maturitytimestamp":1549646167,"target":[0,2,43,120,39,20,204,42,102,32,125,110,53,77,39,71,99,124,13,223,197,154,115,42,126,62,185,120,208,177,21,190],"totalcoins":"0","arbitrarydatatotalsize":4328,"minerpayoutcount":16721,"transactioncount":17262,"coininputcount":633,"coinoutputcount":1225,"blockstakeinputcount":16639,"blockstakeoutputcount":16640,"minerfeecount":622,"arbitrarydatacount":572},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    # we should be able to refund at this point
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        amount=50,
        secret_hash=
        "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
        min_refund_time=0,
        sender=True,
    )

    c.wallets.delete()
    c.delete()