From 046ced3f81e083615e8bdbb696b61ab1875cd054 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Tue, 8 Nov 2016 15:07:58 +0100 Subject: [PATCH] rework txapi class to use local cache, add txcache fixtures --- tests/common.py | 4 +- tests/test_msg_signtx.py | 8 +- tests/test_msg_signtx_zcash.py | 4 +- tests/test_op_return.py | 1 - ...66fb251ef753e0912223a83d1dcb009111d28265e5 | 1 + ...6e53dffc526d68c0eb5c00547e323b2c32382dfba3 | 1 + ...88d23087071103e5bf855f4c1c44e5c8d9d82ca46e | 1 + ...613fbc4bcb37df6cd49b4c96143e99580a472f79fb | 1 + ...b013e12f74159e69574ffea21581dad115572e031c | 1 + ...e4bbf2d7382021b871bd8867ef8fa525ef50864882 | 1 + ...56ef3fe34128dbde30daa9c0639a898f9977299d54 | 1 + ...631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236 | 1 + trezorlib/filecache.py | 187 ----------------- trezorlib/tx_api.py | 194 +++++++++--------- 14 files changed, 115 insertions(+), 291 deletions(-) create mode 100644 tests/txcache/insight_bitcoin_tx_39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5 create mode 100644 tests/txcache/insight_bitcoin_tx_54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3 create mode 100644 tests/txcache/insight_bitcoin_tx_58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e create mode 100644 tests/txcache/insight_bitcoin_tx_c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb create mode 100644 tests/txcache/insight_bitcoin_tx_c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c create mode 100644 tests/txcache/insight_bitcoin_tx_d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 create mode 100644 tests/txcache/insight_testnet_tx_6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54 create mode 100644 tests/txcache/insight_testnet_tx_d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236 delete mode 100644 trezorlib/filecache.py diff --git a/tests/common.py b/tests/common.py index 16dac1475..29190dbe3 100644 --- a/tests/common.py +++ b/tests/common.py @@ -2,7 +2,7 @@ from __future__ import print_function import unittest from trezorlib.client import TrezorDebugClient -from trezorlib.tx_api import TXAPIBitcoin +from trezorlib.tx_api import TxApiBitcoin import config class TrezorTest(unittest.TestCase): @@ -11,7 +11,7 @@ class TrezorTest(unittest.TestCase): self.transport = config.TRANSPORT(*config.TRANSPORT_ARGS, **config.TRANSPORT_KWARGS) self.client = TrezorDebugClient(self.transport) self.client.set_debuglink(self.debug_transport) - self.client.set_tx_api(TXAPIBitcoin()) + self.client.set_tx_api(TxApiBitcoin) # self.client.set_buttonwait(3) # 1 2 3 4 5 6 7 8 9 10 11 12 diff --git a/tests/test_msg_signtx.py b/tests/test_msg_signtx.py index 16918f9c0..54f31cae4 100644 --- a/tests/test_msg_signtx.py +++ b/tests/test_msg_signtx.py @@ -5,7 +5,7 @@ import binascii import trezorlib.messages_pb2 as proto import trezorlib.types_pb2 as proto_types from trezorlib.client import CallException -from trezorlib.tx_api import TXAPITestnet +from trezorlib.tx_api import TxApiTestnet class TestMsgSigntx(common.TrezorTest): def test_one_one_fee(self): @@ -68,7 +68,7 @@ class TestMsgSigntx(common.TrezorTest): ) with self.client: - self.client.set_tx_api(TXAPITestnet()) + self.client.set_tx_api(TxApiTestnet) self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), @@ -113,7 +113,7 @@ class TestMsgSigntx(common.TrezorTest): ) with self.client: - self.client.set_tx_api(TXAPITestnet()) + self.client.set_tx_api(TxApiTestnet) self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), @@ -574,7 +574,7 @@ class TestMsgSigntx(common.TrezorTest): ) with self.client: - self.client.set_tx_api(TXAPITestnet()) + self.client.set_tx_api(TxApiTestnet) self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236"))), diff --git a/tests/test_msg_signtx_zcash.py b/tests/test_msg_signtx_zcash.py index 610a95666..6987fac62 100644 --- a/tests/test_msg_signtx_zcash.py +++ b/tests/test_msg_signtx_zcash.py @@ -5,7 +5,7 @@ import binascii import trezorlib.messages_pb2 as proto import trezorlib.types_pb2 as proto_types from trezorlib.client import CallException -from trezorlib.tx_api import TXAPIZcashTestnet +from trezorlib.tx_api import TxApiZcashTestnet class TestMsgSigntx(common.TrezorTest): @@ -27,7 +27,7 @@ class TestMsgSigntx(common.TrezorTest): ) with self.client: - self.client.set_tx_api(TXAPIZcashTestnet()) + self.client.set_tx_api(TxApiZcashTestnet) self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"))), diff --git a/tests/test_op_return.py b/tests/test_op_return.py index ce45a81b7..4961aaec8 100644 --- a/tests/test_op_return.py +++ b/tests/test_op_return.py @@ -6,7 +6,6 @@ import itertools import trezorlib.messages_pb2 as proto import trezorlib.types_pb2 as proto_types from trezorlib.client import CallException -from trezorlib.tx_api import TXAPITestnet class TestOpReturn(common.TrezorTest): diff --git a/tests/txcache/insight_bitcoin_tx_39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5 b/tests/txcache/insight_bitcoin_tx_39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5 new file mode 100644 index 000000000..6ffaa5314 --- /dev/null +++ b/tests/txcache/insight_bitcoin_tx_39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5 @@ -0,0 +1 @@ +{"valueOut": 3.00986058, "vout": [{"spentIndex": 30, "spentHeight": 288729, "value": "2.98446058", "n": 0, "spentTxId": "6839c71b7d192a698b5388e9ea921805279cbc9f85bae1019d2f4fe7b326979a", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a9149ef561f8f6fe602cba796137f2d56d7e8a0a4c8488ac", "addresses": ["1FVVioK1iE9X6cBZtarVj6e5vjMATc8izW"], "asm": "OP_DUP OP_HASH160 9ef561f8f6fe602cba796137f2d56d7e8a0a4c84 OP_EQUALVERIFY OP_CHECKSIG"}}, {"spentIndex": 1, "spentHeight": 284875, "value": "0.02540000", "n": 1, "spentTxId": "4a7b7e0403ae5607e473949cfa03f09f2cd8b0f404bf99ce10b7303d86280bf7", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a914812c13d97f9159e54e326b481b8f88a73df8507a88ac", "addresses": ["1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5"], "asm": "OP_DUP OP_HASH160 812c13d97f9159e54e326b481b8f88a73df8507a OP_EQUALVERIFY OP_CHECKSIG"}}], "blockhash": "00000000000000016732dadfc971c98b308d46283f0340c0ad9479fc65a28550", "valueIn": 3.00996058, "fees": 0.0001, "vin": [{"addr": "1M2Qq4P8bjXrbvEYicwWNeQ3TkikCiMKdz", "vout": 79, "sequence": 4294967295, "doubleSpentTxID": null, "value": 3.00996058, "n": 0, "valueSat": 300996058, "txid": "5794e0110bd0c664ebad6098ea3449a08be6fb2549c65b49554edadb37a15ecb", "scriptSig": {"hex": "48304502205f9dc47d4f4b545c9b565ba9462e47df50d9c62bb1e9e279532d517650eb085e022100eb4ef1ed295c44adbe19a84b4f477dac407d1ba17eeeb54b64c2176101a09b4001410406a078b4ffd2fe15fe516ce0f1ac68668a614a79f3b5f6d493361a16b0ee4138907f04d85f5a53f7dc1d47f26aa990881b725edc89b911481b92f2d31a250360", "asm": "304502205f9dc47d4f4b545c9b565ba9462e47df50d9c62bb1e9e279532d517650eb085e022100eb4ef1ed295c44adbe19a84b4f477dac407d1ba17eeeb54b64c2176101a09b40[ALL] 0406a078b4ffd2fe15fe516ce0f1ac68668a614a79f3b5f6d493361a16b0ee4138907f04d85f5a53f7dc1d47f26aa990881b725edc89b911481b92f2d31a250360"}}], "txid": "39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5", "blocktime": 1391896241, "version": 1, "confirmations": 153064, "time": 1391896241, "blockheight": 284866, "locktime": 0, "size": 258} \ No newline at end of file diff --git a/tests/txcache/insight_bitcoin_tx_54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3 b/tests/txcache/insight_bitcoin_tx_54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3 new file mode 100644 index 000000000..4847ae61a --- /dev/null +++ b/tests/txcache/insight_bitcoin_tx_54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3 @@ -0,0 +1 @@ +{"valueOut": 1.05472082, "vout": [{"spentIndex": 0, "spentHeight": 293754, "value": "1.05072082", "n": 0, "spentTxId": "b664fca5b225d3fc01d6f562488136adc4d563e52fdc639db8b6f50afaa5d736", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a914486088128a2137cd53b81f3efe4c3d612b7a777f88ac", "addresses": ["17bhHwY6nhomv4RxwkEGRZ6VutKjoGMDSS"], "asm": "OP_DUP OP_HASH160 486088128a2137cd53b81f3efe4c3d612b7a777f OP_EQUALVERIFY OP_CHECKSIG"}}, {"spentIndex": 0, "spentHeight": 293786, "value": "0.00400000", "n": 1, "spentTxId": "8cc1f4adf7224ce855cf535a5104594a0004cb3b640d6714fdb00b9128832dd5", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a91424a56db43cf6f2b02e838ea493f95d8d6047423188ac", "addresses": ["14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e"], "asm": "OP_DUP OP_HASH160 24a56db43cf6f2b02e838ea493f95d8d60474231 OP_EQUALVERIFY OP_CHECKSIG"}}], "blockhash": "000000000000000092268fe69290d4150455aee141bfa0271c6948d18e56dfd0", "valueIn": 1.05482082, "fees": 0.0001, "vin": [{"addr": "13vPZWiYyXxX2MWZrzy68juyYLm9hifCbd", "vout": 30, "sequence": 4294967295, "doubleSpentTxID": null, "value": 1.05482082, "n": 0, "valueSat": 105482082, "txid": "86cb076f72e440773b2cd0e52993bb03f68defb9f84ec1c1cbdae0dff2c51ccb", "scriptSig": {"hex": "493046022100e6a32e0a6211c6ce2dbd4e04a2398330757d421988d4db864b3bb634ba1c252b02210082abc8a64a00c0858f211b0a8f155d8dfecbac5af5451c63c32a72ed9942902b0141042b8d0a66cb3c71792b8b9d27ba9a2639261465d75f7aec799250da8174b8e75481b247d5152c578c558530d60dd9ecd6924bab4c1267f8fe4c10401eb67b0d37", "asm": "3046022100e6a32e0a6211c6ce2dbd4e04a2398330757d421988d4db864b3bb634ba1c252b02210082abc8a64a00c0858f211b0a8f155d8dfecbac5af5451c63c32a72ed9942902b[ALL] 042b8d0a66cb3c71792b8b9d27ba9a2639261465d75f7aec799250da8174b8e75481b247d5152c578c558530d60dd9ecd6924bab4c1267f8fe4c10401eb67b0d37"}}], "txid": "54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3", "blocktime": 1396310563, "version": 1, "confirmations": 144448, "time": 1396310563, "blockheight": 293483, "locktime": 0, "size": 259} \ No newline at end of file diff --git a/tests/txcache/insight_bitcoin_tx_58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e b/tests/txcache/insight_bitcoin_tx_58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e new file mode 100644 index 000000000..c2cdc04bd --- /dev/null +++ b/tests/txcache/insight_bitcoin_tx_58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e @@ -0,0 +1 @@ +{"valueOut": 0.46995, "vout": [{"spentIndex": 28, "spentHeight": 288729, "value": "0.46885000", "n": 0, "spentTxId": "6839c71b7d192a698b5388e9ea921805279cbc9f85bae1019d2f4fe7b326979a", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a91459581dcaf8ed947343b569f1fa2d855d0fc6d9bf88ac", "addresses": ["199QhWMtYE79AG3547QXmZpa8NtLDgme16"], "asm": "OP_DUP OP_HASH160 59581dcaf8ed947343b569f1fa2d855d0fc6d9bf OP_EQUALVERIFY OP_CHECKSIG"}}, {"spentIndex": 1, "spentHeight": 284865, "value": "0.00110000", "n": 1, "spentTxId": "c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a9142db345c36563122e2fd0f5485fb7ea9bbf7cb5a288ac", "addresses": ["15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG"], "asm": "OP_DUP OP_HASH160 2db345c36563122e2fd0f5485fb7ea9bbf7cb5a2 OP_EQUALVERIFY OP_CHECKSIG"}}], "blockhash": "00000000000000009ea3d77854af7c8cc0f28506dc8379c89830e445d951f4bf", "valueIn": 0.47005, "fees": 0.0001, "vin": [{"addr": "19UC6mkNJyqy3iKwQQyNm4TVZMkXyi5TSt", "vout": 0, "sequence": 4294967295, "doubleSpentTxID": null, "value": 0.47005, "n": 0, "valueSat": 47005000, "txid": "8d0650287b230a2708f7cab2099f6062cbfd20f4c298c68f6c6cbc962fb3e044", "scriptSig": {"hex": "4730440220428e0c87d311149c6ea86efcaafbd4830cf2eb14e09ac856ae088bc4b797204902201b9402951a06303336a75d6b77d0c889a53ae7c710642be8b5999583e728d3de014104443b1eb4926c3c90332294eba561962ad28d04eb19514002e20c8ee8d93be576ef9799af500a20864c62a74a0b085b237f71ecb451dd9559cb72ba33d326a912", "asm": "30440220428e0c87d311149c6ea86efcaafbd4830cf2eb14e09ac856ae088bc4b797204902201b9402951a06303336a75d6b77d0c889a53ae7c710642be8b5999583e728d3de[ALL] 04443b1eb4926c3c90332294eba561962ad28d04eb19514002e20c8ee8d93be576ef9799af500a20864c62a74a0b085b237f71ecb451dd9559cb72ba33d326a912"}}], "txid": "58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e", "blocktime": 1391892746, "version": 1, "confirmations": 153072, "time": 1391892746, "blockheight": 284858, "locktime": 0, "size": 257} \ No newline at end of file diff --git a/tests/txcache/insight_bitcoin_tx_c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb b/tests/txcache/insight_bitcoin_tx_c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb new file mode 100644 index 000000000..c9c36f899 --- /dev/null +++ b/tests/txcache/insight_bitcoin_tx_c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb @@ -0,0 +1 @@ +{"valueOut": 0.002, "vout": [{"spentIndex": 29, "spentHeight": 288729, "value": "0.00100000", "n": 0, "spentTxId": "6839c71b7d192a698b5388e9ea921805279cbc9f85bae1019d2f4fe7b326979a", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a9142f4490d5263906e4887ca2996b9e207af3e7824088ac", "addresses": ["15Jvu3nZNP7u2ipw2533Q9VVgEu2Lu9F2B"], "asm": "OP_DUP OP_HASH160 2f4490d5263906e4887ca2996b9e207af3e78240 OP_EQUALVERIFY OP_CHECKSIG"}}, {"spentIndex": 0, "spentHeight": 284875, "value": "0.00100000", "n": 1, "spentTxId": "4a7b7e0403ae5607e473949cfa03f09f2cd8b0f404bf99ce10b7303d86280bf7", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a914812c13d97f9159e54e326b481b8f88a73df8507a88ac", "addresses": ["1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5"], "asm": "OP_DUP OP_HASH160 812c13d97f9159e54e326b481b8f88a73df8507a OP_EQUALVERIFY OP_CHECKSIG"}}], "blockhash": "0000000000000000ad1b23698d40235f4bc71eb1ab6fa5891ade1fd89b0beb7e", "valueIn": 0.0021, "fees": 0.0001, "vin": [{"addr": "1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb", "vout": 1, "sequence": 4294967295, "doubleSpentTxID": null, "value": 0.001, "n": 0, "valueSat": 100000, "txid": "c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c", "scriptSig": {"hex": "493046022100f773c403b2f85a5c1d6c9c4ad69c43de66930fff4b1bc818eb257af98305546a022100bbc421b41bc60d89593186c99b4b9ca6ac8dce1fe62342d38a8e14e0cbf279dc01210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6", "asm": "3046022100f773c403b2f85a5c1d6c9c4ad69c43de66930fff4b1bc818eb257af98305546a022100bbc421b41bc60d89593186c99b4b9ca6ac8dce1fe62342d38a8e14e0cbf279dc[ALL] 0338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6"}}, {"addr": "15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG", "vout": 1, "sequence": 4294967295, "doubleSpentTxID": null, "value": 0.0011, "n": 1, "valueSat": 110000, "txid": "58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e", "scriptSig": {"hex": "49304602210090cff1c1911e771605358a8cddd5ae94c7b60cc96e50275908d9bf9d6367c79f022100d4058d1efd9f5eb9542a62fad91ecca30db32a326f311f51dc2b1a71cbb578670121038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3", "asm": "304602210090cff1c1911e771605358a8cddd5ae94c7b60cc96e50275908d9bf9d6367c79f022100d4058d1efd9f5eb9542a62fad91ecca30db32a326f311f51dc2b1a71cbb57867[ALL] 038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3"}}], "txid": "c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb", "blocktime": 1391895477, "version": 1, "confirmations": 153065, "time": 1391895477, "blockheight": 284865, "locktime": 0, "size": 376} \ No newline at end of file diff --git a/tests/txcache/insight_bitcoin_tx_c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c b/tests/txcache/insight_bitcoin_tx_c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c new file mode 100644 index 000000000..9ab838b05 --- /dev/null +++ b/tests/txcache/insight_bitcoin_tx_c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c @@ -0,0 +1 @@ +{"valueOut": 3.33165406, "vout": [{"spentIndex": 27, "spentHeight": 288729, "value": "3.33065406", "n": 0, "spentTxId": "6839c71b7d192a698b5388e9ea921805279cbc9f85bae1019d2f4fe7b326979a", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a91459581dcaf8ed947343b569f1fa2d855d0fc6d9bf88ac", "addresses": ["199QhWMtYE79AG3547QXmZpa8NtLDgme16"], "asm": "OP_DUP OP_HASH160 59581dcaf8ed947343b569f1fa2d855d0fc6d9bf OP_EQUALVERIFY OP_CHECKSIG"}}, {"spentIndex": 0, "spentHeight": 284865, "value": "0.00100000", "n": 1, "spentTxId": "c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a9140223b1a09138753c9cb0baf95a0a62c82711567a88ac", "addresses": ["1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb"], "asm": "OP_DUP OP_HASH160 0223b1a09138753c9cb0baf95a0a62c82711567a OP_EQUALVERIFY OP_CHECKSIG"}}], "blockhash": "0000000000000000371eecb3a4a9e2347cd8971b9a50a63ef2a7276c3a5e2ca7", "valueIn": 3.33175406, "fees": 0.0001, "vin": [{"addr": "1FSAF2vZ47XnyiF7CuvTErEvtKaGNvwW7w", "vout": 42, "sequence": 4294967295, "doubleSpentTxID": null, "value": 3.33175406, "n": 0, "valueSat": 333175406, "txid": "c810877b6e207671bd28c48cc2b5b4f1d23214c050279a24a760730acc27818d", "scriptSig": {"hex": "473044022046004772823a664287a9496982d232bae3336f558528ae9ca9fe6c904f61751a0220371e084a83fddbf82023d7017f15128cb4c9874e3f27faaa73ee6df1e303d1b7014104a1e881adf937bfe915e9ce6badd3a46e1d7719e23c71291fbdcce15399148e41f16b76a291414b05bffc8705d90034ca6a080cc75c42e4450dc8ffbcaf0a4c9d", "asm": "3044022046004772823a664287a9496982d232bae3336f558528ae9ca9fe6c904f61751a0220371e084a83fddbf82023d7017f15128cb4c9874e3f27faaa73ee6df1e303d1b7[ALL] 04a1e881adf937bfe915e9ce6badd3a46e1d7719e23c71291fbdcce15399148e41f16b76a291414b05bffc8705d90034ca6a080cc75c42e4450dc8ffbcaf0a4c9d"}}], "txid": "c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c", "blocktime": 1391892541, "version": 1, "confirmations": 153073, "time": 1391892541, "blockheight": 284857, "locktime": 0, "size": 257} \ No newline at end of file diff --git a/tests/txcache/insight_bitcoin_tx_d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 b/tests/txcache/insight_bitcoin_tx_d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 new file mode 100644 index 000000000..0b1099dfc --- /dev/null +++ b/tests/txcache/insight_bitcoin_tx_d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 @@ -0,0 +1 @@ +{"valueOut": 0.0039, "vout": [{"spentIndex": 0, "spentHeight": 280227, "value": "0.00390000", "n": 0, "spentTxId": "fd79435246dee76b2f159d2db08032d666c95adc544de64c8c49f474df4a7fee", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a91424a56db43cf6f2b02e838ea493f95d8d6047423188ac", "addresses": ["14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e"], "asm": "OP_DUP OP_HASH160 24a56db43cf6f2b02e838ea493f95d8d60474231 OP_EQUALVERIFY OP_CHECKSIG"}}], "blockhash": "00000000000000011dec345ceae0765c98c72bdcb7cdd83e749ad37bbc3104cc", "valueIn": 0.004, "fees": 0.0001, "vin": [{"addr": "19qyPUSAXJ8cHw6TxZ6FYQFZdLMdJA7A2t", "vout": 1, "sequence": 4294967295, "doubleSpentTxID": null, "value": 0.002, "n": 0, "valueSat": 200000, "txid": "c16a03f1cf8f99f6b5297ab614586cacec784c2d259af245909dedb0e39eddcf", "scriptSig": {"hex": "483045022072ba61305fe7cb542d142b8f3299a7b10f9ea61f6ffaab5dca8142601869d53c0221009a8027ed79eb3b9bc13577ac2853269323434558528c6b6a7e542be46e7e9a820141047a2d177c0f3626fc68c53610b0270fa6156181f46586c679ba6a88b34c6f4874686390b4d92e5769fbb89c8050b984f4ec0b257a0e5c4ff8bd3b035a51709503", "asm": "3045022072ba61305fe7cb542d142b8f3299a7b10f9ea61f6ffaab5dca8142601869d53c0221009a8027ed79eb3b9bc13577ac2853269323434558528c6b6a7e542be46e7e9a82[ALL] 047a2d177c0f3626fc68c53610b0270fa6156181f46586c679ba6a88b34c6f4874686390b4d92e5769fbb89c8050b984f4ec0b257a0e5c4ff8bd3b035a51709503"}}, {"addr": "1B4scQC2N8NZ5cYVbVwDrao1aSnwNAAvbb", "vout": 1, "sequence": 4294967295, "doubleSpentTxID": null, "value": 0.002, "n": 1, "valueSat": 200000, "txid": "1ae39a2f8d59670c8fc61179148a8e61e039d0d9e8ab08610cb69b4a19453eaf", "scriptSig": {"hex": "48304502200fd63adc8f6cb34359dc6cca9e5458d7ea50376cbd0a74514880735e6d1b8a4c0221008b6ead7fe5fbdab7319d6dfede3a0bc8e2a7c5b5a9301636d1de4aa31a3ee9b101410486ad608470d796236b003635718dfc07c0cac0cfc3bfc3079e4f491b0426f0676e6643a39198e8e7bdaffb94f4b49ea21baa107ec2e237368872836073668214", "asm": "304502200fd63adc8f6cb34359dc6cca9e5458d7ea50376cbd0a74514880735e6d1b8a4c0221008b6ead7fe5fbdab7319d6dfede3a0bc8e2a7c5b5a9301636d1de4aa31a3ee9b1[ALL] 0486ad608470d796236b003635718dfc07c0cac0cfc3bfc3079e4f491b0426f0676e6643a39198e8e7bdaffb94f4b49ea21baa107ec2e237368872836073668214"}}], "txid": "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882", "blocktime": 1389542996, "version": 1, "confirmations": 157821, "time": 1389542996, "blockheight": 280109, "locktime": 0, "size": 404} \ No newline at end of file diff --git a/tests/txcache/insight_testnet_tx_6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54 b/tests/txcache/insight_testnet_tx_6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54 new file mode 100644 index 000000000..ffc7feeca --- /dev/null +++ b/tests/txcache/insight_testnet_tx_6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54 @@ -0,0 +1 @@ +{"valueOut": 14.03850989, "vout": [{"spentIndex": 0, "spentHeight": 203911, "value": "4.03850989", "n": 0, "spentTxId": "5170fe1f25a05e1c9e125c27cd09e11f7c79c41409bc5b68f0e6f056af2d56b0", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a914f5a05c2664b40d3116b1c5086c9ba38ed15b742e88ac", "addresses": ["n3uhx4JymCrWKX3e9i59YdJivMghF1bKZ4"], "asm": "OP_DUP OP_HASH160 f5a05c2664b40d3116b1c5086c9ba38ed15b742e OP_EQUALVERIFY OP_CHECKSIG"}}, {"spentIndex": null, "spentHeight": null, "value": "10.00000000", "n": 1, "spentTxId": null, "scriptPubKey": {"type": "pubkeyhash", "hex": "76a91424a56db43cf6f2b02e838ea493f95d8d6047423188ac", "addresses": ["mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL"], "asm": "OP_DUP OP_HASH160 24a56db43cf6f2b02e838ea493f95d8d60474231 OP_EQUALVERIFY OP_CHECKSIG"}}], "blockhash": "000000006656e1d72a211b7f469dd85209ba85c54127957a95591712a63d3848", "valueIn": 14.03850989, "fees": 0, "vin": [{"addr": "mnsfHtywp6AVUzgqu9P4tay6iQYY3WhCpz", "vout": 1, "sequence": 4294967295, "doubleSpentTxID": null, "value": 5.508651, "n": 0, "valueSat": 550865100, "txid": "ee336e79153d51f4f3e45278f1f77ab29fd5bb135dce467282e2aff22cb9c570", "scriptSig": {"hex": "483045022066c418874dbe5628296700382d727ce1734928796068c26271472df09dccf1a20221009dec59d19f9d73db381fcd35c0fff757ad73e54ef59157b0d7c57e6739a092f00121033fef08c603943dc7d25f4ce65771762143b1cd8678343d660a1a76b9d1d3ced7", "asm": "3045022066c418874dbe5628296700382d727ce1734928796068c26271472df09dccf1a20221009dec59d19f9d73db381fcd35c0fff757ad73e54ef59157b0d7c57e6739a092f0[ALL] 033fef08c603943dc7d25f4ce65771762143b1cd8678343d660a1a76b9d1d3ced7"}}, {"addr": "mrDBnbEumaEiHm8pc9pj1rfUCsR4H7N5xh", "vout": 1, "sequence": 4294967295, "doubleSpentTxID": null, "value": 8.52985889, "n": 1, "valueSat": 852985889, "txid": "2fe4d8af2b44faccc10dd5a6578c923491d2d21269a1dfe8c83f492a30fb8f9f", "scriptSig": {"hex": "47304402206fbb8e14be706b8557a2280d2a2a75c0a65c4f7936d90d510f0971c93f41f74402201b79c8c4e4ac4c944913611633c230193558296e70a36269b7fc3a80efa27d120121030cb5be79bdc36a4ff4443dbac43068cc43d638ea06ff2fa1b8dab389e39aefc7", "asm": "304402206fbb8e14be706b8557a2280d2a2a75c0a65c4f7936d90d510f0971c93f41f74402201b79c8c4e4ac4c944913611633c230193558296e70a36269b7fc3a80efa27d12[ALL] 030cb5be79bdc36a4ff4443dbac43068cc43d638ea06ff2fa1b8dab389e39aefc7"}}], "txid": "6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54", "blocktime": 1391901762, "version": 1, "confirmations": 851751, "time": 1391901762, "blockheight": 180573, "locktime": 0, "size": 373} \ No newline at end of file diff --git a/tests/txcache/insight_testnet_tx_d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236 b/tests/txcache/insight_testnet_tx_d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236 new file mode 100644 index 000000000..cbc5389d1 --- /dev/null +++ b/tests/txcache/insight_testnet_tx_d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236 @@ -0,0 +1 @@ +{"valueOut": 25.0027823, "isCoinBase": true, "vout": [{"spentIndex": 0, "spentHeight": 245746, "value": "25.00278230", "n": 0, "spentTxId": "871884776fe6aa078a16b66d82157ab4159257aa2889da9229f4e024ba40d6ee", "scriptPubKey": {"type": "pubkeyhash", "hex": "76a9140223b1a09138753c9cb0baf95a0a62c82711567a88ac", "addresses": ["mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV"], "asm": "OP_DUP OP_HASH160 0223b1a09138753c9cb0baf95a0a62c82711567a OP_EQUALVERIFY OP_CHECKSIG"}}], "blockhash": "000000000001994ec2997c267bc843d5b24032db26e5e1c56bffaf43c786a339", "vin": [{"coinbase": "0352bf03062f503253482f04f919855308f8000001c7000000092f7374726174756d2f", "n": 0, "sequence": 0}], "txid": "d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236", "blocktime": 1401231865, "version": 1, "confirmations": 786738, "time": 1401231865, "blockheight": 245586, "locktime": 0, "size": 120} \ No newline at end of file diff --git a/trezorlib/filecache.py b/trezorlib/filecache.py deleted file mode 100644 index 69625b4ab..000000000 --- a/trezorlib/filecache.py +++ /dev/null @@ -1,187 +0,0 @@ -''' -filecache - -filecache is a decorator which saves the return value of functions even -after the interpreter dies. For example this is useful on functions that download -and parse webpages. All you need to do is specify how long -the return values should be cached (use seconds, like time.sleep). - -USAGE: - - from filecache import filecache - - @filecache(24 * 60 * 60) - def time_consuming_function(args): - # etc - - @filecache(filecache.YEAR) - def another_function(args): - # etc - - -NOTE: All arguments of the decorated function and the return value need to be - picklable for this to work. - -NOTE: The cache isn't automatically cleaned, it is only overwritten. If your - function can receive many different arguments that rarely repeat, your - cache may forever grow. One day I might add a feature that once in every - 100 calls scans the db for outdated stuff and erases. - -NOTE: This is less useful on methods of a class because the instance (self) - is cached, and if the instance isn't the same, the cache isn't used. This - makes sense because class methods are affected by changes in whatever - is attached to self. - -Tested on python 2.7 and 3.1 - -License: BSD, do what you wish with this. Could be awesome to hear if you found -it useful and/or you have suggestions. ubershmekel at gmail - - -A trick to invalidate a single value: - - @filecache.filecache - def somefunc(x, y, z): - return x * y * z - - del somefunc._db[filecache._args_key(somefunc, (1,2,3), {})] - # or just iterate of somefunc._db (it's a shelve, like a dict) to find the right key. - - -''' - - -import collections as _collections -import datetime as _datetime -import functools as _functools -import inspect as _inspect -import os as _os -import pickle as _pickle -import shelve as _shelve -import sys as _sys -import time as _time -import traceback as _traceback -import types -import atexit - -_retval = _collections.namedtuple('_retval', 'timesig data') -_SRC_DIR = _os.path.dirname(_os.path.abspath(__file__)) - -SECOND = 1 -MINUTE = 60 * SECOND -HOUR = 60 * MINUTE -DAY = 24 * HOUR -WEEK = 7 * DAY -MONTH = 30 * DAY -YEAR = 365 * DAY -FOREVER = None - -OPEN_DBS = dict() - -def _get_cache_name(function): - """ - returns a name for the module's cache db. - """ - module_name = _inspect.getfile(function) - module_name = _os.path.abspath(module_name) - cache_name = module_name - - # fix for '' or '' in exec or interpreter usage. - cache_name = cache_name.replace('<', '_lt_') - cache_name = cache_name.replace('>', '_gt_') - - tmpdir = _os.getenv('TMPDIR') or _os.getenv('TEMP') or _os.getenv('TMP') - if tmpdir: - cache_name = tmpdir + '/filecache_' + cache_name.replace(_os.sep, '@') - - cache_name += '.cache' - return cache_name - - -def _log_error(error_str): - try: - error_log_fname = _os.path.join(_SRC_DIR, 'filecache.err.log') - if _os.path.isfile(error_log_fname): - fhand = open(error_log_fname, 'a') - else: - fhand = open(error_log_fname, 'w') - fhand.write('[%s] %s\r\n' % (_datetime.datetime.now().isoformat(), error_str)) - fhand.close() - except Exception: - pass - -def _args_key(function, args, kwargs): - arguments = (args, kwargs) - # Check if you have a valid, cached answer, and return it. - # Sadly this is python version dependant - if _sys.version_info[0] == 2: - arguments_pickle = _pickle.dumps(arguments) - else: - # NOTE: protocol=0 so it's ascii, this is crucial for py3k - # because shelve only works with proper strings. - # Otherwise, we'd get an exception because - # function.__name__ is str but dumps returns bytes. - arguments_pickle = _pickle.dumps(arguments, protocol=0).decode('ascii') - - key = function.__name__ + arguments_pickle - return key - -def filecache(seconds_of_validity=None, fail_silently=False): - ''' - filecache is called and the decorator should be returned. - ''' - def filecache_decorator(function): - @_functools.wraps(function) - def function_with_cache(*args, **kwargs): - try: - key = _args_key(function, args, kwargs) - - if key in function._db: - rv = function._db[key] - if seconds_of_validity is None or _time.time() - rv.timesig < seconds_of_validity: - return rv.data - except Exception: - # in any case of failure, don't let filecache break the program - error_str = _traceback.format_exc() - _log_error(error_str) - if not fail_silently: - raise - - retval = function(*args, **kwargs) - - # store in cache - # NOTE: no need to _db.sync() because there was no mutation - # NOTE: it's importatnt to do _db.sync() because otherwise the cache doesn't survive Ctrl-Break! - try: - function._db[key] = _retval(_time.time(), retval) - function._db.sync() - except Exception: - # in any case of failure, don't let filecache break the program - error_str = _traceback.format_exc() - _log_error(error_str) - if not fail_silently: - raise - - return retval - - # make sure cache is loaded - if not hasattr(function, '_db'): - cache_name = _get_cache_name(function) - if cache_name in OPEN_DBS: - function._db = OPEN_DBS[cache_name] - else: - function._db = _shelve.open(cache_name) - OPEN_DBS[cache_name] = function._db - atexit.register(function._db.close) - - function_with_cache._db = function._db - - return function_with_cache - - if type(seconds_of_validity) == types.FunctionType: - # support for when people use '@filecache.filecache' instead of '@filecache.filecache()' - func = seconds_of_validity - seconds_of_validity = None - return filecache_decorator(func) - - return filecache_decorator diff --git a/trezorlib/tx_api.py b/trezorlib/tx_api.py index 3308e8c13..9068462dc 100644 --- a/trezorlib/tx_api.py +++ b/trezorlib/tx_api.py @@ -1,116 +1,120 @@ import binascii from decimal import Decimal -# from filecache import filecache, DAY import requests +import json from . import types_pb2 as proto_types -def fetch_json(url): - try: - r = requests.get(url, headers={'User-agent': 'Mozilla/5.0'}) - return r.json() - except: - raise Exception('URL error: %s' % url) -def insight_tx(url, rawdata=False, zcash=False): - if not rawdata: - data = fetch_json(url) - else: - data = url +class TxApi(object): - t = proto_types.TransactionType() - t.version = data['version'] - t.lock_time = data['locktime'] + def __init__(self, network, url): + self.network = network + self.url = url - for vin in data['vin']: - i = t.inputs.add() - if 'coinbase' in vin.keys(): - i.prev_hash = b"\0"*32 - i.prev_index = 0xffffffff # signed int -1 - i.script_sig = binascii.unhexlify(vin['coinbase']) - i.sequence = vin['sequence'] + def fetch_json(self, url, resource, resourceid): + cachefile = '%s_%s_%s' % (self.network, resource, resourceid) + try: # looking into cache first + j = json.load(open('txcache/' + cachefile)) + return j + except: + pass + try: + r = requests.get('%s/%s/%s' % (self.url, resource, resourceid), headers={'User-agent': 'Mozilla/5.0'}) + j = r.json() + except: + raise Exception('URL error: %s' % url) + try: # saving into cache + json.dump(j, open('txcache/' + cachefile, 'w')) + except: + pass + return j - else: - i.prev_hash = binascii.unhexlify(vin['txid']) - i.prev_index = vin['vout'] - i.script_sig = binascii.unhexlify(vin['scriptSig']['hex']) - i.sequence = vin['sequence'] + def get_tx(self, txhash): + raise NotImplementedError - for vout in data['vout']: - o = t.bin_outputs.add() - o.amount = int(Decimal(str(vout['value'])) * 100000000) - o.script_pubkey = binascii.unhexlify(vout['scriptPubKey']['hex']) - if zcash: - if t.version == 2: - joinsplit_cnt = len(data['vjoinsplit']) - if joinsplit_cnt == 0: - t.extra_data =b'\x00' +class TxApiInsight(TxApi): + + def __init__(self, network, url, zcash=None): + super(TxApiInsight, self).__init__(network, url) + self.zcash = zcash + + def get_tx(self, txhash): + + data = self.fetch_json(self.url, 'tx', txhash) + + t = proto_types.TransactionType() + t.version = data['version'] + t.lock_time = data['locktime'] + + for vin in data['vin']: + i = t.inputs.add() + if 'coinbase' in vin.keys(): + i.prev_hash = b"\0"*32 + i.prev_index = 0xffffffff # signed int -1 + i.script_sig = binascii.unhexlify(vin['coinbase']) + i.sequence = vin['sequence'] + else: - extra_data_len = 1 + joinsplit_cnt * 1802 + 32 + 64 # we assume cnt < 253, so we can treat varIntLen(cnt) as 1 - raw = fetch_json(url.replace('/tx/', '/rawtx/')) - raw = binascii.unhexlify(raw['rawtx']) - t.extra_data = raw[-extra_data_len:] + i.prev_hash = binascii.unhexlify(vin['txid']) + i.prev_index = vin['vout'] + i.script_sig = binascii.unhexlify(vin['scriptSig']['hex']) + i.sequence = vin['sequence'] - return t + for vout in data['vout']: + o = t.bin_outputs.add() + o.amount = int(Decimal(str(vout['value'])) * 100000000) + o.script_pubkey = binascii.unhexlify(vout['scriptPubKey']['hex']) -def smartbit_tx(url, rawdata=False): - if not rawdata: - data = fetch_json(url) - else: - data = url + if self.zcash: + if t.version == 2: + joinsplit_cnt = len(data['vjoinsplit']) + if joinsplit_cnt == 0: + t.extra_data =b'\x00' + else: + extra_data_len = 1 + joinsplit_cnt * 1802 + 32 + 64 # we assume cnt < 253, so we can treat varIntLen(cnt) as 1 + raw = fetch_json(self.url, 'rawtx', txhash) + raw = binascii.unhexlify(raw['rawtx']) + t.extra_data = raw[-extra_data_len:] - data = data['transaction'] + return t - t = proto_types.TransactionType() - t.version = int(data['version']) - t.lock_time = data['locktime'] - for vin in data['inputs']: - i = t.inputs.add() - if 'coinbase' in vin.keys(): - i.prev_hash = b"\0"*32 - i.prev_index = 0xffffffff # signed int -1 - i.script_sig = binascii.unhexlify(vin['coinbase']) - i.sequence = vin['sequence'] +class TxApiSmartbit(TxApi): - else: - i.prev_hash = binascii.unhexlify(vin['txid']) - i.prev_index = vin['vout'] - i.script_sig = binascii.unhexlify(vin['script_sig']['hex']) - i.sequence = vin['sequence'] - - for vout in data['outputs']: - o = t.bin_outputs.add() - o.amount = int(Decimal(vout['value']) * 100000000) - o.script_pubkey = binascii.unhexlify(vout['script_pub_key']['hex']) - - return t - -class TXAPIBitcoin(object): - - # @filecache(DAY) def get_tx(self, txhash): - url = 'https://insight.bitpay.com/api/tx/%s' % txhash.decode('ascii') - return insight_tx(url) + + data = self.fetch_json(self.url, 'tx', txhash) + + data = data['transaction'] + + t = proto_types.TransactionType() + t.version = int(data['version']) + t.lock_time = data['locktime'] + + for vin in data['inputs']: + i = t.inputs.add() + if 'coinbase' in vin.keys(): + i.prev_hash = b"\0"*32 + i.prev_index = 0xffffffff # signed int -1 + i.script_sig = binascii.unhexlify(vin['coinbase']) + i.sequence = vin['sequence'] + + else: + i.prev_hash = binascii.unhexlify(vin['txid']) + i.prev_index = vin['vout'] + i.script_sig = binascii.unhexlify(vin['script_sig']['hex']) + i.sequence = vin['sequence'] + + for vout in data['outputs']: + o = t.bin_outputs.add() + o.amount = int(Decimal(vout['value']) * 100000000) + o.script_pubkey = binascii.unhexlify(vout['script_pub_key']['hex']) + + return t -class TXAPITestnet(object): - - # @filecache(DAY) - def get_tx(self, txhash): - url = 'https://test-insight.bitpay.com/api/tx/%s' % txhash.decode('ascii') - return insight_tx(url) - -class TXAPISegnet(object): - - # @filecache(DAY) - def get_tx(self, txhash): - url = 'https://segnet-api.smartbit.com.au/v1/blockchain/tx/%s' % txhash.decode('ascii') - return smartbit_tx(url) - -class TXAPIZcashTestnet(object): - - # @filecache(DAY) - def get_tx(self, txhash): - url = 'https://explorer.testnet.z.cash/api/tx/%s' % txhash.decode('ascii') - return insight_tx(url, zcash=True) +TxApiBitcoin = TxApiInsight(network='insight_bitcoin', url='https://insight.bitpay.com/api/') +TxApiTestnet = TxApiInsight(network='insight_testnet', url='https://test-insight.bitpay.com/api/') +TxApiSegnet = TxApiSmartbit(network='smartbit_segnet', url='https://segnet-api.smartbit.com.au/v1/blockchain/') +TxApiZcashTestnet = TxApiInsight(network='insight_zcashtestnet', url='https://explorer.testnet.z.cash/api/', zcash=True)