1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-13 19:18:56 +00:00

rework txapi class to use local cache, add txcache fixtures

This commit is contained in:
Pavol Rusnak 2016-11-08 15:07:58 +01:00
parent 2257117278
commit 046ced3f81
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
14 changed files with 115 additions and 291 deletions

View File

@ -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

View File

@ -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"))),

View File

@ -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"))),

View File

@ -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):

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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 '<string>' or '<stdin>' 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

View File

@ -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)