1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-06-27 18:32:34 +00:00

style: use flake8

This commit is contained in:
Pavol Rusnak 2017-06-23 21:31:42 +02:00
parent 71996c1e43
commit 33f274d145
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
62 changed files with 1200 additions and 881 deletions

16
.flake8 Normal file
View File

@ -0,0 +1,16 @@
[flake8]
exclude =
.tox/,
build/,
dist/,
tools/signtest.py,
trezorlib/*_pb2.py
ignore =
# F821 undefined name 'unicode',
F821,
# F401: module imported but unused
F401,
# E402: module level import not at top of file
E402,
# E501: line too long
E501

View File

@ -25,9 +25,11 @@ install:
- pip install "pip>=7.0" wheel - pip install "pip>=7.0" wheel
- pip install "setuptools>=19.0" - pip install "setuptools>=19.0"
- pip install tox-travis - pip install tox-travis
- pip install flake8
script: script:
- python setup.py install - python setup.py install
- flake8
- tox - tox
notifications: notifications:

View File

@ -39,7 +39,7 @@ setup(
'trezorlib.tx_api', 'trezorlib.tx_api',
'trezorlib.types_pb2', 'trezorlib.types_pb2',
], ],
scripts = ['trezorctl'], scripts=['trezorctl'],
install_requires=install_requires, install_requires=install_requires,
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,

View File

@ -45,7 +45,8 @@ except Exception as e:
def pipe_exists(path): def pipe_exists(path):
import os, stat import os
import stat
try: try:
return stat.S_ISFIFO(os.stat(path).st_mode) return stat.S_ISFIFO(os.stat(path).st_mode)
except: except:

View File

@ -21,6 +21,7 @@ import common
from trezorlib import messages_pb2 as messages from trezorlib import messages_pb2 as messages
class TestBasic(common.TrezorTest): class TestBasic(common.TrezorTest):
def test_features(self): def test_features(self):
@ -50,5 +51,6 @@ class TestBasic(common.TrezorTest):
# Device ID must be fresh after every reset # Device ID must be fresh after every reset
self.assertNotEqual(id1, id2) self.assertNotEqual(id1, id2)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -21,7 +21,7 @@ from __future__ import print_function
import unittest import unittest
import common import common
import time import time
from trezorlib import tools
class TestBip32Speed(common.TrezorTest): class TestBip32Speed(common.TrezorTest):
@ -70,5 +70,6 @@ class TestBip32Speed(common.TrezorTest):
# Cached time expected to be at least 2x faster # Cached time expected to be at least 2x faster
self.assertLessEqual(cache_time, nocache_time / 2.) self.assertLessEqual(cache_time, nocache_time / 2.)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -16,14 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>. # along with this library. If not, see <http://www.gnu.org/licenses/>.
import time
import unittest import unittest
import common import common
import binascii
from trezorlib import messages_pb2 as proto from trezorlib import messages_pb2 as proto
from trezorlib import types_pb2 as types
from trezorlib.client import PinException
class TestDebugLink(common.TrezorTest): class TestDebugLink(common.TrezorTest):
@ -56,5 +53,6 @@ class TestDebugLink(common.TrezorTest):
resp = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded)) resp = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
self.assertIsInstance(resp, proto.Success) self.assertIsInstance(resp, proto.Success)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>. # along with this library. If not, see <http://www.gnu.org/licenses/>.
import time
import unittest import unittest
import common import common
from trezorlib import messages_pb2 as proto from trezorlib import messages_pb2 as proto
class TestMsgApplysettings(common.TrezorTest): class TestMsgApplysettings(common.TrezorTest):
def test_apply_settings(self): def test_apply_settings(self):
@ -92,5 +92,6 @@ class TestMsgApplysettings(common.TrezorTest):
proto.Features()]) proto.Features()])
self.client.apply_settings(homescreen=img) self.client.apply_settings(homescreen=img)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -16,12 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>. # along with this library. If not, see <http://www.gnu.org/licenses/>.
import time
import unittest import unittest
import common import common
from trezorlib import messages_pb2 as proto from trezorlib import messages_pb2 as proto
from trezorlib import types_pb2 as proto_types
class TestMsgChangepin(common.TrezorTest): class TestMsgChangepin(common.TrezorTest):
@ -218,5 +217,6 @@ class TestMsgChangepin(common.TrezorTest):
self.assertTrue(features.pin_protection) self.assertTrue(features.pin_protection)
self.assertEqual(self.client.debug.read_pin()[0], self.pin4) self.assertEqual(self.client.debug.read_pin()[0], self.pin4)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -20,7 +20,6 @@ import unittest
import common import common
import binascii import binascii
from trezorlib.client import CallException
class TestMsgCipherkeyvalue(common.TrezorTest): class TestMsgCipherkeyvalue(common.TrezorTest):
@ -88,5 +87,6 @@ class TestMsgCipherkeyvalue(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
self.assertRaises(Exception, self.client.decrypt_keyvalue, [0, 1, 2], b"test", b"testing") self.assertRaises(Exception, self.client.decrypt_keyvalue, [0, 1, 2], b"test", b"testing")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -16,13 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>. # along with this library. If not, see <http://www.gnu.org/licenses/>.
import time
import unittest import unittest
import common import common
from trezorlib import messages_pb2 as proto from trezorlib import messages_pb2 as proto
from trezorlib import types_pb2 as proto_types from trezorlib import types_pb2 as proto_types
class TestMsgClearsession(common.TrezorTest): class TestMsgClearsession(common.TrezorTest):
def test_clearsession(self): def test_clearsession(self):
@ -53,5 +53,6 @@ class TestMsgClearsession(common.TrezorTest):
res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True) res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
self.assertEqual(res, 'random data') self.assertEqual(res, 'random data')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -17,28 +17,28 @@
# along with this library. If not, see <http://www.gnu.org/licenses/>. # along with this library. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
import common
import binascii import binascii
import common
import trezorlib.messages_pb2 as proto
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
from trezorlib.client import CallException
class TestMsgEstimatetxsize(common.TrezorTest): class TestMsgEstimatetxsize(common.TrezorTest):
def test_estimate_size(self): def test_estimate_size(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=390000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), # amount=390000,
prev_index=0, prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'),
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
amount=390000 - 10000,
script_type=proto_types.PAYTOADDRESS,
)
out1 = proto_types.TxOutputType(
address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
amount=390000 - 10000,
script_type=proto_types.PAYTOADDRESS,
)
est_size = self.client.estimate_tx_size('Bitcoin', [inp1, ], [out1, ]) est_size = self.client.estimate_tx_size('Bitcoin', [inp1, ], [out1, ])
self.assertEqual(est_size, 194) self.assertEqual(est_size, 194)
@ -48,5 +48,6 @@ class TestMsgEstimatetxsize(common.TrezorTest):
self.assertGreaterEqual(est_size, real_size) self.assertGreaterEqual(est_size, real_size)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -18,9 +18,9 @@
import unittest import unittest
import common import common
import trezorlib.ckd_public as bip32
import binascii import binascii
class TestMsgEthereumGetaddress(common.TrezorTest): class TestMsgEthereumGetaddress(common.TrezorTest):
def test_ethereum_getaddress(self): def test_ethereum_getaddress(self):
@ -31,5 +31,6 @@ class TestMsgEthereumGetaddress(common.TrezorTest):
self.assertEqual(binascii.hexlify(self.client.ethereum_get_address([-9, 0])), b'f68804ac9eca9483ab4241d3e4751590d2c05102') self.assertEqual(binascii.hexlify(self.client.ethereum_get_address([-9, 0])), b'f68804ac9eca9483ab4241d3e4751590d2c05102')
self.assertEqual(binascii.hexlify(self.client.ethereum_get_address([0, 9999999])), b'7a6366ecfcaf0d5dcc1539c171696c6cdd1eb8ed') self.assertEqual(binascii.hexlify(self.client.ethereum_get_address([0, 9999999])), b'7a6366ecfcaf0d5dcc1539c171696c6cdd1eb8ed')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -20,10 +20,6 @@ import unittest
import common import common
import binascii import binascii
import trezorlib.messages_pb2 as proto
import trezorlib.types_pb2 as proto_types
from rlp.utils import int_to_big_endian
class TestMsgEthereumSigntx(common.TrezorTest): class TestMsgEthereumSigntx(common.TrezorTest):
@ -94,18 +90,20 @@ class TestMsgEthereumSigntx(common.TrezorTest):
self.assertEqual(binascii.hexlify(sig_r), '070e9dafda4d9e733fa7b6747a75f8a4916459560efb85e3e73cd39f31aa160d') self.assertEqual(binascii.hexlify(sig_r), '070e9dafda4d9e733fa7b6747a75f8a4916459560efb85e3e73cd39f31aa160d')
self.assertEqual(binascii.hexlify(sig_s), '7842db33ef15c27049ed52741db41fe3238a6fa3a6a0888fcfb74d6917600e41') self.assertEqual(binascii.hexlify(sig_s), '7842db33ef15c27049ed52741db41fe3238a6fa3a6a0888fcfb74d6917600e41')
def test_ethereum_signtx_newcontract(self): def test_ethereum_signtx_newcontract(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
# contract creation without data should fail. # contract creation without data should fail.
self.assertRaises(Exception, self.client.ethereum_sign_tx, self.assertRaises(
Exception,
self.client.ethereum_sign_tx,
n=[0, 0], n=[0, 0],
nonce=123456, nonce=123456,
gas_price=20000, gas_price=20000,
gas_limit=20000, gas_limit=20000,
to='', to='',
value=12345678901234567890) value=12345678901234567890
)
sig_v, sig_r, sig_s = self.client.ethereum_sign_tx( sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
n=[0, 0], n=[0, 0],
@ -121,37 +119,49 @@ class TestMsgEthereumSigntx(common.TrezorTest):
def test_ethereum_sanity_checks(self): def test_ethereum_sanity_checks(self):
# gas overflow # gas overflow
self.assertRaises(Exception, self.client.ethereum_sign_tx, self.assertRaises(
Exception,
self.client.ethereum_sign_tx,
n=[0, 0], n=[0, 0],
nonce=123456, nonce=123456,
gas_price=0xffffffffffffffffffffffffffffffff, gas_price=0xffffffffffffffffffffffffffffffff,
gas_limit=0xffffffffffffffffffffffffffffff, gas_limit=0xffffffffffffffffffffffffffffff,
to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'), to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
value=12345678901234567890) value=12345678901234567890
)
# no gas price # no gas price
self.assertRaises(Exception, self.client.ethereum_sign_tx, self.assertRaises(
Exception,
self.client.ethereum_sign_tx,
n=[0, 0], n=[0, 0],
nonce=123456, nonce=123456,
gas_limit=10000, gas_limit=10000,
to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'), to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
value=12345678901234567890) value=12345678901234567890
)
# no gas limit # no gas limit
self.assertRaises(Exception, self.client.ethereum_sign_tx, self.assertRaises(
Exception,
self.client.ethereum_sign_tx,
n=[0, 0], n=[0, 0],
nonce=123456, nonce=123456,
gas_price=10000, gas_price=10000,
to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'), to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
value=12345678901234567890) value=12345678901234567890
)
# no nonce # no nonce
self.assertRaises(Exception, self.client.ethereum_sign_tx, self.assertRaises(
Exception,
self.client.ethereum_sign_tx,
n=[0, 0], n=[0, 0],
gas_price=10000, gas_price=10000,
gas_limit=123456, gas_limit=123456,
to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'), to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
value=12345678901234567890) value=12345678901234567890
)
def test_ethereum_signtx_nodata_eip155(self): def test_ethereum_signtx_nodata_eip155(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
@ -235,5 +245,6 @@ class TestMsgEthereumSigntx(common.TrezorTest):
self.assertEqual(binascii.hexlify(sig_r), 'f7505f709d5999343aea3c384034c62d0514336ff6c6af65582006f708f81503') self.assertEqual(binascii.hexlify(sig_r), 'f7505f709d5999343aea3c384034c62d0514336ff6c6af65582006f708f81503')
self.assertEqual(binascii.hexlify(sig_s), '44e09e29a4b6247000b46ddc94fe391e94deb2b39ad6ac6398e6db5bec095ba9') self.assertEqual(binascii.hexlify(sig_s), '44e09e29a4b6247000b46ddc94fe391e94deb2b39ad6ac6398e6db5bec095ba9')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -20,6 +20,7 @@ import unittest
import common import common
import trezorlib.ckd_public as bip32 import trezorlib.ckd_public as bip32
class TestMsgGetaddress(common.TrezorTest): class TestMsgGetaddress(common.TrezorTest):
def test_btc(self): def test_btc(self):
@ -58,5 +59,6 @@ class TestMsgGetaddress(common.TrezorTest):
self.assertEqual(address2, '1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb') self.assertEqual(address2, '1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb')
self.assertEqual(address1, address2) self.assertEqual(address1, address2)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -2,7 +2,7 @@ import unittest
import common import common
import trezorlib.ckd_public as bip32 import trezorlib.ckd_public as bip32
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
import binascii
class TestMsgGetaddressSegwit(common.TrezorTest): class TestMsgGetaddressSegwit(common.TrezorTest):
@ -23,21 +23,21 @@ class TestMsgGetaddressSegwit(common.TrezorTest):
def test_show_multisig_3(self): def test_show_multisig_3(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
nodes = map(lambda index : self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1,4)) nodes = map(lambda index: self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
multisig1 = proto_types.MultisigRedeemScriptType( multisig1 = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2,0]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 0]), nodes),
signatures=[b'', b'', b''],
m=2,
)
multisig2 = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2,1]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )
# multisig2 = proto_types.MultisigRedeemScriptType(
# pubkeys=map(lambda n: proto_types.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 1]), nodes),
# signatures=[b'', b'', b''],
# m=2,
# )
for i in [1, 2, 3]: for i in [1, 2, 3]:
self.assertEqual(self.client.get_address("Testnet", self.client.expand_path("999'/1'/%d'/2/0" % i), self.assertEqual(self.client.get_address("Testnet", self.client.expand_path("999'/1'/%d'/2/0" % i),
False, multisig1, script_type=proto_types.SPENDP2SHWITNESS), False, multisig1, script_type=proto_types.SPENDP2SHWITNESS),
'2N2MxyAfifVhb3AMagisxaj3uij8bfXqf4Y'); '2N2MxyAfifVhb3AMagisxaj3uij8bfXqf4Y')
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -2,7 +2,7 @@ import unittest
import common import common
import trezorlib.ckd_public as bip32 import trezorlib.ckd_public as bip32
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
import binascii
class TestMsgGetaddressSegwitNative(common.TrezorTest): class TestMsgGetaddressSegwitNative(common.TrezorTest):
@ -23,14 +23,14 @@ class TestMsgGetaddressSegwitNative(common.TrezorTest):
def test_show_multisig_3(self): def test_show_multisig_3(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
nodes = map(lambda index : self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1,4)) nodes = map(lambda index: self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
multisig1 = proto_types.MultisigRedeemScriptType( multisig1 = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2,0]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 0]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )
multisig2 = proto_types.MultisigRedeemScriptType( multisig2 = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2,1]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 1]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )

View File

@ -20,7 +20,7 @@ import unittest
import common import common
import trezorlib.ckd_public as bip32 import trezorlib.ckd_public as bip32
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
import binascii
class TestMsgGetaddress(common.TrezorTest): class TestMsgGetaddress(common.TrezorTest):
@ -35,12 +35,14 @@ class TestMsgGetaddress(common.TrezorTest):
node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy') node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy')
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=node, address_n=[1]), pubkeys=[
proto_types.HDNodePathType(node=node, address_n=[2]), proto_types.HDNodePathType(node=node, address_n=[1]),
proto_types.HDNodePathType(node=node, address_n=[3])], proto_types.HDNodePathType(node=node, address_n=[2]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=node, address_n=[3])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
for i in [1, 2, 3]: for i in [1, 2, 3]:
self.assertEqual(self.client.get_address('Bitcoin', [i], show_display=True, multisig=multisig), '3E7GDtuHqnqPmDgwH59pVC7AvySiSkbibz') self.assertEqual(self.client.get_address('Bitcoin', [i], show_display=True, multisig=multisig), '3E7GDtuHqnqPmDgwH59pVC7AvySiSkbibz')
@ -55,13 +57,14 @@ class TestMsgGetaddress(common.TrezorTest):
pubs.append(proto_types.HDNodePathType(node=node, address_n=[x])) pubs.append(proto_types.HDNodePathType(node=node, address_n=[x]))
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=pubs, pubkeys=pubs,
signatures=[b''] * 15, signatures=[b''] * 15,
m=15, m=15,
) )
for i in range(15): for i in range(15):
self.assertEqual(self.client.get_address('Bitcoin', [i], show_display=True, multisig=multisig), '3QaKF8zobqcqY8aS6nxCD5ZYdiRfL3RCmU') self.assertEqual(self.client.get_address('Bitcoin', [i], show_display=True, multisig=multisig), '3QaKF8zobqcqY8aS6nxCD5ZYdiRfL3RCmU')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -19,12 +19,13 @@
from __future__ import print_function from __future__ import print_function
import unittest import unittest
import common
import math import math
import common
import trezorlib.messages_pb2 as proto import trezorlib.messages_pb2 as proto
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
def entropy(data): def entropy(data):
counts = {} counts = {}
for c in data: for c in data:
@ -38,6 +39,7 @@ def entropy(data):
e -= p * math.log(p, 256) e -= p * math.log(p, 256)
return e return e
class TestMsgGetentropy(common.TrezorTest): class TestMsgGetentropy(common.TrezorTest):
def test_entropy(self): def test_entropy(self):
@ -48,5 +50,6 @@ class TestMsgGetentropy(common.TrezorTest):
self.assertTrue(len(ent) == l) self.assertTrue(len(ent) == l)
print('entropy = ', entropy(ent)) print('entropy = ', entropy(ent))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -20,6 +20,7 @@ import unittest
import common import common
import trezorlib.ckd_public as bip32 import trezorlib.ckd_public as bip32
class TestMsgGetpublic_key(common.TrezorTest): class TestMsgGetpublic_key(common.TrezorTest):
def test_btc(self): def test_btc(self):
@ -42,5 +43,6 @@ class TestMsgGetpublic_key(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
self.assertEqual(bip32.serialize(self.client.get_public_node([111, 42]).node, 0x043587CF), 'tpubDAgixSyai5PWbc8N1mBkHDR5nLgAnHFtY7r4y5EzxqAxrt9YUDpZL3kaRoHVvCfrcwNo31c2isBP2uTHcZxEosuKbyJhCAbrvGoPuLUZ7Mz') self.assertEqual(bip32.serialize(self.client.get_public_node([111, 42]).node, 0x043587CF), 'tpubDAgixSyai5PWbc8N1mBkHDR5nLgAnHFtY7r4y5EzxqAxrt9YUDpZL3kaRoHVvCfrcwNo31c2isBP2uTHcZxEosuKbyJhCAbrvGoPuLUZ7Mz')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -19,7 +19,6 @@
import unittest import unittest
import common import common
from trezorlib import messages_pb2 as messages
class TestDeviceLoad(common.TrezorTest): class TestDeviceLoad(common.TrezorTest):
@ -89,5 +88,6 @@ class TestDeviceLoad(common.TrezorTest):
self.assertEqual(address_nfkd, address_nfkc) self.assertEqual(address_nfkd, address_nfkc)
self.assertEqual(address_nfkd, address_nfd) self.assertEqual(address_nfkd, address_nfd)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -19,7 +19,6 @@
import unittest import unittest
import common import common
from trezorlib import messages_pb2 as messages
class TestDeviceLoadXprv(common.TrezorTest): class TestDeviceLoadXprv(common.TrezorTest):
@ -43,5 +42,6 @@ class TestDeviceLoadXprv(common.TrezorTest):
address = self.client.get_address('Bitcoin', []) address = self.client.get_address('Bitcoin', [])
self.assertEqual(address, '1CHUbFa4wTTPYgkYaw2LHSd5D4qJjMU8ri') self.assertEqual(address, '1CHUbFa4wTTPYgkYaw2LHSd5D4qJjMU8ri')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -16,13 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>. # along with this library. If not, see <http://www.gnu.org/licenses/>.
import time
import unittest import unittest
import common import common
from trezorlib import messages_pb2 as proto from trezorlib import messages_pb2 as proto
from trezorlib import types_pb2 as proto_types from trezorlib import types_pb2 as proto_types
class TestPing(common.TrezorTest): class TestPing(common.TrezorTest):
def test_ping(self): def test_ping(self):
@ -62,5 +62,6 @@ class TestPing(common.TrezorTest):
res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True) res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
self.assertEqual(res, 'random data') self.assertEqual(res, 'random data')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -23,6 +23,7 @@ import common
from trezorlib import messages_pb2 as proto from trezorlib import messages_pb2 as proto
class TestDeviceRecovery(common.TrezorTest): class TestDeviceRecovery(common.TrezorTest):
def test_pin_passphrase(self): def test_pin_passphrase(self):
mnemonic = self.mnemonic12.split(' ') mnemonic = self.mnemonic12.split(' ')
@ -171,5 +172,6 @@ class TestDeviceRecovery(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
self.assertRaises(Exception, self.client.recovery_device, 12, False, False, 'label', 'english') self.assertRaises(Exception, self.client.recovery_device, 12, False, False, 'label', 'english')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -17,12 +17,13 @@
# along with this library. If not, see <http://www.gnu.org/licenses/>. # along with this library. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
import common
import hashlib import hashlib
import common
from trezorlib import messages_pb2 as proto from trezorlib import messages_pb2 as proto
from mnemonic import Mnemonic from mnemonic import Mnemonic
def generate_entropy(strength, internal_entropy, external_entropy): def generate_entropy(strength, internal_entropy, external_entropy):
''' '''
strength - length of produced seed. One of 128, 192, 256 strength - length of produced seed. One of 128, 192, 256
@ -51,18 +52,21 @@ def generate_entropy(strength, internal_entropy, external_entropy):
return entropy_stripped return entropy_stripped
class TestDeviceReset(common.TrezorTest): class TestDeviceReset(common.TrezorTest):
def test_reset_device(self): def test_reset_device(self):
# No PIN, no passphrase # No PIN, no passphrase
external_entropy = b'zlutoucky kun upel divoke ody' * 2 external_entropy = b'zlutoucky kun upel divoke ody' * 2
strength = 128 strength = 128
ret = self.client.call_raw(proto.ResetDevice(display_random=False, ret = self.client.call_raw(proto.ResetDevice(
strength=strength, display_random=False,
passphrase_protection=False, strength=strength,
pin_protection=False, passphrase_protection=False,
language='english', pin_protection=False,
label='test')) language='english',
label='test'
))
# Provide entropy # Provide entropy
self.assertIsInstance(ret, proto.EntropyRequest) self.assertIsInstance(ret, proto.EntropyRequest)
@ -74,7 +78,7 @@ class TestDeviceReset(common.TrezorTest):
expected_mnemonic = Mnemonic('english').to_mnemonic(entropy) expected_mnemonic = Mnemonic('english').to_mnemonic(entropy)
mnemonic = [] mnemonic = []
for _ in range(strength//32*3): for _ in range(strength // 32 * 3):
self.assertIsInstance(ret, proto.ButtonRequest) self.assertIsInstance(ret, proto.ButtonRequest)
mnemonic.append(self.client.debug.read_reset_word()) mnemonic.append(self.client.debug.read_reset_word())
self.client.debug.press_yes() self.client.debug.press_yes()
@ -86,7 +90,7 @@ class TestDeviceReset(common.TrezorTest):
self.assertEqual(mnemonic, expected_mnemonic) self.assertEqual(mnemonic, expected_mnemonic)
mnemonic = [] mnemonic = []
for _ in range(strength//32*3): for _ in range(strength // 32 * 3):
self.assertIsInstance(ret, proto.ButtonRequest) self.assertIsInstance(ret, proto.ButtonRequest)
mnemonic.append(self.client.debug.read_reset_word()) mnemonic.append(self.client.debug.read_reset_word())
self.client.debug.press_yes() self.client.debug.press_yes()
@ -116,12 +120,14 @@ class TestDeviceReset(common.TrezorTest):
external_entropy = b'zlutoucky kun upel divoke ody' * 2 external_entropy = b'zlutoucky kun upel divoke ody' * 2
strength = 128 strength = 128
ret = self.client.call_raw(proto.ResetDevice(display_random=True, ret = self.client.call_raw(proto.ResetDevice(
strength=strength, display_random=True,
passphrase_protection=True, strength=strength,
pin_protection=True, passphrase_protection=True,
language='english', pin_protection=True,
label='test')) language='english',
label='test'
))
self.assertIsInstance(ret, proto.ButtonRequest) self.assertIsInstance(ret, proto.ButtonRequest)
self.client.debug.press_yes() self.client.debug.press_yes()
@ -148,7 +154,7 @@ class TestDeviceReset(common.TrezorTest):
expected_mnemonic = Mnemonic('english').to_mnemonic(entropy) expected_mnemonic = Mnemonic('english').to_mnemonic(entropy)
mnemonic = [] mnemonic = []
for _ in range(strength//32*3): for _ in range(strength // 32 * 3):
self.assertIsInstance(ret, proto.ButtonRequest) self.assertIsInstance(ret, proto.ButtonRequest)
mnemonic.append(self.client.debug.read_reset_word()) mnemonic.append(self.client.debug.read_reset_word())
self.client.debug.press_yes() self.client.debug.press_yes()
@ -160,7 +166,7 @@ class TestDeviceReset(common.TrezorTest):
self.assertEqual(mnemonic, expected_mnemonic) self.assertEqual(mnemonic, expected_mnemonic)
mnemonic = [] mnemonic = []
for _ in range(strength//32*3): for _ in range(strength // 32 * 3):
self.assertIsInstance(ret, proto.ButtonRequest) self.assertIsInstance(ret, proto.ButtonRequest)
mnemonic.append(self.client.debug.read_reset_word()) mnemonic.append(self.client.debug.read_reset_word())
self.client.debug.press_yes() self.client.debug.press_yes()
@ -189,15 +195,17 @@ class TestDeviceReset(common.TrezorTest):
self.client.call_raw(proto.Cancel()) self.client.call_raw(proto.Cancel())
def test_failed_pin(self): def test_failed_pin(self):
external_entropy = b'zlutoucky kun upel divoke ody' * 2 # external_entropy = b'zlutoucky kun upel divoke ody' * 2
strength = 128 strength = 128
ret = self.client.call_raw(proto.ResetDevice(display_random=True, ret = self.client.call_raw(proto.ResetDevice(
strength=strength, display_random=True,
passphrase_protection=True, strength=strength,
pin_protection=True, passphrase_protection=True,
language='english', pin_protection=True,
label='test')) language='english',
label='test'
))
self.assertIsInstance(ret, proto.ButtonRequest) self.assertIsInstance(ret, proto.ButtonRequest)
self.client.debug.press_yes() self.client.debug.press_yes()
@ -220,5 +228,6 @@ class TestDeviceReset(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
self.assertRaises(Exception, self.client.reset_device, False, 128, True, True, 'label', 'english') self.assertRaises(Exception, self.client.reset_device, False, 128, True, True, 'label', 'english')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -19,29 +19,35 @@
from __future__ import print_function from __future__ import print_function
import unittest import unittest
import common
import binascii import binascii
import hashlib import hashlib
import struct import struct
import common
from trezorlib.client import CallException
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
def check_path(identity): def check_path(identity):
m = hashlib.sha256() m = hashlib.sha256()
m.update(struct.pack("<I", identity.index)) m.update(struct.pack("<I", identity.index))
uri = '' uri = ''
if identity.proto: uri += identity.proto + '://' if identity.proto:
if identity.user: uri += identity.user + '@' uri += identity.proto + '://'
if identity.host: uri += identity.host if identity.user:
if identity.port: uri += ':' + identity.port uri += identity.user + '@'
if identity.path: uri += identity.path if identity.host:
uri += identity.host
if identity.port:
uri += ':' + identity.port
if identity.path:
uri += identity.path
m.update(uri) m.update(uri)
print('hash:', m.hexdigest()) print('hash:', m.hexdigest())
(a, b, c, d, _, _, _, _) = struct.unpack('<8I', m.digest()) (a, b, c, d, _, _, _, _) = struct.unpack('<8I', m.digest())
address_n = [0x80000000 | 13, 0x80000000 | a, 0x80000000 | b, 0x80000000 | c, 0x80000000 | d] address_n = [0x80000000 | 13, 0x80000000 | a, 0x80000000 | b, 0x80000000 | c, 0x80000000 | d]
print('path:', 'm/' + '/'.join([str(x) for x in address_n])) print('path:', 'm/' + '/'.join([str(x) for x in address_n]))
class TestMsgSignidentity(common.TrezorTest): class TestMsgSignidentity(common.TrezorTest):
def test_sign(self): def test_sign(self):

View File

@ -20,7 +20,6 @@ import unittest
import common import common
import binascii import binascii
from trezorlib.client import CallException
class TestMsgSignmessage(common.TrezorTest): class TestMsgSignmessage(common.TrezorTest):
@ -57,5 +56,6 @@ class TestMsgSignmessage(common.TrezorTest):
self.assertEqual(sig_nfc.address, '14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e') self.assertEqual(sig_nfc.address, '14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e')
self.assertEqual(binascii.hexlify(sig_nfc.signature), b'20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6') self.assertEqual(binascii.hexlify(sig_nfc.signature), b'20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -45,16 +45,18 @@ class TestMsgSigntx(common.TrezorTest):
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
# input 0: 0.0039 BTC # input 0: 0.0039 BTC
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=390000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=TXHASH_d5f65e, # amount=390000,
prev_index=0, prev_hash=TXHASH_d5f65e,
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', out1 = proto_types.TxOutputType(
amount=390000 - 10000, address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
script_type=proto_types.PAYTOADDRESS, amount=390000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -82,21 +84,24 @@ class TestMsgSigntx(common.TrezorTest):
# tx: 6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54 # tx: 6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54
# input 1: 10.00000000 BTC # input 1: 10.00000000 BTC
inp1 = proto_types.TxInputType(address_n=[0], # mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL inp1 = proto_types.TxInputType(
# amount=1000000000, address_n=[0], # mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL
prev_hash=TXHASH_6f90f3, # amount=1000000000,
prev_index=1, prev_hash=TXHASH_6f90f3,
) prev_index=1,
)
out1 = proto_types.TxOutputType(address='mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV', out1 = proto_types.TxOutputType(
amount=1000000000 - 500000000 - 10000000, address='mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV',
script_type=proto_types.PAYTOADDRESS, amount=1000000000 - 500000000 - 10000000,
) script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType(address_n=[2], out2 = proto_types.TxOutputType(
amount=500000000, address_n=[2],
script_type=proto_types.PAYTOADDRESS, amount=500000000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
@ -127,21 +132,24 @@ class TestMsgSigntx(common.TrezorTest):
# tx: 6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54 # tx: 6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54
# input 1: 10.00000000 BTC # input 1: 10.00000000 BTC
inp1 = proto_types.TxInputType(address_n=[0], # mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL inp1 = proto_types.TxInputType(
# amount=1000000000, address_n=[0], # mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL
prev_hash=TXHASH_6f90f3, # amount=1000000000,
prev_index=1, prev_hash=TXHASH_6f90f3,
) prev_index=1,
)
out1 = proto_types.TxOutputType(address='mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV', out1 = proto_types.TxOutputType(
amount=1000000000 - 500000000 - 100000000, address='mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV',
script_type=proto_types.PAYTOADDRESS, amount=1000000000 - 500000000 - 100000000,
) script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType(address_n=[2], out2 = proto_types.TxOutputType(
amount=500000000, address_n=[2],
script_type=proto_types.PAYTOADDRESS, amount=500000000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
@ -174,21 +182,24 @@ class TestMsgSigntx(common.TrezorTest):
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
# input 0: 0.0039 BTC # input 0: 0.0039 BTC
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=390000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=TXHASH_d5f65e, # amount=390000,
prev_index=0, prev_hash=TXHASH_d5f65e,
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', out1 = proto_types.TxOutputType(
amount=390000 - 80000 - 10000, address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
script_type=proto_types.PAYTOADDRESS, amount=390000 - 80000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType(address_n=[1], out2 = proto_types.TxOutputType(
amount=80000, address_n=[1],
script_type=proto_types.PAYTOADDRESS, amount=80000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -218,26 +229,30 @@ class TestMsgSigntx(common.TrezorTest):
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
# input 0: 0.0039 BTC # input 0: 0.0039 BTC
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=390000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=TXHASH_d5f65e, # amount=390000,
prev_index=0, prev_hash=TXHASH_d5f65e,
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', out1 = proto_types.TxOutputType(
amount=390000 - 80000 - 12000 - 10000, address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
script_type=proto_types.PAYTOADDRESS, amount=390000 - 80000 - 12000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType(address='13uaUYn6XAooo88QvAqAVsiVvr2mAXutqP', out2 = proto_types.TxOutputType(
amount=12000, address='13uaUYn6XAooo88QvAqAVsiVvr2mAXutqP',
script_type=proto_types.PAYTOADDRESS, amount=12000,
) script_type=proto_types.PAYTOADDRESS,
)
out3 = proto_types.TxOutputType(address_n=[1], out3 = proto_types.TxOutputType(
amount=80000, address_n=[1],
script_type=proto_types.PAYTOADDRESS, amount=80000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -273,27 +288,31 @@ class TestMsgSigntx(common.TrezorTest):
# tx: 58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e # tx: 58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e
# input 1: 0.0011 BTC # input 1: 0.0011 BTC
inp1 = proto_types.TxInputType(address_n=[1], # 1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb inp1 = proto_types.TxInputType(
# amount=100000, address_n=[1], # 1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb
prev_hash=TXHASH_c6be22, # amount=100000,
prev_index=1, prev_hash=TXHASH_c6be22,
) prev_index=1,
)
inp2 = proto_types.TxInputType(address_n=[2], # 15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG inp2 = proto_types.TxInputType(
# amount=110000, address_n=[2], # 15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG
prev_hash=TXHASH_58497a, # amount=110000,
prev_index=1, prev_hash=TXHASH_58497a,
) prev_index=1,
)
out1 = proto_types.TxOutputType(address='15Jvu3nZNP7u2ipw2533Q9VVgEu2Lu9F2B', out1 = proto_types.TxOutputType(
amount=210000 - 100000 - 10000, address='15Jvu3nZNP7u2ipw2533Q9VVgEu2Lu9F2B',
script_type=proto_types.PAYTOADDRESS, amount=210000 - 100000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType(address_n=[3], # 1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5 out2 = proto_types.TxOutputType(
amount=100000, address_n=[3], # 1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5
script_type=proto_types.PAYTOADDRESS, amount=100000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -358,25 +377,28 @@ class TestMsgSigntx(common.TrezorTest):
# tx: 39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5 # tx: 39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5
# index 1: 0.0254 BTC # index 1: 0.0254 BTC
inp1 = proto_types.TxInputType(address_n=[3], # 1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5 inp1 = proto_types.TxInputType(
# amount=100000, address_n=[3], # 1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5
prev_hash=TXHASH_c63e24, # amount=100000,
prev_index=1, prev_hash=TXHASH_c63e24,
) prev_index=1,
)
inp2 = proto_types.TxInputType(address_n=[3], # 1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5 inp2 = proto_types.TxInputType(
# amount=2540000, address_n=[3], # 1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5
prev_hash=TXHASH_39a29e, # amount=2540000,
prev_index=1, prev_hash=TXHASH_39a29e,
) prev_index=1,
)
outputs = [] outputs = []
cnt = 255 cnt = 255
for _ in range(cnt): for _ in range(cnt):
out = proto_types.TxOutputType(address='1NwN6UduuVkJi6sw3gSiKZaCY5rHgVXC2h', out = proto_types.TxOutputType(
amount=(100000 + 2540000 - 39000) // cnt, address='1NwN6UduuVkJi6sw3gSiKZaCY5rHgVXC2h',
script_type=proto_types.PAYTOADDRESS, amount=(100000 + 2540000 - 39000) // cnt,
) script_type=proto_types.PAYTOADDRESS,
)
outputs.append(out) outputs.append(out)
with self.client: with self.client:
@ -424,16 +446,18 @@ class TestMsgSigntx(common.TrezorTest):
# tx: 1570416eb4302cf52979afd5e6909e37d8fdd874301f7cc87e547e509cb1caa6 # tx: 1570416eb4302cf52979afd5e6909e37d8fdd874301f7cc87e547e509cb1caa6
# input 0: 1.0 BTC # input 0: 1.0 BTC
inp1 = proto_types.TxInputType(address_n=[0], # 1HWDaLTpTCTtRWyWqZkzWx1wex5NKyncLW inp1 = proto_types.TxInputType(
# amount=100000000, address_n=[0], # 1HWDaLTpTCTtRWyWqZkzWx1wex5NKyncLW
prev_hash=TXHASH_157041, # amount=100000000,
prev_index=0, prev_hash=TXHASH_157041,
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', out1 = proto_types.TxOutputType(
amount=100000000 - 510000, address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
script_type=proto_types.PAYTOADDRESS, amount=100000000 - 510000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -461,16 +485,18 @@ class TestMsgSigntx(common.TrezorTest):
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
# input 0: 0.0039 BTC # input 0: 0.0039 BTC
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=390000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=TXHASH_d5f65e, # amount=390000,
prev_index=0, prev_hash=TXHASH_d5f65e,
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', out1 = proto_types.TxOutputType(
amount=400000, address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
script_type=proto_types.PAYTOADDRESS, amount=400000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -494,16 +520,18 @@ class TestMsgSigntx(common.TrezorTest):
def test_p2sh(self): def test_p2sh(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=400000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=TXHASH_54aa56, # amount=400000,
prev_index=1, prev_hash=TXHASH_54aa56,
) prev_index=1,
)
out1 = proto_types.TxOutputType(address='3DKGE1pvPpBAgZj94MbCinwmksewUNNYVR', # p2sh out1 = proto_types.TxOutputType(
amount=400000 - 10000, address='3DKGE1pvPpBAgZj94MbCinwmksewUNNYVR', # p2sh
script_type=proto_types.PAYTOSCRIPTHASH, amount=400000 - 10000,
) script_type=proto_types.PAYTOSCRIPTHASH,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -536,27 +564,31 @@ class TestMsgSigntx(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
inp1 = proto_types.TxInputType(address_n=[1], # 1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb inp1 = proto_types.TxInputType(
# amount=100000, address_n=[1], # 1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb
prev_hash=TXHASH_c6be22, # amount=100000,
prev_index=1, prev_hash=TXHASH_c6be22,
) prev_index=1,
)
inp2 = proto_types.TxInputType(address_n=[2], # 15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG inp2 = proto_types.TxInputType(
# amount=110000, address_n=[2], # 15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG
prev_hash=TXHASH_58497a, # amount=110000,
prev_index=1, prev_hash=TXHASH_58497a,
) prev_index=1,
)
out1 = proto_types.TxOutputType(address='15Jvu3nZNP7u2ipw2533Q9VVgEu2Lu9F2B', out1 = proto_types.TxOutputType(
amount=210000 - 100000 - 10000, address='15Jvu3nZNP7u2ipw2533Q9VVgEu2Lu9F2B',
script_type=proto_types.PAYTOADDRESS, amount=210000 - 100000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType(address_n=[3], # 1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5 out2 = proto_types.TxOutputType(
amount=100000, address_n=[3], # 1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5
script_type=proto_types.PAYTOADDRESS, amount=100000,
) script_type=proto_types.PAYTOADDRESS,
)
global run_attack global run_attack
run_attack = False run_attack = False
@ -593,16 +625,18 @@ class TestMsgSigntx(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
inp1 = proto_types.TxInputType(address_n=[1], # mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV inp1 = proto_types.TxInputType(
# amount=390000, address_n=[1], # mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV
prev_hash=TXHASH_d6da21, # amount=390000,
prev_index=0, prev_hash=TXHASH_d6da21,
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='mm6FM31rM5Vc3sw5D7kztiBg3jHUzyqF1g', out1 = proto_types.TxOutputType(
amount=2500278230 - 10000, address='mm6FM31rM5Vc3sw5D7kztiBg3jHUzyqF1g',
script_type=proto_types.PAYTOADDRESS, amount=2500278230 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
@ -624,5 +658,6 @@ class TestMsgSigntx(common.TrezorTest):
# Accepted by network: tx # Accepted by network: tx
self.assertEqual(binascii.hexlify(serialized_tx), b'010000000136825bfdb78c8ede226c7c4f25a018e99a2c061d63c7fb425fca7c7d6721dad6000000006a473044022047845c366eb24f40be315c7815a154513c444c7989eb80f7ce7ff6aeb703d26a022007c1f5efadf67c5889634fd7ac39a7ce78bffac291673e8772ecd8389c901d9f01210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6ffffffff01c6100795000000001976a9143d2496e67f5f57a924353da42d4725b318e7a8ea88ac00000000') self.assertEqual(binascii.hexlify(serialized_tx), b'010000000136825bfdb78c8ede226c7c4f25a018e99a2c061d63c7fb425fca7c7d6721dad6000000006a473044022047845c366eb24f40be315c7815a154513c444c7989eb80f7ce7ff6aeb703d26a022007c1f5efadf67c5889634fd7ac39a7ce78bffac291673e8772ecd8389c901d9f01210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6ffffffff01c6100795000000001976a9143d2496e67f5f57a924353da42d4725b318e7a8ea88ac00000000')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -21,31 +21,33 @@ import binascii
import trezorlib.messages_pb2 as proto import trezorlib.messages_pb2 as proto
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
from trezorlib.client import CallException
from trezorlib.tx_api import TxApiTestnet from trezorlib.tx_api import TxApiTestnet
from trezorlib.ckd_public import deserialize from trezorlib.ckd_public import deserialize
class TestMsgSigntxSegwit(common.TrezorTest): class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_p2sh(self): def test_send_p2sh(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("49'/1'/0'/1/0"), inp1 = proto_types.TxInputType(
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX address_n=self.client.expand_path("49'/1'/0'/1/0"),
amount=123456789, # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'), amount=123456789,
prev_index=0, prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'),
script_type=proto_types.SPENDP2SHWITNESS, prev_index=0,
) script_type=proto_types.SPENDP2SHWITNESS,
out1 = proto_types.TxOutputType(address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC', )
amount=12300000, out1 = proto_types.TxOutputType(
script_type=proto_types.PAYTOADDRESS, address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
) amount=12300000,
script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType( out2 = proto_types.TxOutputType(
address='2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX', address='2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX',
script_type=proto_types.PAYTOADDRESS, script_type=proto_types.PAYTOADDRESS,
amount=123456789 - 11000 - 12300000, amount=123456789 - 11000 - 12300000,
) )
with self.client: with self.client:
self.client.set_expected_responses([ 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.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
@ -67,22 +69,24 @@ class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_p2sh_change(self): def test_send_p2sh_change(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("49'/1'/0'/1/0"), inp1 = proto_types.TxInputType(
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX address_n=self.client.expand_path("49'/1'/0'/1/0"),
amount=123456789, # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'), amount=123456789,
prev_index=0, prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'),
script_type=proto_types.SPENDP2SHWITNESS, prev_index=0,
) script_type=proto_types.SPENDP2SHWITNESS,
out1 = proto_types.TxOutputType(address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC', )
amount=12300000, out1 = proto_types.TxOutputType(
script_type=proto_types.PAYTOADDRESS, address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
) amount=12300000,
script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType( out2 = proto_types.TxOutputType(
address_n=self.client.expand_path("49'/1'/0'/1/0"), address_n=self.client.expand_path("49'/1'/0'/1/0"),
script_type=proto_types.PAYTOP2SHWITNESS, script_type=proto_types.PAYTOP2SHWITNESS,
amount=123456789 - 11000 - 12300000, amount=123456789 - 11000 - 12300000,
) )
with self.client: with self.client:
self.client.set_expected_responses([ 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.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
@ -103,19 +107,20 @@ class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_multisig_1(self): def test_send_multisig_1(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
nodes = map(lambda index : self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1,4)) nodes = map(lambda index: self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[2,0]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[2, 0]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("999'/1'/1'/2/0"), inp1 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be'), address_n=self.client.expand_path("999'/1'/1'/2/0"),
prev_index=1, prev_hash=binascii.unhexlify('9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be'),
script_type=proto_types.SPENDP2SHWITNESS, prev_index=1,
multisig=multisig, script_type=proto_types.SPENDP2SHWITNESS,
amount=1610436 multisig=multisig,
amount=1610436
) )
out1 = proto_types.TxOutputType(address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC', out1 = proto_types.TxOutputType(address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
@ -133,7 +138,7 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
# store signature # store signature
inp1.multisig.signatures[0] = signatures1[0] inp1.multisig.signatures[0] = signatures1[0]
# sign with third key # sign with third key
@ -148,9 +153,10 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])
self.assertEqual(binascii.hexlify(serialized_tx), b'01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402205b44c20cf2681690edaaf7cd2e30d4704124dd8b7eb1fb7f459d3906c3c374a602205ca359b6544ce2c101c979899c782f7d141c3b0454ea69202b1fb4c09d3b715701473044022052fafa64022554ae436dbf781e550bf0d326fef31eea1438350b3ff1940a180102202851bd19203b7fe8582a9ef52e82aa9f61cd52d4bcedfe6dcc0cf782468e6a8e01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000') self.assertEqual(binascii.hexlify(serialized_tx), b'01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402205b44c20cf2681690edaaf7cd2e30d4704124dd8b7eb1fb7f459d3906c3c374a602205ca359b6544ce2c101c979899c782f7d141c3b0454ea69202b1fb4c09d3b715701473044022052fafa64022554ae436dbf781e550bf0d326fef31eea1438350b3ff1940a180102202851bd19203b7fe8582a9ef52e82aa9f61cd52d4bcedfe6dcc0cf782468e6a8e01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -21,30 +21,32 @@ import binascii
import trezorlib.messages_pb2 as proto import trezorlib.messages_pb2 as proto
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
from trezorlib.client import CallException
from trezorlib.tx_api import TxApiTestnet from trezorlib.tx_api import TxApiTestnet
from trezorlib.ckd_public import deserialize from trezorlib.ckd_public import deserialize
class TestMsgSigntxSegwit(common.TrezorTest): class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_p2sh(self): def test_send_p2sh(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("49'/1'/0'/1/0"), inp1 = proto_types.TxInputType(
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX address_n=self.client.expand_path("49'/1'/0'/1/0"),
amount=123456789, # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'), amount=123456789,
prev_index=0, prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'),
script_type=proto_types.SPENDP2SHWITNESS, prev_index=0,
) script_type=proto_types.SPENDP2SHWITNESS,
out1 = proto_types.TxOutputType(address='QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i', )
amount=12300000, out1 = proto_types.TxOutputType(
script_type=proto_types.PAYTOADDRESS, address='QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i',
) amount=12300000,
script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType( out2 = proto_types.TxOutputType(
address='2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX', address='2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX',
script_type=proto_types.PAYTOADDRESS, script_type=proto_types.PAYTOADDRESS,
amount=123456789 - 11000 - 12300000, amount=123456789 - 11000 - 12300000,
) )
with self.client: with self.client:
self.client.set_expected_responses([ 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.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
@ -66,22 +68,24 @@ class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_p2sh_change(self): def test_send_p2sh_change(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("49'/1'/0'/1/0"), inp1 = proto_types.TxInputType(
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX address_n=self.client.expand_path("49'/1'/0'/1/0"),
amount=123456789, # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'), amount=123456789,
prev_index=0, prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'),
script_type=proto_types.SPENDP2SHWITNESS, prev_index=0,
) script_type=proto_types.SPENDP2SHWITNESS,
out1 = proto_types.TxOutputType(address='QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i', )
amount=12300000, out1 = proto_types.TxOutputType(
script_type=proto_types.PAYTOADDRESS, address='QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i',
) amount=12300000,
script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType( out2 = proto_types.TxOutputType(
address_n=self.client.expand_path("49'/1'/0'/1/0"), address_n=self.client.expand_path("49'/1'/0'/1/0"),
script_type=proto_types.PAYTOP2SHWITNESS, script_type=proto_types.PAYTOP2SHWITNESS,
amount=123456789 - 11000 - 12300000, amount=123456789 - 11000 - 12300000,
) )
with self.client: with self.client:
self.client.set_expected_responses([ 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.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
@ -102,22 +106,24 @@ class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_native(self): def test_send_native(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("49'/1'/0'/0/0"), inp1 = proto_types.TxInputType(
# QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i address_n=self.client.expand_path("49'/1'/0'/0/0"),
amount=12300000, # QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i
prev_hash=binascii.unhexlify('09144602765ce3dd8f4329445b20e3684e948709c5cdcaf12da3bb079c99448a'), amount=12300000,
prev_index=0, prev_hash=binascii.unhexlify('09144602765ce3dd8f4329445b20e3684e948709c5cdcaf12da3bb079c99448a'),
script_type=proto_types.SPENDWITNESS, prev_index=0,
) script_type=proto_types.SPENDWITNESS,
out1 = proto_types.TxOutputType(address='2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp', )
amount=5000000, out1 = proto_types.TxOutputType(
script_type=proto_types.PAYTOADDRESS, address='2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp',
) amount=5000000,
script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType( out2 = proto_types.TxOutputType(
address='QWzGpyMkAEvmkSVprBzRRVQMP6UPp17q4kQn', address='QWzGpyMkAEvmkSVprBzRRVQMP6UPp17q4kQn',
script_type=proto_types.PAYTOADDRESS, script_type=proto_types.PAYTOADDRESS,
amount=12300000 - 11000 - 5000000, amount=12300000 - 11000 - 5000000,
) )
with self.client: with self.client:
self.client.set_expected_responses([ 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.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
@ -132,29 +138,31 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1, out2 ]) (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1, out2])
self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001018a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090000000000ffffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014d16b8c0680c61fc6ed2e407455715055e41052f502483045022100a7ca8f097525f9044e64376dc0a0f5d4aeb8d15d66808ba97979a0475b06b66502200597c8ebcef63e047f9aeef1a8001d3560470cf896c12f6990eec4faec599b950121033add1f0e8e3c3136f7428dd4a4de1057380bd311f5b0856e2269170b4ffa65bf00000000') self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001018a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090000000000ffffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014d16b8c0680c61fc6ed2e407455715055e41052f502483045022100a7ca8f097525f9044e64376dc0a0f5d4aeb8d15d66808ba97979a0475b06b66502200597c8ebcef63e047f9aeef1a8001d3560470cf896c12f6990eec4faec599b950121033add1f0e8e3c3136f7428dd4a4de1057380bd311f5b0856e2269170b4ffa65bf00000000')
def test_send_native_change(self): def test_send_native_change(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("49'/1'/0'/0/0"), inp1 = proto_types.TxInputType(
# QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i address_n=self.client.expand_path("49'/1'/0'/0/0"),
amount=12300000, # QWywnqNMsMNavbCgMYiQLa91ApvsVRoaqt1i
prev_hash=binascii.unhexlify('09144602765ce3dd8f4329445b20e3684e948709c5cdcaf12da3bb079c99448a'), amount=12300000,
prev_index=0, prev_hash=binascii.unhexlify('09144602765ce3dd8f4329445b20e3684e948709c5cdcaf12da3bb079c99448a'),
script_type=proto_types.SPENDWITNESS, prev_index=0,
) script_type=proto_types.SPENDWITNESS,
out1 = proto_types.TxOutputType(address='2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp', )
amount=5000000, out1 = proto_types.TxOutputType(
script_type=proto_types.PAYTOADDRESS, address='2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp',
) amount=5000000,
script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType( out2 = proto_types.TxOutputType(
address_n=self.client.expand_path("49'/1'/0'/1/0"), address_n=self.client.expand_path("49'/1'/0'/1/0"),
script_type=proto_types.PAYTOWITNESS, script_type=proto_types.PAYTOWITNESS,
amount=12300000 - 11000 - 5000000, amount=12300000 - 11000 - 5000000,
) )
with self.client: with self.client:
self.client.set_expected_responses([ 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.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
@ -168,42 +176,47 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1, out2 ]) (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1, out2])
self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001018a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090000000000ffffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014d16b8c0680c61fc6ed2e407455715055e41052f502483045022100a7ca8f097525f9044e64376dc0a0f5d4aeb8d15d66808ba97979a0475b06b66502200597c8ebcef63e047f9aeef1a8001d3560470cf896c12f6990eec4faec599b950121033add1f0e8e3c3136f7428dd4a4de1057380bd311f5b0856e2269170b4ffa65bf00000000') self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001018a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090000000000ffffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014d16b8c0680c61fc6ed2e407455715055e41052f502483045022100a7ca8f097525f9044e64376dc0a0f5d4aeb8d15d66808ba97979a0475b06b66502200597c8ebcef63e047f9aeef1a8001d3560470cf896c12f6990eec4faec599b950121033add1f0e8e3c3136f7428dd4a4de1057380bd311f5b0856e2269170b4ffa65bf00000000')
def test_send_both(self): def test_send_both(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("49'/1'/0'/1/0"), inp1 = proto_types.TxInputType(
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX address_n=self.client.expand_path("49'/1'/0'/1/0"),
amount=111145789, # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
prev_hash=binascii.unhexlify('09144602765ce3dd8f4329445b20e3684e948709c5cdcaf12da3bb079c99448a'), amount=111145789,
prev_index=1, prev_hash=binascii.unhexlify('09144602765ce3dd8f4329445b20e3684e948709c5cdcaf12da3bb079c99448a'),
script_type=proto_types.SPENDP2SHWITNESS, prev_index=1,
) script_type=proto_types.SPENDP2SHWITNESS,
inp2 = proto_types.TxInputType(address_n=self.client.expand_path("49'/1'/0'/1/0"), )
# QWzGpyMkAEvmkSVprBzRRVQMP6UPp17q4kQn inp2 = proto_types.TxInputType(
amount=7289000, address_n=self.client.expand_path("49'/1'/0'/1/0"),
prev_hash=binascii.unhexlify('65b811d3eca0fe6915d9f2d77c86c5a7f19bf66b1b1253c2c51cb4ae5f0c017b'), # QWzGpyMkAEvmkSVprBzRRVQMP6UPp17q4kQn
prev_index=1, amount=7289000,
script_type=proto_types.SPENDWITNESS, prev_hash=binascii.unhexlify('65b811d3eca0fe6915d9f2d77c86c5a7f19bf66b1b1253c2c51cb4ae5f0c017b'),
) prev_index=1,
out1 = proto_types.TxOutputType(address='QWzCpc1NeTN7hNDzK9sQQ9yrTQP8zh5Hef5J', script_type=proto_types.SPENDWITNESS,
amount=12300000, )
script_type=proto_types.PAYTOADDRESS, out1 = proto_types.TxOutputType(
) address='QWzCpc1NeTN7hNDzK9sQQ9yrTQP8zh5Hef5J',
amount=12300000,
script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType( out2 = proto_types.TxOutputType(
#address_n=self.client.expand_path("44'/1'/0'/0/0"), # address_n=self.client.expand_path("44'/1'/0'/0/0"),
#script_type=proto_types.PAYTOP2SHWITNESS, # script_type=proto_types.PAYTOP2SHWITNESS,
address='2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc', address='2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc',
script_type=proto_types.PAYTOADDRESS, script_type=proto_types.PAYTOADDRESS,
amount=45600000, amount=45600000,
) )
out3 = proto_types.TxOutputType(address='mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q', out3 = proto_types.TxOutputType(
amount=111145789 + 7289000 - 11000 - 12300000 - 45600000, address='mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q',
script_type=proto_types.PAYTOADDRESS, amount=111145789 + 7289000 - 11000 - 12300000 - 45600000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_expected_responses([ 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.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
@ -224,7 +237,7 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1, inp2], [out1, out2, out3 ]) (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1, inp2], [out1, out2, out3])
# 0e480a97c7a545c85e101a2f13c9af0e115d43734e1448f0cac3e55fe8e7399d # 0e480a97c7a545c85e101a2f13c9af0e115d43734e1448f0cac3e55fe8e7399d
self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001028a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090100000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff7b010c5faeb41cc5c253121b6bf69bf1a7c5867cd7f2d91569fea0ecd311b8650100000000ffffffff03e0aebb0000000000160014a579388225827d9f2fe9014add644487808c695d00cdb7020000000017a91491233e24a9bf8dbb19c1187ad876a9380c12e787870d859b03000000001976a914a579388225827d9f2fe9014add644487808c695d88ac02483045022100ead79ee134f25bb585b48aee6284a4bb14e07f03cc130253e83450d095515e5202201e161e9402c8b26b666f2b67e5b668a404ef7e57858ae9a6a68c3837e65fdc69012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7902483045022100b4099ec4c7b3123795b3c080a86f4b745f3784eb3f77de79bef1d8da319cbee5022039766865d448a4a3e435a95d0df3ff56ebc6532bf538988a7e8a679b40ec41b6012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000') self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001028a44999c07bba32df1cacdc50987944e68e3205b4429438fdde35c76024614090100000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff7b010c5faeb41cc5c253121b6bf69bf1a7c5867cd7f2d91569fea0ecd311b8650100000000ffffffff03e0aebb0000000000160014a579388225827d9f2fe9014add644487808c695d00cdb7020000000017a91491233e24a9bf8dbb19c1187ad876a9380c12e787870d859b03000000001976a914a579388225827d9f2fe9014add644487808c695d88ac02483045022100ead79ee134f25bb585b48aee6284a4bb14e07f03cc130253e83450d095515e5202201e161e9402c8b26b666f2b67e5b668a404ef7e57858ae9a6a68c3837e65fdc69012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7902483045022100b4099ec4c7b3123795b3c080a86f4b745f3784eb3f77de79bef1d8da319cbee5022039766865d448a4a3e435a95d0df3ff56ebc6532bf538988a7e8a679b40ec41b6012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000')
@ -232,24 +245,27 @@ class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_multisig_1(self): def test_send_multisig_1(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
nodes = map(lambda index : self.client.get_public_node(self.client.expand_path("999'/1'/"+str(index)+"'")), range(1,4)) nodes = map(lambda index: self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[2,0]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[2, 0]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("999'/1'/1'/2/0"), inp1 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be'), address_n=self.client.expand_path("999'/1'/1'/2/0"),
prev_index=1, prev_hash=binascii.unhexlify('9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be'),
script_type=proto_types.SPENDP2SHWITNESS, prev_index=1,
multisig=multisig, script_type=proto_types.SPENDP2SHWITNESS,
amount=1610436 multisig=multisig,
amount=1610436
) )
out1 = proto_types.TxOutputType(address='T7nZJt6QbGJy6Hok4EF2LqtJPcT7z7VFSrSysGS3tEqCfDPwizqy4', out1 = proto_types.TxOutputType(
amount=1605000, address='T7nZJt6QbGJy6Hok4EF2LqtJPcT7z7VFSrSysGS3tEqCfDPwizqy4',
script_type=proto_types.PAYTOADDRESS) amount=1605000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -262,7 +278,7 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
# store signature # store signature
inp1.multisig.signatures[0] = signatures1[0] inp1.multisig.signatures[0] = signatures1[0]
# sign with third key # sign with third key
@ -277,7 +293,7 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])
# f41cbedd8becee05a830f418d13aa665125464547db5c7a6cd28f21639fe1228 # f41cbedd8becee05a830f418d13aa665125464547db5c7a6cd28f21639fe1228
self.assertEqual(binascii.hexlify(serialized_tx), b'01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d180000000000220020c5f4a0a4ea7c0392efe0a9670a73264cffa90b19107cd8a8e9750ff93c77fdfb0400483045022100a9b681f324ff4cf419ab06820d07248cc4e359c77334bf448ae7b5cdf3995ddf022039811f91f55b602368b4ba08a217b82bfd62d1a97dc635deb1457e7cfcc1550b0147304402201ad86a795c3d26881d696fa0a0619c24c4d505718132a82965cc2a609c9d8798022067cd490ce1366cde77e307ced5b13040bbc04991619ea6f49e06cece9a83268b01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000') self.assertEqual(binascii.hexlify(serialized_tx), b'01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d180000000000220020c5f4a0a4ea7c0392efe0a9670a73264cffa90b19107cd8a8e9750ff93c77fdfb0400483045022100a9b681f324ff4cf419ab06820d07248cc4e359c77334bf448ae7b5cdf3995ddf022039811f91f55b602368b4ba08a217b82bfd62d1a97dc635deb1457e7cfcc1550b0147304402201ad86a795c3d26881d696fa0a0619c24c4d505718132a82965cc2a609c9d8798022067cd490ce1366cde77e307ced5b13040bbc04991619ea6f49e06cece9a83268b01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000')
@ -285,24 +301,27 @@ class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_multisig_2(self): def test_send_multisig_2(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
nodes = map(lambda index : self.client.get_public_node(self.client.expand_path("999'/1'/"+str(index)+"'")), range(1,4)) nodes = map(lambda index: self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[2,1]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[2, 1]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("999'/1'/2'/2/1"), inp1 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('f41cbedd8becee05a830f418d13aa665125464547db5c7a6cd28f21639fe1228'), address_n=self.client.expand_path("999'/1'/2'/2/1"),
prev_index=0, prev_hash=binascii.unhexlify('f41cbedd8becee05a830f418d13aa665125464547db5c7a6cd28f21639fe1228'),
script_type=proto_types.SPENDWITNESS, prev_index=0,
multisig=multisig, script_type=proto_types.SPENDWITNESS,
amount=1605000 multisig=multisig,
amount=1605000
) )
out1 = proto_types.TxOutputType(address='T7nY3A3kewpDKumsdhonP4TBDfTXFSc2RNhZxkqmeeszRDHjM5yUn', out1 = proto_types.TxOutputType(
amount=1604000, address='T7nY3A3kewpDKumsdhonP4TBDfTXFSc2RNhZxkqmeeszRDHjM5yUn',
script_type=proto_types.PAYTOADDRESS) amount=1604000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -315,7 +334,7 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
# store signature # store signature
inp1.multisig.signatures[1] = signatures1[0] inp1.multisig.signatures[1] = signatures1[0]
# sign with first key # sign with first key
@ -330,7 +349,7 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])
# c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc # c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc
self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001012812fe3916f228cda6c7b57d5464541265a63ad118f430a805eeec8bddbe1cf40000000000ffffffff01a0791800000000002200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a10400483045022100cc97f21a7cabc543a9b4ac52424e8f7e420622903f2417a1c08a6af68058ec4a02200baca0b222fc825078d94e8e1b55f174c4828bed16697e4281cda2a0c799eecf01473044022009b8058dc30fa7a13310dd8f1a99c4341c4cd95f771c5a41c4381f956e2344c102205e829c560c0184fd4b4db8971f99711e2a87409afa4df0840b4f12a87b2c8afc0169522102740ec30d0af8591a0dd4a3e3b274e57f3f73bdc0638a9603f9ee6ade0475ba57210311aada919974e882abf0c67b5c0fba00000b26997312ca00345027d22359443021029382591271a79d4b12365fa27c67fad3753150d8eaa987e5a12dc5ba1bb2fa1653ae00000000') self.assertEqual(binascii.hexlify(serialized_tx), b'010000000001012812fe3916f228cda6c7b57d5464541265a63ad118f430a805eeec8bddbe1cf40000000000ffffffff01a0791800000000002200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a10400483045022100cc97f21a7cabc543a9b4ac52424e8f7e420622903f2417a1c08a6af68058ec4a02200baca0b222fc825078d94e8e1b55f174c4828bed16697e4281cda2a0c799eecf01473044022009b8058dc30fa7a13310dd8f1a99c4341c4cd95f771c5a41c4381f956e2344c102205e829c560c0184fd4b4db8971f99711e2a87409afa4df0840b4f12a87b2c8afc0169522102740ec30d0af8591a0dd4a3e3b274e57f3f73bdc0638a9603f9ee6ade0475ba57210311aada919974e882abf0c67b5c0fba00000b26997312ca00345027d22359443021029382591271a79d4b12365fa27c67fad3753150d8eaa987e5a12dc5ba1bb2fa1653ae00000000')
@ -338,30 +357,33 @@ class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_multisig_3_change(self): def test_send_multisig_3_change(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
nodes = map(lambda index : self.client.get_public_node(self.client.expand_path("999'/1'/"+str(index)+"'")), range(1,4)) nodes = map(lambda index: self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[2,0]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[2, 0]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )
multisig2 = proto_types.MultisigRedeemScriptType( multisig2 = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[1,1]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[1, 1]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("999'/1'/1'/2/0"), inp1 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc'), address_n=self.client.expand_path("999'/1'/1'/2/0"),
prev_index=0, prev_hash=binascii.unhexlify('c9348040bbc2024e12dcb4a0b4806b0398646b91acf314da028c3f03dd0179fc'),
script_type=proto_types.SPENDWITNESS, prev_index=0,
multisig=multisig, script_type=proto_types.SPENDWITNESS,
amount=1604000 multisig=multisig,
amount=1604000
) )
out1 = proto_types.TxOutputType(address_n=self.client.expand_path("999'/1'/1'/1/1"), out1 = proto_types.TxOutputType(
amount=1603000, address_n=self.client.expand_path("999'/1'/1'/1/1"),
multisig=multisig2, amount=1603000,
script_type=proto_types.PAYTOP2SHWITNESS) multisig=multisig2,
script_type=proto_types.PAYTOP2SHWITNESS
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -373,7 +395,7 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
# store signature # store signature
inp1.multisig.signatures[0] = signatures1[0] inp1.multisig.signatures[0] = signatures1[0]
# sign with third key # sign with third key
@ -388,7 +410,7 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])
# 31bc1c88ce6ae337a6b3057a16d5bad0b561ad1dfc047d0a7fbb8814668f91e5 # 31bc1c88ce6ae337a6b3057a16d5bad0b561ad1dfc047d0a7fbb8814668f91e5
self.assertEqual(binascii.hexlify(serialized_tx), b'01000000000101fc7901dd033f8c02da14f3ac916b6498036b80b4a0b4dc124e02c2bb408034c90000000000ffffffff01b87518000000000017a914a8655acf68f785125561158b0f4db9b5d0044047870400473044022057b571986c07f8ccb231811334ad06ee6f87b722495def2e9511c1da46f3433202207b6e95bdd99e7fc7d319486437cb930d40a4af3cd753c4cb960b330badbf7f35014730440220517ecc6d0a2544276921d8fc2077aec4285ab83b1b21f5eb73cdb6187a0583e4022043fb5ab942f8981c04a54c66a57c4d291fad8514d4a8afea09f01f2db7a8f32901695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000') self.assertEqual(binascii.hexlify(serialized_tx), b'01000000000101fc7901dd033f8c02da14f3ac916b6498036b80b4a0b4dc124e02c2bb408034c90000000000ffffffff01b87518000000000017a914a8655acf68f785125561158b0f4db9b5d0044047870400473044022057b571986c07f8ccb231811334ad06ee6f87b722495def2e9511c1da46f3433202207b6e95bdd99e7fc7d319486437cb930d40a4af3cd753c4cb960b330badbf7f35014730440220517ecc6d0a2544276921d8fc2077aec4285ab83b1b21f5eb73cdb6187a0583e4022043fb5ab942f8981c04a54c66a57c4d291fad8514d4a8afea09f01f2db7a8f32901695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000')
@ -396,30 +418,33 @@ class TestMsgSigntxSegwit(common.TrezorTest):
def test_send_multisig_4_change(self): def test_send_multisig_4_change(self):
self.setup_mnemonic_allallall() self.setup_mnemonic_allallall()
self.client.set_tx_api(TxApiTestnet) self.client.set_tx_api(TxApiTestnet)
nodes = map(lambda index : self.client.get_public_node(self.client.expand_path("999'/1'/"+str(index)+"'")), range(1,4)) nodes = map(lambda index: self.client.get_public_node(self.client.expand_path("999'/1'/%d'" % index)), range(1, 4))
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[1,1]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[1, 1]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )
multisig2 = proto_types.MultisigRedeemScriptType( multisig2 = proto_types.MultisigRedeemScriptType(
pubkeys=map(lambda n : proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[1,2]), nodes), pubkeys=map(lambda n: proto_types.HDNodePathType(node=deserialize(n.xpub), address_n=[1, 2]), nodes),
signatures=[b'', b'', b''], signatures=[b'', b'', b''],
m=2, m=2,
) )
inp1 = proto_types.TxInputType(address_n=self.client.expand_path("999'/1'/1'/1/1"), inp1 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('31bc1c88ce6ae337a6b3057a16d5bad0b561ad1dfc047d0a7fbb8814668f91e5'), address_n=self.client.expand_path("999'/1'/1'/1/1"),
prev_index=0, prev_hash=binascii.unhexlify('31bc1c88ce6ae337a6b3057a16d5bad0b561ad1dfc047d0a7fbb8814668f91e5'),
script_type=proto_types.SPENDP2SHWITNESS, prev_index=0,
multisig=multisig, script_type=proto_types.SPENDP2SHWITNESS,
amount=1603000 multisig=multisig,
amount=1603000
) )
out1 = proto_types.TxOutputType(address_n=self.client.expand_path("999'/1'/1'/1/2"), out1 = proto_types.TxOutputType(
amount=1602000, address_n=self.client.expand_path("999'/1'/1'/1/2"),
multisig=multisig2, amount=1602000,
script_type=proto_types.PAYTOWITNESS) multisig=multisig2,
script_type=proto_types.PAYTOWITNESS
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -431,7 +456,7 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1])
# store signature # store signature
inp1.multisig.signatures[0] = signatures1[0] inp1.multisig.signatures[0] = signatures1[0]
# sign with third key # sign with third key
@ -446,10 +471,11 @@ class TestMsgSigntxSegwit(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto_types.TXFINISHED), proto.TxRequest(request_type=proto_types.TXFINISHED),
]) ])
(signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1 ]) (signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1])
# c0bf56060a109624b4635222696d94a7d533cacea1b3f8245417a4348c045829 # c0bf56060a109624b4635222696d94a7d533cacea1b3f8245417a4348c045829
self.assertEqual(binascii.hexlify(serialized_tx), b'01000000000101e5918f661488bb7f0a7d04fc1dad61b5d0bad5167a05b3a637e36ace881cbc3100000000232200205b9824093eaf5cdcf8247c00dc0b557a7720957828fcde8384ac11f80a91f403ffffffff01d071180000000000220020e77caf5fbef07b1e461475c02afd4aed877693263d69c81e14617304349b629a040047304402204832553b0da1009da496881e58e8e2e41010cfe5c0161623048093f1b1a817b7022020dad8bf887acf574af80bfe4b39cd24e95019fd5e6b8ae967471e21ddc67354014830450221009e5d60847e7275edcf4619ed8ee462c56a042eef75d17da2d44e6b13d78e50e50220665195492900ef87a5eb8a924fa0ac9afc4fc75ca704ff356dc3a213979970c80169522103f4040006e3561b3e76c6d4113225c84748ab9d55ffd23f9578ab4c18fb0c3b9721020975f2e6922897ff6b80da6412a8d6ebd67e33c9611d081656a53ef967964e5021026b0546f23a6ce6b756c2c30b4176ce6f1c3268744f7aca82668d5116c4f764e453ae00000000') self.assertEqual(binascii.hexlify(serialized_tx), b'01000000000101e5918f661488bb7f0a7d04fc1dad61b5d0bad5167a05b3a637e36ace881cbc3100000000232200205b9824093eaf5cdcf8247c00dc0b557a7720957828fcde8384ac11f80a91f403ffffffff01d071180000000000220020e77caf5fbef07b1e461475c02afd4aed877693263d69c81e14617304349b629a040047304402204832553b0da1009da496881e58e8e2e41010cfe5c0161623048093f1b1a817b7022020dad8bf887acf574af80bfe4b39cd24e95019fd5e6b8ae967471e21ddc67354014830450221009e5d60847e7275edcf4619ed8ee462c56a042eef75d17da2d44e6b13d78e50e50220665195492900ef87a5eb8a924fa0ac9afc4fc75ca704ff356dc3a213979970c80169522103f4040006e3561b3e76c6d4113225c84748ab9d55ffd23f9578ab4c18fb0c3b9721020975f2e6922897ff6b80da6412a8d6ebd67e33c9611d081656a53ef967964e5021026b0546f23a6ce6b756c2c30b4176ce6f1c3268744f7aca82668d5116c4f764e453ae00000000')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -22,9 +22,9 @@ import binascii
import trezorlib.messages_pb2 as proto import trezorlib.messages_pb2 as proto
import trezorlib.types_pb2 as proto_types 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): class TestMsgSigntx(common.TrezorTest):
def test_one_one_fee(self): def test_one_one_fee(self):
@ -33,16 +33,18 @@ class TestMsgSigntx(common.TrezorTest):
# tx: 93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c # tx: 93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c
# input 0: 1.234567 TAZ # input 0: 1.234567 TAZ
inp1 = proto_types.TxInputType(address_n=[2147483692, 2147483649, 2147483648, 0, 0], # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu inp1 = proto_types.TxInputType(
# amount=123456700, address_n=[2147483692, 2147483649, 2147483648, 0, 0], # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
prev_hash=binascii.unhexlify(b'93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c'), # amount=123456700,
prev_index=0, prev_hash=binascii.unhexlify(b'93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c'),
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z', out1 = proto_types.TxOutputType(
amount=123456700 - 1940, address='tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z',
script_type=proto_types.PAYTOADDRESS, amount=123456700 - 1940,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
self.client.set_tx_api(TxApiZcashTestnet) self.client.set_tx_api(TxApiZcashTestnet)
@ -50,10 +52,10 @@ class TestMsgSigntx(common.TrezorTest):
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), 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"))), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"))),
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"))),
proto.TxRequest(request_type=proto_types.TXEXTRADATA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"),extra_data_offset=0, extra_data_len=1024)), proto.TxRequest(request_type=proto_types.TXEXTRADATA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"), extra_data_offset=0, extra_data_len=1024)),
proto.TxRequest(request_type=proto_types.TXEXTRADATA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"),extra_data_offset=1024, extra_data_len=1024)), proto.TxRequest(request_type=proto_types.TXEXTRADATA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"), extra_data_offset=1024, extra_data_len=1024)),
proto.TxRequest(request_type=proto_types.TXEXTRADATA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"),extra_data_offset=2048, extra_data_len=1024)), proto.TxRequest(request_type=proto_types.TXEXTRADATA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"), extra_data_offset=2048, extra_data_len=1024)),
proto.TxRequest(request_type=proto_types.TXEXTRADATA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"),extra_data_offset=3072, extra_data_len=629)), proto.TxRequest(request_type=proto_types.TXEXTRADATA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify(b"93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c"), extra_data_offset=3072, extra_data_len=629)),
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
@ -68,5 +70,6 @@ class TestMsgSigntx(common.TrezorTest):
# Accepted by network: tx dcc2a10894e0e8a785c2afd4de2d958207329b9acc2b987fd768a09c5efc4547 # Accepted by network: tx dcc2a10894e0e8a785c2afd4de2d958207329b9acc2b987fd768a09c5efc4547
self.assertEqual(binascii.hexlify(serialized_tx), b'01000000015c2f725c959f9b0c66db42f185a9ebb51b51d675d79a047d4a6c62cc633e3793000000006a4730440220670b2b63d749a7038f9aea6ddf0302fe63bdcad93dafa4a89a1f0e7300ae2484022002c50af43fd867490cea0c527273c5828ff1b9a5115678f155a1830737cf29390121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff0128c55b07000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000') self.assertEqual(binascii.hexlify(serialized_tx), b'01000000015c2f725c959f9b0c66db42f185a9ebb51b51d675d79a047d4a6c62cc633e3793000000006a4730440220670b2b63d749a7038f9aea6ddf0302fe63bdcad93dafa4a89a1f0e7300ae2484022002c50af43fd867490cea0c527273c5828ff1b9a5115678f155a1830737cf29390121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff0128c55b07000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -21,7 +21,6 @@ import common
import binascii import binascii
import base64 import base64
from trezorlib.client import CallException
class TestMsgVerifymessage(common.TrezorTest): class TestMsgVerifymessage(common.TrezorTest):
@ -164,5 +163,6 @@ class TestMsgVerifymessage(common.TrezorTest):
self.assertTrue(res_nfc) self.assertTrue(res_nfc)
""" """
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -21,6 +21,7 @@ import common
from trezorlib import messages_pb2 as proto from trezorlib import messages_pb2 as proto
class TestDeviceWipe(common.TrezorTest): class TestDeviceWipe(common.TrezorTest):
def test_wipe_device(self): def test_wipe_device(self):
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
@ -39,5 +40,6 @@ class TestDeviceWipe(common.TrezorTest):
self.assertEqual(features.passphrase_protection, False) self.assertEqual(features.passphrase_protection, False)
self.assertNotEqual(features.device_id, device_id) self.assertNotEqual(features.device_id, device_id)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -21,7 +21,6 @@ from __future__ import print_function
import unittest import unittest
import common import common
import binascii import binascii
import itertools
import trezorlib.messages_pb2 as proto import trezorlib.messages_pb2 as proto
import trezorlib.ckd_public as bip32 import trezorlib.ckd_public as bip32
@ -33,14 +32,15 @@ from trezorlib.client import CallException
# https://sx.dyne.org/multisig.html # https://sx.dyne.org/multisig.html
# #
class TestMultisig(common.TrezorTest): class TestMultisig(common.TrezorTest):
def test_2_of_3(self): def test_2_of_3(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
#key1 = self.client.get_public_node([1]) # key1 = self.client.get_public_node([1])
#key2 = self.client.get_public_node([2]) # key2 = self.client.get_public_node([2])
#key3 = self.client.get_public_node([3]) # key3 = self.client.get_public_node([3])
# xpub: # xpub:
# print(bip32.serialize(self.client.get_public_node([]).node)) # print(bip32.serialize(self.client.get_public_node([]).node))
@ -62,24 +62,29 @@ class TestMultisig(common.TrezorTest):
node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy') node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy')
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=node, address_n=[1]), pubkeys=[
proto_types.HDNodePathType(node=node, address_n=[2]), proto_types.HDNodePathType(node=node, address_n=[1]),
proto_types.HDNodePathType(node=node, address_n=[3])], proto_types.HDNodePathType(node=node, address_n=[2]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=node, address_n=[3])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
# Let's go to sign with key 1 # Let's go to sign with key 1
inp1 = proto_types.TxInputType(address_n=[1], inp1 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52'), address_n=[1],
prev_index=1, prev_hash=binascii.unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52'),
script_type=proto_types.SPENDMULTISIG, prev_index=1,
multisig=multisig, script_type=proto_types.SPENDMULTISIG,
) multisig=multisig,
)
out1 = proto_types.TxOutputType(address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss', out1 = proto_types.TxOutputType(
amount=100000, address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -106,20 +111,23 @@ class TestMultisig(common.TrezorTest):
# Let's do second signature using 3rd key # Let's do second signature using 3rd key
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=node, address_n=[1]), pubkeys=[
proto_types.HDNodePathType(node=node, address_n=[2]), proto_types.HDNodePathType(node=node, address_n=[1]),
proto_types.HDNodePathType(node=node, address_n=[3])], proto_types.HDNodePathType(node=node, address_n=[2]),
signatures=[signatures1[0], b'', b''], # Fill signature from previous signing process proto_types.HDNodePathType(node=node, address_n=[3])
m=2, ],
) signatures=[signatures1[0], b'', b''], # Fill signature from previous signing process
m=2,
)
# Let's do a second signature with key 3 # Let's do a second signature with key 3
inp3 = proto_types.TxInputType(address_n=[3], inp3 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52'), address_n=[3],
prev_index=1, prev_hash=binascii.unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52'),
script_type=proto_types.SPENDMULTISIG, prev_index=1,
multisig=multisig, script_type=proto_types.SPENDMULTISIG,
) multisig=multisig,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -169,23 +177,26 @@ class TestMultisig(common.TrezorTest):
signatures = [b''] * 15 signatures = [b''] * 15
out1 = proto_types.TxOutputType(address='17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1', out1 = proto_types.TxOutputType(
amount=10000, address='17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1',
script_type=proto_types.PAYTOADDRESS) amount=10000,
script_type=proto_types.PAYTOADDRESS
)
for x in range(15): for x in range(15):
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=pubs, pubkeys=pubs,
signatures=signatures, signatures=signatures,
m=15, m=15,
) )
inp1 = proto_types.TxInputType(address_n=[x], inp1 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('6189e3febb5a21cee8b725aa1ef04ffce7e609448446d3a8d6f483c634ef5315'), address_n=[x],
prev_index=1, prev_hash=binascii.unhexlify('6189e3febb5a21cee8b725aa1ef04ffce7e609448446d3a8d6f483c634ef5315'),
script_type=proto_types.SPENDMULTISIG, prev_index=1,
multisig=multisig, script_type=proto_types.SPENDMULTISIG,
) multisig=multisig,
)
with self.client: with self.client:
(sig, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ]) (sig, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])
@ -197,9 +208,9 @@ class TestMultisig(common.TrezorTest):
def test_missing_pubkey(self): def test_missing_pubkey(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
#key1 = self.client.get_public_node([1]) # key1 = self.client.get_public_node([1])
#key2 = self.client.get_public_node([2]) # key2 = self.client.get_public_node([2])
#key3 = self.client.get_public_node([3]) # key3 = self.client.get_public_node([3])
# pubkeys: # pubkeys:
# 0338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6 # 0338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6
@ -214,24 +225,29 @@ class TestMultisig(common.TrezorTest):
node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy') node = bip32.deserialize('xpub661MyMwAqRbcF1zGijBb2K6x9YiJPh58xpcCeLvTxMX6spkY3PcpJ4ABcCyWfskq5DDxM3e6Ez5ePCqG5bnPUXR4wL8TZWyoDaUdiWW7bKy')
multisig = proto_types.MultisigRedeemScriptType( multisig = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=node, address_n=[1]), pubkeys=[
proto_types.HDNodePathType(node=node, address_n=[2]), proto_types.HDNodePathType(node=node, address_n=[1]),
proto_types.HDNodePathType(node=node, address_n=[3])], proto_types.HDNodePathType(node=node, address_n=[2]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=node, address_n=[3])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
# Let's go to sign with key 10, which is NOT in pubkeys # Let's go to sign with key 10, which is NOT in pubkeys
inp1 = proto_types.TxInputType(address_n=[10], inp1 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52'), address_n=[10],
prev_index=1, prev_hash=binascii.unhexlify('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52'),
script_type=proto_types.SPENDMULTISIG, prev_index=1,
multisig=multisig, script_type=proto_types.SPENDMULTISIG,
) multisig=multisig,
)
out1 = proto_types.TxOutputType(address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss', out1 = proto_types.TxOutputType(
amount=100000, address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
# It should throw Failure 'Pubkey not found in multisig script' # It should throw Failure 'Pubkey not found in multisig script'

View File

@ -19,12 +19,11 @@
import unittest import unittest
import common import common
import binascii import binascii
import itertools
import trezorlib.messages_pb2 as proto import trezorlib.messages_pb2 as proto
import trezorlib.ckd_public as bip32 import trezorlib.ckd_public as bip32
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
from trezorlib.client import CallException
class TestMultisigChange(common.TrezorTest): class TestMultisigChange(common.TrezorTest):
@ -45,67 +44,76 @@ class TestMultisigChange(common.TrezorTest):
# m/2 => 038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3 # m/2 => 038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3
# ext1 + ext2 + int # ext1 + ext2 + int
# redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae # redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae
# multisig address: 3Gj7y1FdTppx2JEDqYqAEZFnKCA4GRysKF # multisig address: 3Gj7y1FdTppx2JEDqYqAEZFnKCA4GRysKF
# tx: d1d08ea63255af4ad16b098e9885a252632086fa6be53301521d05253ce8a73d # tx: d1d08ea63255af4ad16b098e9885a252632086fa6be53301521d05253ce8a73d
# input 0: 0.001 BTC # input 0: 0.001 BTC
# ext1 + int + ext2 # ext1 + int + ext2
# redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c153ae # redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c153ae
# multisig address: 3QsvfB6d1LzYcpm8xyhS1N1HBRrzHTgLHB # multisig address: 3QsvfB6d1LzYcpm8xyhS1N1HBRrzHTgLHB
# tx: a6e2829d089cee47e481b1a753a53081b40738cc87e38f1d9b23ab57d9ad4396 # tx: a6e2829d089cee47e481b1a753a53081b40738cc87e38f1d9b23ab57d9ad4396
# input 0: 0.001 BTC # input 0: 0.001 BTC
# ext1 + ext3 + int # ext1 + ext3 + int
# redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e2102e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae # redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e2102e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae
# multisig address: 37LvC1Q5CyKbMbKMncEJdXxqGhHxrBEgPE # multisig address: 37LvC1Q5CyKbMbKMncEJdXxqGhHxrBEgPE
# tx: e4bc1ae5e5007a08f2b3926fe11c66612e8f73c6b00c69c7027213b84d259be3 # tx: e4bc1ae5e5007a08f2b3926fe11c66612e8f73c6b00c69c7027213b84d259be3
# input 1: 0.001 BTC # input 1: 0.001 BTC
multisig_in1 = proto_types.MultisigRedeemScriptType( multisig_in1 = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=node_ext1, address_n=[1]), pubkeys=[
proto_types.HDNodePathType(node=node_ext2, address_n=[1]), proto_types.HDNodePathType(node=node_ext1, address_n=[1]),
proto_types.HDNodePathType(node=node_int, address_n=[1])], proto_types.HDNodePathType(node=node_ext2, address_n=[1]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=node_int, address_n=[1])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
multisig_in2 = proto_types.MultisigRedeemScriptType( multisig_in2 = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=node_ext1, address_n=[1]), pubkeys=[
proto_types.HDNodePathType(node=node_int, address_n=[1]), proto_types.HDNodePathType(node=node_ext1, address_n=[1]),
proto_types.HDNodePathType(node=node_ext2, address_n=[1])], proto_types.HDNodePathType(node=node_int, address_n=[1]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=node_ext2, address_n=[1])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
multisig_in3 = proto_types.MultisigRedeemScriptType( multisig_in3 = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=node_ext1, address_n=[1]), pubkeys=[
proto_types.HDNodePathType(node=node_ext3, address_n=[1]), proto_types.HDNodePathType(node=node_ext1, address_n=[1]),
proto_types.HDNodePathType(node=node_int, address_n=[1])], proto_types.HDNodePathType(node=node_ext3, address_n=[1]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=node_int, address_n=[1])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
inp1 = proto_types.TxInputType(address_n=[1], inp1 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('d1d08ea63255af4ad16b098e9885a252632086fa6be53301521d05253ce8a73d'), address_n=[1],
prev_index=0, prev_hash=binascii.unhexlify('d1d08ea63255af4ad16b098e9885a252632086fa6be53301521d05253ce8a73d'),
script_type=proto_types.SPENDMULTISIG, prev_index=0,
multisig=multisig_in1, script_type=proto_types.SPENDMULTISIG,
) multisig=multisig_in1,
)
inp2 = proto_types.TxInputType(address_n=[1], inp2 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('a6e2829d089cee47e481b1a753a53081b40738cc87e38f1d9b23ab57d9ad4396'), address_n=[1],
prev_index=0, prev_hash=binascii.unhexlify('a6e2829d089cee47e481b1a753a53081b40738cc87e38f1d9b23ab57d9ad4396'),
script_type=proto_types.SPENDMULTISIG, prev_index=0,
multisig=multisig_in2, script_type=proto_types.SPENDMULTISIG,
) multisig=multisig_in2,
)
inp3 = proto_types.TxInputType(address_n=[1], inp3 = proto_types.TxInputType(
prev_hash=binascii.unhexlify('e4bc1ae5e5007a08f2b3926fe11c66612e8f73c6b00c69c7027213b84d259be3'), address_n=[1],
prev_index=1, prev_hash=binascii.unhexlify('e4bc1ae5e5007a08f2b3926fe11c66612e8f73c6b00c69c7027213b84d259be3'),
script_type=proto_types.SPENDMULTISIG, prev_index=1,
multisig=multisig_in3, script_type=proto_types.SPENDMULTISIG,
) multisig=multisig_in3,
)
def _responses(self, inp1, inp2, change=0): def _responses(self, inp1, inp2, change=0):
resp = [ resp = [
@ -152,13 +160,17 @@ class TestMultisigChange(common.TrezorTest):
def test_external_external(self): def test_external_external(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
out1 = proto_types.TxOutputType(address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss', out1 = proto_types.TxOutputType(
amount=100000, address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
out2 = proto_types.TxOutputType(address='17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1', out2 = proto_types.TxOutputType(
amount=100000, address='17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
self.client.set_expected_responses(self._responses(self.inp1, self.inp2)) self.client.set_expected_responses(self._responses(self.inp1, self.inp2))
@ -170,13 +182,17 @@ class TestMultisigChange(common.TrezorTest):
def test_external_internal(self): def test_external_internal(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
out1 = proto_types.TxOutputType(address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss', out1 = proto_types.TxOutputType(
amount=100000, address='12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
out2 = proto_types.TxOutputType(address_n=[4], out2 = proto_types.TxOutputType(
amount=100000, address_n=[4],
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=2)) self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=2))
@ -188,13 +204,17 @@ class TestMultisigChange(common.TrezorTest):
def test_internal_external(self): def test_internal_external(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
out1 = proto_types.TxOutputType(address_n=[4], out1 = proto_types.TxOutputType(
amount=100000, address_n=[4],
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
out2 = proto_types.TxOutputType(address='17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1', out2 = proto_types.TxOutputType(
amount=100000, address='17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=1)) self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=1))
@ -206,13 +226,17 @@ class TestMultisigChange(common.TrezorTest):
def test_multisig_external_external(self): def test_multisig_external_external(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
out1 = proto_types.TxOutputType(address='3796Q9jVirg2KY1WQRqtmHKXCoSk8MB7Td', out1 = proto_types.TxOutputType(
amount=100000, address='3796Q9jVirg2KY1WQRqtmHKXCoSk8MB7Td',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
out2 = proto_types.TxOutputType(address='3CTPCg3ksh59jWt9zQpTPHCSQDCdJoQQ9d', out2 = proto_types.TxOutputType(
amount=100000, address='3CTPCg3ksh59jWt9zQpTPHCSQDCdJoQQ9d',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
self.client.set_expected_responses(self._responses(self.inp1, self.inp2)) self.client.set_expected_responses(self._responses(self.inp1, self.inp2))
@ -225,21 +249,27 @@ class TestMultisigChange(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
multisig_out1 = proto_types.MultisigRedeemScriptType( multisig_out1 = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=self.node_int, address_n=[1]), pubkeys=[
proto_types.HDNodePathType(node=self.node_ext1, address_n=[1]), proto_types.HDNodePathType(node=self.node_int, address_n=[1]),
proto_types.HDNodePathType(node=self.node_ext2, address_n=[1])], proto_types.HDNodePathType(node=self.node_ext1, address_n=[1]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=self.node_ext2, address_n=[1])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
out1 = proto_types.TxOutputType(address_n=[1], out1 = proto_types.TxOutputType(
multisig=multisig_out1, address_n=[1],
amount=100000, multisig=multisig_out1,
script_type=proto_types.PAYTOMULTISIG) amount=100000,
script_type=proto_types.PAYTOMULTISIG
)
out2 = proto_types.TxOutputType(address='3CTPCg3ksh59jWt9zQpTPHCSQDCdJoQQ9d', out2 = proto_types.TxOutputType(
amount=100000, address='3CTPCg3ksh59jWt9zQpTPHCSQDCdJoQQ9d',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=1)) self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=1))
@ -252,21 +282,27 @@ class TestMultisigChange(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
multisig_out2 = proto_types.MultisigRedeemScriptType( multisig_out2 = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=self.node_int, address_n=[2]), pubkeys=[
proto_types.HDNodePathType(node=self.node_ext1, address_n=[2]), proto_types.HDNodePathType(node=self.node_int, address_n=[2]),
proto_types.HDNodePathType(node=self.node_ext2, address_n=[2])], proto_types.HDNodePathType(node=self.node_ext1, address_n=[2]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=self.node_ext2, address_n=[2])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
out1 = proto_types.TxOutputType(address='37Wf955dcCaFSJmiNaGpacczMwj7iC8JMx', out1 = proto_types.TxOutputType(
amount=100000, address='37Wf955dcCaFSJmiNaGpacczMwj7iC8JMx',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
out2 = proto_types.TxOutputType(address_n=[2], out2 = proto_types.TxOutputType(
multisig=multisig_out2, address_n=[2],
amount=100000, multisig=multisig_out2,
script_type=proto_types.PAYTOMULTISIG) amount=100000,
script_type=proto_types.PAYTOMULTISIG
)
with self.client: with self.client:
self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=2)) self.client.set_expected_responses(self._responses(self.inp1, self.inp2, change=2))
@ -279,21 +315,27 @@ class TestMultisigChange(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
multisig_out2 = proto_types.MultisigRedeemScriptType( multisig_out2 = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=self.node_int, address_n=[2]), pubkeys=[
proto_types.HDNodePathType(node=self.node_ext1, address_n=[2]), proto_types.HDNodePathType(node=self.node_int, address_n=[2]),
proto_types.HDNodePathType(node=self.node_ext3, address_n=[2])], proto_types.HDNodePathType(node=self.node_ext1, address_n=[2]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=self.node_ext3, address_n=[2])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
out1 = proto_types.TxOutputType(address='3796Q9jVirg2KY1WQRqtmHKXCoSk8MB7Td', out1 = proto_types.TxOutputType(
amount=100000, address='3796Q9jVirg2KY1WQRqtmHKXCoSk8MB7Td',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
out2 = proto_types.TxOutputType(address_n=[2], out2 = proto_types.TxOutputType(
multisig=multisig_out2, address_n=[2],
amount=100000, multisig=multisig_out2,
script_type=proto_types.PAYTOMULTISIG) amount=100000,
script_type=proto_types.PAYTOMULTISIG
)
with self.client: with self.client:
self.client.set_expected_responses(self._responses(self.inp1, self.inp2)) self.client.set_expected_responses(self._responses(self.inp1, self.inp2))
@ -306,21 +348,27 @@ class TestMultisigChange(common.TrezorTest):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
multisig_out1 = proto_types.MultisigRedeemScriptType( multisig_out1 = proto_types.MultisigRedeemScriptType(
pubkeys=[proto_types.HDNodePathType(node=self.node_ext1, address_n=[1]), pubkeys=[
proto_types.HDNodePathType(node=self.node_ext2, address_n=[1]), proto_types.HDNodePathType(node=self.node_ext1, address_n=[1]),
proto_types.HDNodePathType(node=self.node_int, address_n=[1])], proto_types.HDNodePathType(node=self.node_ext2, address_n=[1]),
signatures=[b'', b'', b''], proto_types.HDNodePathType(node=self.node_int, address_n=[1])
m=2, ],
) signatures=[b'', b'', b''],
m=2,
)
out1 = proto_types.TxOutputType(address_n=[1], out1 = proto_types.TxOutputType(
multisig=multisig_out1, address_n=[1],
amount=100000, multisig=multisig_out1,
script_type=proto_types.PAYTOMULTISIG) amount=100000,
script_type=proto_types.PAYTOMULTISIG
)
out2 = proto_types.TxOutputType(address='3CTPCg3ksh59jWt9zQpTPHCSQDCdJoQQ9d', out2 = proto_types.TxOutputType(
amount=100000, address='3CTPCg3ksh59jWt9zQpTPHCSQDCdJoQQ9d',
script_type=proto_types.PAYTOADDRESS) amount=100000,
script_type=proto_types.PAYTOADDRESS
)
with self.client: with self.client:
self.client.set_expected_responses(self._responses(self.inp1, self.inp3)) self.client.set_expected_responses(self._responses(self.inp1, self.inp3))
@ -328,5 +376,6 @@ class TestMultisigChange(common.TrezorTest):
self.assertEqual(binascii.hexlify(serialized_tx), b'01000000023da7e83c25051d520133e56bfa86206352a285988e096bd14aaf5532a68ed0d100000000b40047304402204b7d6c7e9feef91209cbdf4deaf855696dc22a40e57bd3eafd5e00b0ee41d9de0220262c5a05d0b46ef98fddfef3831b3ebb6841ffbeb10666f8fb6f8d2e3023e30d014c69522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653aeffffffffe39b254db8137202c7690cb0c6738f2e61661ce16f92b3f2087a00e5e51abce401000000b500483045022100bb2118da21c8a84f115b655f640f269a40be77ae2c0af9c5ffd8260a85dbfc7702202e7b5b6c05b8f50bd879dbee88828e80e85448d686b63a1a50e99d921923f6f5014c69522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e2102e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653aeffffffff02a08601000000000017a914a4efc33d43d7a8a0040182c76ab624ff862f50d287a08601000000000017a9147615527d78854293edadf83682ea26937f8a51bb8700000000') self.assertEqual(binascii.hexlify(serialized_tx), b'01000000023da7e83c25051d520133e56bfa86206352a285988e096bd14aaf5532a68ed0d100000000b40047304402204b7d6c7e9feef91209cbdf4deaf855696dc22a40e57bd3eafd5e00b0ee41d9de0220262c5a05d0b46ef98fddfef3831b3ebb6841ffbeb10666f8fb6f8d2e3023e30d014c69522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653aeffffffffe39b254db8137202c7690cb0c6738f2e61661ce16f92b3f2087a00e5e51abce401000000b500483045022100bb2118da21c8a84f115b655f640f269a40be77ae2c0af9c5ffd8260a85dbfc7702202e7b5b6c05b8f50bd879dbee88828e80e85448d686b63a1a50e99d921923f6f5014c69522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e2102e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653aeffffffff02a08601000000000017a914a4efc33d43d7a8a0040182c76ab624ff862f50d287a08601000000000017a9147615527d78854293edadf83682ea26937f8a51bb8700000000')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -17,9 +17,8 @@
# along with this library. If not, see <http://www.gnu.org/licenses/>. # along with this library. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
import common
import binascii import binascii
import itertools import common
import trezorlib.messages_pb2 as proto import trezorlib.messages_pb2 as proto
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
@ -37,21 +36,24 @@ class TestOpReturn(common.TrezorTest):
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
# input 0: 0.0039 BTC # input 0: 0.0039 BTC
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=390000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=TXHASH_d5f65e, # amount=390000,
prev_index=0, prev_hash=TXHASH_d5f65e,
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', out1 = proto_types.TxOutputType(
amount=390000 - 10000, address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
script_type=proto_types.PAYTOADDRESS, amount=390000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
out2 = proto_types.TxOutputType(op_return_data=b'test of the op_return data', out2 = proto_types.TxOutputType(
amount=0, op_return_data=b'test of the op_return data',
script_type=proto_types.PAYTOOPRETURN, amount=0,
) script_type=proto_types.PAYTOOPRETURN,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -81,21 +83,24 @@ class TestOpReturn(common.TrezorTest):
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
# input 0: 0.0039 BTC # input 0: 0.0039 BTC
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=390000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=TXHASH_d5f65e, # amount=390000,
prev_index=0, prev_hash=TXHASH_d5f65e,
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', out1 = proto_types.TxOutputType(
amount=390000 - 10000 - 10000, address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
script_type=proto_types.PAYTOADDRESS, amount=390000 - 10000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
out1 = proto_types.TxOutputType(op_return_data=b'test of the op_return data', out1 = proto_types.TxOutputType(
amount=10000, op_return_data=b'test of the op_return data',
script_type=proto_types.PAYTOOPRETURN, amount=10000,
) script_type=proto_types.PAYTOOPRETURN,
)
with self.client: with self.client:
self.client.set_expected_responses([ self.client.set_expected_responses([
@ -109,5 +114,6 @@ class TestOpReturn(common.TrezorTest):
]) ])
self.assertRaises(CallException, self.client.sign_tx, 'Bitcoin', [inp1, ], [out1, ]) self.assertRaises(CallException, self.client.sign_tx, 'Bitcoin', [inp1, ], [out1, ])
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -23,19 +23,21 @@ import unittest
import common import common
from trezorlib import messages_pb2 as proto from trezorlib import messages_pb2 as proto
from trezorlib import types_pb2 as types from trezorlib.client import PinException
from trezorlib.client import PinException, CallException
# FIXME TODO Add passphrase tests # FIXME TODO Add passphrase tests
class TestProtectCall(common.TrezorTest): class TestProtectCall(common.TrezorTest):
def _some_protected_call(self, button, pin, passphrase): def _some_protected_call(self, button, pin, passphrase):
# This method perform any call which have protection in the device # This method perform any call which have protection in the device
res = self.client.ping('random data', res = self.client.ping(
button_protection=button, 'random data',
pin_protection=pin, button_protection=button,
passphrase_protection=passphrase) pin_protection=pin,
passphrase_protection=passphrase
)
self.assertEqual(res, 'random data') self.assertEqual(res, 'random data')
""" """
@ -131,5 +133,6 @@ class TestProtectCall(common.TrezorTest):
self.assertRaises(PinException, self._some_protected_call, False, True, False) self.assertRaises(PinException, self._some_protected_call, False, True, False)
test_backoff(attempt, start) test_backoff(attempt, start)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -38,61 +38,75 @@ class TestProtectionLevels(common.TrezorTest):
def test_apply_settings(self): def test_apply_settings(self):
with self.client: with self.client:
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.PinMatrixRequest(), self.client.set_expected_responses([
proto.ButtonRequest(), proto.PinMatrixRequest(),
proto.Success(), proto.ButtonRequest(),
proto.Features()]) # TrezorClient reinitializes device proto.Success(),
proto.Features()
]) # TrezorClient reinitializes device
self.client.apply_settings(label='nazdar') self.client.apply_settings(label='nazdar')
def test_change_pin(self): def test_change_pin(self):
with self.client: with self.client:
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.ButtonRequest(), self.client.set_expected_responses([
proto.PinMatrixRequest(), proto.ButtonRequest(),
proto.PinMatrixRequest(), proto.PinMatrixRequest(),
proto.PinMatrixRequest(), proto.PinMatrixRequest(),
proto.Success(), proto.PinMatrixRequest(),
proto.Features()]) proto.Success(),
proto.Features()
])
self.client.change_pin() self.client.change_pin()
def test_ping(self): def test_ping(self):
with self.client: with self.client:
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.ButtonRequest(), self.client.set_expected_responses([
proto.PinMatrixRequest(), proto.ButtonRequest(),
proto.PassphraseRequest(), proto.PinMatrixRequest(),
proto.Success()]) proto.PassphraseRequest(),
proto.Success()
])
self.client.ping('msg', True, True, True) self.client.ping('msg', True, True, True)
def test_get_entropy(self): def test_get_entropy(self):
with self.client: with self.client:
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.ButtonRequest(), self.client.set_expected_responses([
proto.Entropy()]) proto.ButtonRequest(),
proto.Entropy()
])
self.client.get_entropy(10) self.client.get_entropy(10)
def test_get_public_key(self): def test_get_public_key(self):
with self.client: with self.client:
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.PinMatrixRequest(), self.client.set_expected_responses([
proto.PassphraseRequest(), proto.PinMatrixRequest(),
proto.PublicKey()]) proto.PassphraseRequest(),
proto.PublicKey()
])
self.client.get_public_node([]) self.client.get_public_node([])
def test_get_address(self): def test_get_address(self):
with self.client: with self.client:
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.PinMatrixRequest(), self.client.set_expected_responses([
proto.PassphraseRequest(), proto.PinMatrixRequest(),
proto.Address()]) proto.PassphraseRequest(),
proto.Address()
])
self.client.get_address('Bitcoin', []) self.client.get_address('Bitcoin', [])
def test_wipe_device(self): def test_wipe_device(self):
with self.client: with self.client:
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.ButtonRequest(), self.client.set_expected_responses([
proto.Success(), proto.ButtonRequest(),
proto.Features()]) proto.Success(),
proto.Features()
])
self.client.wipe_device() self.client.wipe_device()
def test_load_device(self): def test_load_device(self):
@ -108,10 +122,7 @@ class TestProtectionLevels(common.TrezorTest):
def test_reset_device(self): def test_reset_device(self):
with self.client: with self.client:
self.client.set_expected_responses([proto.EntropyRequest()] + \ self.client.set_expected_responses([proto.EntropyRequest()] + [proto.ButtonRequest()] * 24 + [proto.Success(), proto.Features()])
[proto.ButtonRequest()] * 24 + \
[proto.Success(),
proto.Features()])
self.client.reset_device(False, 128, True, False, 'label', 'english') self.client.reset_device(False, 128, True, False, 'label', 'english')
# This must fail, because device is already initialized # This must fail, because device is already initialized
@ -120,9 +131,7 @@ class TestProtectionLevels(common.TrezorTest):
def test_recovery_device(self): def test_recovery_device(self):
with self.client: with self.client:
self.client.set_mnemonic(self.mnemonic12) self.client.set_mnemonic(self.mnemonic12)
self.client.set_expected_responses([proto.WordRequest()] * 24 + \ self.client.set_expected_responses([proto.WordRequest()] * 24 + [proto.Success(), proto.Features()])
[proto.Success(),
proto.Features()])
self.client.recovery_device(12, False, False, 'label', 'english') self.client.recovery_device(12, False, False, 'label', 'english')
# This must fail, because device is already initialized # This must fail, because device is already initialized
@ -131,16 +140,18 @@ class TestProtectionLevels(common.TrezorTest):
def test_sign_message(self): def test_sign_message(self):
with self.client: with self.client:
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.ButtonRequest(), self.client.set_expected_responses([
proto.PinMatrixRequest(), proto.ButtonRequest(),
proto.PassphraseRequest(), proto.PinMatrixRequest(),
proto.MessageSignature()]) proto.PassphraseRequest(),
proto.MessageSignature()
])
self.client.sign_message('Bitcoin', [], 'testing message') self.client.sign_message('Bitcoin', [], 'testing message')
def test_verify_message(self): def test_verify_message(self):
with self.client: with self.client:
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.ButtonRequest(),proto.Success()]) self.client.set_expected_responses([proto.ButtonRequest(), proto.Success()])
self.client.verify_message( self.client.verify_message(
'Bitcoin', 'Bitcoin',
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e', '14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',
@ -179,15 +190,17 @@ class TestProtectionLevels(common.TrezorTest):
def test_signtx(self): def test_signtx(self):
self.setup_mnemonic_pin_passphrase() self.setup_mnemonic_pin_passphrase()
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
prev_hash=TXHASH_d5f65e, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_index=0, prev_hash=TXHASH_d5f65e,
) prev_index=0,
)
out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', out1 = proto_types.TxOutputType(
amount=390000 - 10000, address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
script_type=proto_types.PAYTOADDRESS, amount=390000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
with self.client: with self.client:
@ -215,5 +228,6 @@ class TestProtectionLevels(common.TrezorTest):
# def test_firmware_upload(self): # def test_firmware_upload(self):
# pass # pass
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -19,18 +19,18 @@
from __future__ import print_function from __future__ import print_function
import unittest import unittest
import common
import binascii import binascii
import sys import sys
import common
import trezorlib.messages_pb2 as proto
import trezorlib.types_pb2 as proto_types import trezorlib.types_pb2 as proto_types
if sys.version_info < (3,): if sys.version_info < (3,):
def byteindex(data, index): def byteindex(data, index):
return ord(data[index]) return ord(data[index])
else: else:
byteindex = lambda data, index: data[index] def byteindex(data, index):
return data[index]
TXHASH_d5f65e = binascii.unhexlify(b'd5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882') TXHASH_d5f65e = binascii.unhexlify(b'd5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')
@ -74,17 +74,19 @@ class TestZeroSig(common.TrezorTest):
def test_one_zero_signature(self): def test_one_zero_signature(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=390000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=TXHASH_d5f65e, # amount=390000,
prev_index=0, prev_hash=TXHASH_d5f65e,
) prev_index=0,
)
# Following address_n has been mined by 'test_mine_zero_signature' # Following address_n has been mined by 'test_mine_zero_signature'
out1 = proto_types.TxOutputType(address_n=[177], out1 = proto_types.TxOutputType(
amount=390000 - 10000, address_n=[177],
script_type=proto_types.PAYTOADDRESS, amount=390000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
(signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])
siglen = byteindex(serialized_tx, 44) siglen = byteindex(serialized_tx, 44)
@ -95,17 +97,19 @@ class TestZeroSig(common.TrezorTest):
def test_two_zero_signature(self): def test_two_zero_signature(self):
self.setup_mnemonic_nopin_nopassphrase() self.setup_mnemonic_nopin_nopassphrase()
inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e inp1 = proto_types.TxInputType(
# amount=390000, address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
prev_hash=TXHASH_d5f65e, # amount=390000,
prev_index=0, prev_hash=TXHASH_d5f65e,
) prev_index=0,
)
# Following address_n has been mined by 'test_mine_zero_signature' # Following address_n has been mined by 'test_mine_zero_signature'
out1 = proto_types.TxOutputType(address_n=[16518], out1 = proto_types.TxOutputType(
amount=390000 - 10000, address_n=[16518],
script_type=proto_types.PAYTOADDRESS, amount=390000 - 10000,
) script_type=proto_types.PAYTOADDRESS,
)
(signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])
siglen = byteindex(serialized_tx, 44) siglen = byteindex(serialized_tx, 44)
@ -113,5 +117,6 @@ class TestZeroSig(common.TrezorTest):
# TREZOR must strip leading zero from signature # TREZOR must strip leading zero from signature
self.assertEqual(siglen, 66) self.assertEqual(siglen, 66)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -19,7 +19,7 @@
import common import common
import unittest import unittest
from trezorlib.protobuf_json import json2pb, pb2json from trezorlib.protobuf_json import pb2json
import trezorlib.messages_pb2 as msg import trezorlib.messages_pb2 as msg
@ -29,7 +29,7 @@ class TestProtobufJson(unittest.TestCase):
m = msg.Features() m = msg.Features()
m.device_id = '1234' m.device_id = '1234'
j = pb2json(m) j = pb2json(m)
self.assertEqual(j, {'device_id': u'1234'} ) self.assertEqual(j, {'device_id': u'1234'})
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -25,20 +25,20 @@ from trezorlib.tx_api import TxApiBitcoin, TxApiTestnet
class TestTxApi(unittest.TestCase): class TestTxApi(unittest.TestCase):
def test_get(self): def test_get(self):
tx = TxApiBitcoin.get_tx('39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5') TxApiBitcoin.get_tx('39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5')
tx = TxApiBitcoin.get_tx('54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3') TxApiBitcoin.get_tx('54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3')
tx = TxApiBitcoin.get_tx('58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e') TxApiBitcoin.get_tx('58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e')
tx = TxApiBitcoin.get_tx('6189e3febb5a21cee8b725aa1ef04ffce7e609448446d3a8d6f483c634ef5315') TxApiBitcoin.get_tx('6189e3febb5a21cee8b725aa1ef04ffce7e609448446d3a8d6f483c634ef5315')
tx = TxApiBitcoin.get_tx('a6e2829d089cee47e481b1a753a53081b40738cc87e38f1d9b23ab57d9ad4396') TxApiBitcoin.get_tx('a6e2829d089cee47e481b1a753a53081b40738cc87e38f1d9b23ab57d9ad4396')
tx = TxApiBitcoin.get_tx('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52') TxApiBitcoin.get_tx('c6091adf4c0c23982a35899a6e58ae11e703eacd7954f588ed4b9cdefc4dba52')
tx = TxApiBitcoin.get_tx('c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb') TxApiBitcoin.get_tx('c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb')
tx = TxApiBitcoin.get_tx('c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c') TxApiBitcoin.get_tx('c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c')
tx = TxApiBitcoin.get_tx('d1d08ea63255af4ad16b098e9885a252632086fa6be53301521d05253ce8a73d') TxApiBitcoin.get_tx('d1d08ea63255af4ad16b098e9885a252632086fa6be53301521d05253ce8a73d')
tx = TxApiBitcoin.get_tx('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882') TxApiBitcoin.get_tx('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')
tx = TxApiBitcoin.get_tx('e4bc1ae5e5007a08f2b3926fe11c66612e8f73c6b00c69c7027213b84d259be3') TxApiBitcoin.get_tx('e4bc1ae5e5007a08f2b3926fe11c66612e8f73c6b00c69c7027213b84d259be3')
tx = TxApiTestnet.get_tx('6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54') TxApiTestnet.get_tx('6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54')
tx = TxApiTestnet.get_tx('d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236') TxApiTestnet.get_tx('d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236')
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -15,7 +15,7 @@ import json
import hashlib import hashlib
import binascii import binascii
from trezorlib.client import TrezorClient, TrezorClientDebug from trezorlib.client import TrezorClient
from trezorlib.transport_hid import HidTransport from trezorlib.transport_hid import HidTransport
# Python2 vs Python3 # Python2 vs Python3
@ -24,6 +24,7 @@ try:
except NameError: except NameError:
pass pass
def wait_for_devices(): def wait_for_devices():
devices = HidTransport.enumerate() devices = HidTransport.enumerate()
while not len(devices): while not len(devices):
@ -33,6 +34,7 @@ def wait_for_devices():
return devices return devices
def choose_device(devices): def choose_device(devices):
if not len(devices): if not len(devices):
raise Exception("No TREZOR connected!") raise Exception("No TREZOR connected!")
@ -71,9 +73,10 @@ def choose_device(devices):
except: except:
raise Exception("Invalid choice, exiting...") raise Exception("Invalid choice, exiting...")
def main(): def main():
if not 'encfs_root' in os.environ: if 'encfs_root' not in os.environ:
sys.stderr.write('\nThis is not a standalone script and is not meant to be run independently.\n') sys.stderr.write('\nThis is not a standalone script and is not meant to be run independently.\n')
sys.stderr.write('\nUsage: encfs --standard --extpass=./encfs_aes_getpass.py ~/.crypt ~/crypt\n') sys.stderr.write('\nUsage: encfs --standard --extpass=./encfs_aes_getpass.py ~/.crypt ~/crypt\n')
sys.exit(1) sys.exit(1)
@ -122,5 +125,6 @@ def main():
print(passw) print(passw)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -4,6 +4,7 @@ from __future__ import print_function
from trezorlib.client import TrezorClient from trezorlib.client import TrezorClient
from trezorlib.transport_hid import HidTransport from trezorlib.transport_hid import HidTransport
def main(): def main():
# List all connected TREZORs on USB # List all connected TREZORs on USB
devices = HidTransport.enumerate() devices = HidTransport.enumerate()
@ -30,5 +31,6 @@ def main():
client.close() client.close()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -2,9 +2,8 @@
from __future__ import print_function from __future__ import print_function
from trezorlib.debuglink import DebugLink from trezorlib.debuglink import DebugLink
from trezorlib.client import TrezorClient, TrezorDebugClient from trezorlib.client import TrezorClient
from trezorlib.transport_hid import HidTransport from trezorlib.transport_hid import HidTransport
import binascii
import sys import sys
# usage examples # usage examples
@ -15,6 +14,7 @@ import sys
# note that in order for this to work, your trezor device must # note that in order for this to work, your trezor device must
# be running a firmware that was built with debug link enabled # be running a firmware that was built with debug link enabled
def main(): def main():
# List all connected TREZORs on USB # List all connected TREZORs on USB
devices = HidTransport.enumerate() devices = HidTransport.enumerate()
@ -39,12 +39,13 @@ def main():
f = open('memory.dat', 'w') f = open('memory.dat', 'w')
for addr in range(arg1, arg1 + arg2, step): for addr in range(arg1, arg1 + arg2, step):
mem = debug.memory_read(addr, step) mem = debug.memory_read(addr, step)
f.write(mem) f.write(mem)
f.close() f.close()
client.close() client.close()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -2,11 +2,12 @@
from __future__ import print_function from __future__ import print_function
from trezorlib.debuglink import DebugLink from trezorlib.debuglink import DebugLink
from trezorlib.client import TrezorClient, TrezorDebugClient from trezorlib.client import TrezorClient
from trezorlib.transport_hid import HidTransport from trezorlib.transport_hid import HidTransport
import binascii import binascii
import sys import sys
def main(): def main():
# List all connected TREZORs on USB # List all connected TREZORs on USB
devices = HidTransport.enumerate() devices = HidTransport.enumerate()
@ -24,8 +25,9 @@ def main():
client = TrezorClient(transport) client = TrezorClient(transport)
debug = DebugLink(debug_transport) debug = DebugLink(debug_transport)
mem = debug.memory_write(int(sys.argv[1],16), binascii.unhexlify(sys.argv[2]), flash=True) debug.memory_write(int(sys.argv[1], 16), binascii.unhexlify(sys.argv[2]), flash=True)
client.close() client.close()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -22,6 +22,7 @@ try:
except NameError: except NameError:
pass pass
def generate_entropy(strength, internal_entropy, external_entropy): def generate_entropy(strength, internal_entropy, external_entropy):
''' '''
strength - length of produced seed. One of 128, 192, 256 strength - length of produced seed. One of 128, 192, 256
@ -50,6 +51,7 @@ def generate_entropy(strength, internal_entropy, external_entropy):
return entropy_stripped return entropy_stripped
def main(): def main():
print(__doc__) print(__doc__)
@ -72,5 +74,6 @@ def main():
print("Generated mnemonic is:", words) print("Generated mnemonic is:", words)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -5,18 +5,19 @@
# push confirmation # push confirmation
from __future__ import print_function from __future__ import print_function
import binascii
import io import io
import sys import sys
from trezorlib.client import TrezorClient from trezorlib.client import TrezorClient
from trezorlib.transport_hid import HidTransport from trezorlib.transport_hid import HidTransport
def get_client(): def get_client():
devices = HidTransport.enumerate() # List all connected TREZORs on USB devices = HidTransport.enumerate() # list all connected TREZORs on USB
if len(devices) == 0: # Check whether we found any if len(devices) == 0: # check whether we found any
return None return None
transport = HidTransport(devices[0]) # Use first connected device transport = HidTransport(devices[0]) # use first connected device
return TrezorClient(transport) # Creates object for communicating with TREZOR return TrezorClient(transport) # creates object for communicating with TREZOR
def main(): def main():
client = get_client() client = get_client()
@ -24,9 +25,9 @@ def main():
print('No TREZOR connected') print('No TREZOR connected')
return return
arg1 = sys.argv[1] # output file arg1 = sys.argv[1] # output file
arg2 = int(sys.argv[2], 10) # total number of how many bytes of entropy to read arg2 = int(sys.argv[2], 10) # total number of how many bytes of entropy to read
step = 1024 if arg2 >= 1024 else arg2 # trezor will only return 1KB at a time step = 1024 if arg2 >= 1024 else arg2 # trezor will only return 1KB at a time
with io.open(arg1, 'wb') as f: with io.open(arg1, 'wb') as f:
for i in xrange(0, arg2, step): for i in xrange(0, arg2, step):
@ -35,5 +36,6 @@ def main():
client.close() client.close()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -20,20 +20,26 @@ from __future__ import print_function
import binascii import binascii
from trezorlib.client import TrezorClient from trezorlib.client import TrezorClient
from trezorlib.transport_hid import HidTransport from trezorlib.transport_hid import HidTransport
from trezorlib.tx_api import * from trezorlib.tx_api import TxApiBitcoin, TxApiTestnet, TxApiLitecoin
from trezorlib import types_pb2 as types from trezorlib import types_pb2 as types
# Python2 vs Python3
try:
input = raw_input
except NameError:
pass
def get_client(): def get_client():
devices = HidTransport.enumerate() # List all connected TREZORs on USB devices = HidTransport.enumerate() # list all connected TREZORs on USB
if len(devices) == 0: # Check whether we found any if len(devices) == 0: # check whether we found any
return None return None
transport = HidTransport(devices[0]) # Use first connected device transport = HidTransport(devices[0]) # use first connected device
return TrezorClient(transport) # Creates object for communicating with TREZOR return TrezorClient(transport) # creates object for communicating with TREZOR
def get_txapi(): def get_txapi():
coin = raw_input('Which coin {Bitcoin, Testnet, Litecoin}? ').strip() coin = input('Which coin {Bitcoin, Testnet, Litecoin}? ').strip()
if coin not in {'Bitcoin', 'Testnet', 'Litecoin'}: if coin not in {'Bitcoin', 'Testnet', 'Litecoin'}:
return None, None return None, None
txapi_lookup = { txapi_lookup = {
@ -66,29 +72,29 @@ def main():
while True: while True:
print() print()
prev_in_hash = raw_input('Previous input hash (empty to move on): ').strip() prev_in_hash = input('Previous input hash (empty to move on): ').strip()
if prev_in_hash == '': if prev_in_hash == '':
break break
prev_in_vout = raw_input('Previous input index: ').strip() prev_in_vout = input('Previous input index: ').strip()
addrn = raw_input("Node path to sign with (e.g.- %s/0'/0/0): " % coin).strip() addrn = input("Node path to sign with (e.g.- %s/0'/0/0): " % coin).strip()
inputs.append(types.TxInputType( inputs.append(types.TxInputType(
prev_hash = binascii.unhexlify(prev_in_hash), prev_hash=binascii.unhexlify(prev_in_hash),
prev_index = int(prev_in_vout, 10), prev_index=int(prev_in_vout, 10),
address_n = client.expand_path(addrn) address_n=client.expand_path(addrn)
)) ))
outputs = [] outputs = []
while True: while True:
print() print()
out_addr = raw_input('Pay to address (empty to move on): ').strip() out_addr = input('Pay to address (empty to move on): ').strip()
if out_addr == '': if out_addr == '':
break break
out_amount = raw_input('Amount (in satoshis): ').strip() out_amount = input('Amount (in satoshis): ').strip()
outputs.append(types.TxOutputType( outputs.append(types.TxOutputType(
amount = int(out_amount, 10), amount=int(out_amount, 10),
script_type = types.PAYTOADDRESS, script_type=types.PAYTOADDRESS,
address = out_addr address=out_addr
)) ))
(signatures, serialized_tx) = client.sign_tx(coin, inputs, outputs) (signatures, serialized_tx) = client.sign_tx(coin, inputs, outputs)

View File

@ -10,4 +10,4 @@ deps =
-rrequirements.txt -rrequirements.txt
commands = commands =
python -m compileall trezorlib/ python -m compileall trezorlib/
python trezorctl python trezorctl --help

View File

@ -36,7 +36,8 @@ if sys.version_info < (3,):
def byteindex(data, index): def byteindex(data, index):
return ord(data[index]) return ord(data[index])
else: else:
byteindex = lambda data, index: data[index] def byteindex(data, index):
return data[index]
def point_to_pubkey(point): def point_to_pubkey(point):
@ -46,6 +47,7 @@ def point_to_pubkey(point):
vk = x_str + y_str vk = x_str + y_str
return struct.pack('B', (byteindex(vk, 63) & 1) + 2) + vk[0:32] # To compressed key return struct.pack('B', (byteindex(vk, 63) & 1) + 2) + vk[0:32] # To compressed key
def sec_to_public_pair(pubkey): def sec_to_public_pair(pubkey):
"""Convert a public key in sec binary format to a public pair.""" """Convert a public key in sec binary format to a public pair."""
x = string_to_number(pubkey[1:33]) x = string_to_number(pubkey[1:33])
@ -64,15 +66,19 @@ def sec_to_public_pair(pubkey):
return public_pair_for_x(ecdsa.ecdsa.generator_secp256k1, x, is_even=(sec0 == b'\2')) return public_pair_for_x(ecdsa.ecdsa.generator_secp256k1, x, is_even=(sec0 == b'\2'))
def is_prime(n): def is_prime(n):
return (bool)(n & PRIME_DERIVATION_FLAG) return (bool)(n & PRIME_DERIVATION_FLAG)
def fingerprint(pubkey): def fingerprint(pubkey):
return string_to_number(tools.hash_160(pubkey)[:4]) return string_to_number(tools.hash_160(pubkey)[:4])
def get_address(public_node, address_type): def get_address(public_node, address_type):
return tools.public_key_to_bc_address(public_node.public_key, address_type) return tools.public_key_to_bc_address(public_node.public_key, address_type)
def public_ckd(public_node, n): def public_ckd(public_node, n):
if not isinstance(n, list): if not isinstance(n, list):
raise Exception('Parameter must be a list') raise Exception('Parameter must be a list')
@ -85,6 +91,7 @@ def public_ckd(public_node, n):
return node return node
def get_subnode(node, i): def get_subnode(node, i):
# Public Child key derivation (CKD) algorithm of BIP32 # Public Child key derivation (CKD) algorithm of BIP32
i_as_bytes = struct.pack(">L", i) i_as_bytes = struct.pack(">L", i)
@ -106,8 +113,7 @@ def get_subnode(node, i):
# BIP32 magic converts old public key to new public point # BIP32 magic converts old public key to new public point
x, y = sec_to_public_pair(node.public_key) x, y = sec_to_public_pair(node.public_key)
point = I_left_as_exponent * SECP256k1.generator + \ point = I_left_as_exponent * SECP256k1.generator + Point(SECP256k1.curve, x, y, SECP256k1.order)
Point(SECP256k1.curve, x, y, SECP256k1.order)
if point == INFINITY: if point == INFINITY:
raise Exception("Point cannot be INFINITY") raise Exception("Point cannot be INFINITY")
@ -117,6 +123,7 @@ def get_subnode(node, i):
return node_out return node_out
def serialize(node, version=0x0488B21E): def serialize(node, version=0x0488B21E):
s = b'' s = b''
s += struct.pack('>I', version) s += struct.pack('>I', version)
@ -131,6 +138,7 @@ def serialize(node, version=0x0488B21E):
s += tools.Hash(s)[:4] s += tools.Hash(s)[:4]
return tools.b58encode(s) return tools.b58encode(s)
def deserialize(xpub): def deserialize(xpub):
data = tools.b58decode(xpub, None) data = tools.b58decode(xpub, None)

View File

@ -25,17 +25,24 @@ import time
import binascii import binascii
import hashlib import hashlib
import unicodedata import unicodedata
import json # import json
import getpass import getpass
from mnemonic import Mnemonic from mnemonic import Mnemonic
from . import tools from . import tools
from . import mapping # from . import mapping
from . import messages_pb2 as proto from . import messages_pb2 as proto
from . import types_pb2 as types from . import types_pb2 as types
from .debuglink import DebugLink from .debuglink import DebugLink
# Python2 vs Python3
try:
input = raw_input
except NameError:
pass
# try: # try:
# from PIL import Image # from PIL import Image
# SCREENSHOT = True # SCREENSHOT = True
@ -59,7 +66,9 @@ def getch():
return msvcrt.getch() return msvcrt.getch()
# POSIX system. Create and return a getch that manipulates the tty. # POSIX system. Create and return a getch that manipulates the tty.
import sys, tty import sys
import tty
def _getch(): def _getch():
fd = sys.stdin.fileno() fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd) old_settings = termios.tcgetattr(fd)
@ -72,9 +81,11 @@ def getch():
return _getch() return _getch()
def get_buttonrequest_value(code): def get_buttonrequest_value(code):
# Converts integer code to its string representation of ButtonRequestType # Converts integer code to its string representation of ButtonRequestType
return [ k for k, v in types.ButtonRequestType.items() if v == code][0] return [k for k, v in types.ButtonRequestType.items() if v == code][0]
def pprint(msg): def pprint(msg):
msg_class = msg.__class__.__name__ msg_class = msg.__class__.__name__
@ -89,19 +100,23 @@ def pprint(msg):
else: else:
return "<%s> (%d bytes):\n%s" % (msg_class, msg_size, msg) return "<%s> (%d bytes):\n%s" % (msg_class, msg_size, msg)
def log(msg): def log(msg):
sys.stderr.write(str(msg)) sys.stderr.write(str(msg))
sys.stderr.write('\n') sys.stderr.write('\n')
sys.stderr.flush() sys.stderr.flush()
class CallException(Exception): class CallException(Exception):
def __init__(self, code, message): def __init__(self, code, message):
super(CallException, self).__init__() super(CallException, self).__init__()
self.args = [code, message] self.args = [code, message]
class PinException(CallException): class PinException(CallException):
pass pass
class field(object): class field(object):
# Decorator extracts single value from # Decorator extracts single value from
# protobuf object. If the field is not # protobuf object. If the field is not
@ -116,6 +131,7 @@ class field(object):
return getattr(ret, self.field) return getattr(ret, self.field)
return wrapped_f return wrapped_f
class expect(object): class expect(object):
# Decorator checks if the method # Decorator checks if the method
# returned one of expected protobuf messages # returned one of expected protobuf messages
@ -131,6 +147,7 @@ class expect(object):
return ret return ret
return wrapped_f return wrapped_f
def session(f): def session(f):
# Decorator wraps a BaseClient method # Decorator wraps a BaseClient method
# with session activation / deactivation # with session activation / deactivation
@ -143,6 +160,7 @@ def session(f):
client.transport.session_end() client.transport.session_end()
return wrapped_f return wrapped_f
def normalize_nfc(txt): def normalize_nfc(txt):
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
if isinstance(txt, unicode): if isinstance(txt, unicode):
@ -157,6 +175,7 @@ def normalize_nfc(txt):
raise Exception('unicode/str or bytes/str expected') raise Exception('unicode/str or bytes/str expected')
class BaseClient(object): class BaseClient(object):
# Implements very basic layer of sending raw protobuf # Implements very basic layer of sending raw protobuf
# messages to device and getting its response back. # messages to device and getting its response back.
@ -178,9 +197,9 @@ class BaseClient(object):
handler_name = "callback_%s" % resp.__class__.__name__ handler_name = "callback_%s" % resp.__class__.__name__
handler = getattr(self, handler_name, None) handler = getattr(self, handler_name, None)
if handler != None: if handler is not None:
msg = handler(resp) msg = handler(resp)
if msg == None: if msg is None:
raise Exception("Callback %s must return protobuf message, not None" % handler) raise Exception("Callback %s must return protobuf message, not None" % handler)
resp = self.call(msg) resp = self.call(msg)
@ -188,7 +207,7 @@ class BaseClient(object):
def callback_Failure(self, msg): def callback_Failure(self, msg):
if msg.code in (types.Failure_PinInvalid, if msg.code in (types.Failure_PinInvalid,
types.Failure_PinCancelled, types.Failure_PinExpected): types.Failure_PinCancelled, types.Failure_PinExpected):
raise PinException(msg.code, msg.message) raise PinException(msg.code, msg.message)
raise CallException(msg.code, msg.message) raise CallException(msg.code, msg.message)
@ -196,6 +215,7 @@ class BaseClient(object):
def close(self): def close(self):
self.transport.close() self.transport.close()
class DebugWireMixin(object): class DebugWireMixin(object):
def call_raw(self, msg): def call_raw(self, msg):
log("SENDING " + pprint(msg)) log("SENDING " + pprint(msg))
@ -203,6 +223,7 @@ class DebugWireMixin(object):
log("RECEIVED " + pprint(resp)) log("RECEIVED " + pprint(resp))
return resp return resp
class TextUIMixin(object): class TextUIMixin(object):
# This class demonstrates easy test-based UI # This class demonstrates easy test-based UI
# integration between the device and wallet. # integration between the device and wallet.
@ -233,8 +254,7 @@ class TextUIMixin(object):
return proto.WordAck(word='\x08') return proto.WordAck(word='\x08')
# ignore middle column if only 6 keys requested. # ignore middle column if only 6 keys requested.
if (msg.type == types.WordRequestType_Matrix6 and if (isinstance(msg.type, types.WordRequestType_Matrix6) and character in ('2', '5', '8')):
character in ('2', '5', '8')):
continue continue
if (ord(character) >= ord('1') and ord(character) <= ord('9')): if (ord(character) >= ord('1') and ord(character) <= ord('9')):
@ -274,14 +294,12 @@ class TextUIMixin(object):
types.WordRequestType_Matrix6): types.WordRequestType_Matrix6):
return self.callback_RecoveryMatrix(msg) return self.callback_RecoveryMatrix(msg)
log("Enter one word of mnemonic: ") log("Enter one word of mnemonic: ")
try: word = input()
word = raw_input()
except NameError:
word = input() # Python 3
if self.expand: if self.expand:
word = self.mnemonic_wordlist.expand_word(word) word = self.mnemonic_wordlist.expand_word(word)
return proto.WordAck(word=word) return proto.WordAck(word=word)
class DebugLinkMixin(object): class DebugLinkMixin(object):
# This class implements automatic responses # This class implements automatic responses
# and other functionality for unit tests # and other functionality for unit tests
@ -328,15 +346,15 @@ class DebugLinkMixin(object):
def __exit__(self, _type, value, traceback): def __exit__(self, _type, value, traceback):
self.in_with_statement -= 1 self.in_with_statement -= 1
if _type != None: if _type is not None:
# Another exception raised # Another exception raised
return False return False
# return isinstance(value, TypeError) # return isinstance(value, TypeError)
# Evaluate missed responses in 'with' statement # Evaluate missed responses in 'with' statement
if self.expected_responses != None and len(self.expected_responses): if self.expected_responses is not None and len(self.expected_responses):
raise Exception("Some of expected responses didn't come from device: %s" % \ raise Exception("Some of expected responses didn't come from device: %s" %
[ pprint(x) for x in self.expected_responses ]) [pprint(x) for x in self.expected_responses])
# Cleanup # Cleanup
self.expected_responses = None self.expected_responses = None
@ -376,22 +394,22 @@ class DebugLinkMixin(object):
return resp return resp
def _check_request(self, msg): def _check_request(self, msg):
if self.expected_responses != None: if self.expected_responses is not None:
try: try:
expected = self.expected_responses.pop(0) expected = self.expected_responses.pop(0)
except IndexError: except IndexError:
raise CallException(types.Failure_UnexpectedMessage, raise CallException(types.Failure_UnexpectedMessage,
"Got %s, but no message has been expected" % pprint(msg)) "Got %s, but no message has been expected" % pprint(msg))
if msg.__class__ != expected.__class__: if msg.__class__ != expected.__class__:
raise CallException(types.Failure_UnexpectedMessage, raise CallException(types.Failure_UnexpectedMessage,
"Expected %s, got %s" % (pprint(expected), pprint(msg))) "Expected %s, got %s" % (pprint(expected), pprint(msg)))
fields = expected.ListFields() # only filled (including extensions) fields = expected.ListFields() # only filled (including extensions)
for field, value in fields: for field, value in fields:
if not msg.HasField(field.name) or getattr(msg, field.name) != value: if not msg.HasField(field.name) or getattr(msg, field.name) != value:
raise CallException(types.Failure_UnexpectedMessage, raise CallException(types.Failure_UnexpectedMessage,
"Expected %s, got %s" % (pprint(expected), pprint(msg))) "Expected %s, got %s" % (pprint(expected), pprint(msg)))
def callback_ButtonRequest(self, msg): def callback_ButtonRequest(self, msg):
log("ButtonRequest code: " + get_buttonrequest_value(msg.code)) log("ButtonRequest code: " + get_buttonrequest_value(msg.code))
@ -423,6 +441,7 @@ class DebugLinkMixin(object):
raise Exception("Unexpected call") raise Exception("Unexpected call")
class ProtocolMixin(object): class ProtocolMixin(object):
PRIME_DERIVATION_FLAG = 0x80000000 PRIME_DERIVATION_FLAG = 0x80000000
VENDORS = ('bitcointrezor.com', 'trezor.io') VENDORS = ('bitcointrezor.com', 'trezor.io')
@ -445,7 +464,7 @@ class ProtocolMixin(object):
def _convert_prime(self, n): def _convert_prime(self, n):
# Convert minus signs to uint32 with flag # Convert minus signs to uint32 with flag
return [ int(abs(x) | self.PRIME_DERIVATION_FLAG) if x < 0 else x for x in n ] return [int(abs(x) | self.PRIME_DERIVATION_FLAG) if x < 0 else x for x in n]
@staticmethod @staticmethod
def expand_path(n): def expand_path(n):
@ -474,7 +493,7 @@ class ProtocolMixin(object):
"Decred": 42 "Decred": 42
} }
if n[0] in coins: if n[0] in coins:
n = ["44'", "%d'" % coins[n[0]] ] + n[1:] n = ["44'", "%d'" % coins[n[0]]] + n[1:]
path = [] path = []
for x in n: for x in n:
@ -498,7 +517,7 @@ class ProtocolMixin(object):
def get_public_node(self, n, ecdsa_curve_name=DEFAULT_CURVE, show_display=False, coin_name=None): def get_public_node(self, n, ecdsa_curve_name=DEFAULT_CURVE, show_display=False, coin_name=None):
n = self._convert_prime(n) n = self._convert_prime(n)
if not ecdsa_curve_name: if not ecdsa_curve_name:
ecdsa_curve_name=DEFAULT_CURVE ecdsa_curve_name = DEFAULT_CURVE
return self.call(proto.GetPublicKey(address_n=n, ecdsa_curve_name=ecdsa_curve_name, show_display=show_display, coin_name=coin_name)) return self.call(proto.GetPublicKey(address_n=n, ecdsa_curve_name=ecdsa_curve_name, show_display=show_display, coin_name=coin_name))
@field('address') @field('address')
@ -553,7 +572,6 @@ class ProtocolMixin(object):
return response.signature_v, response.signature_r, response.signature_s return response.signature_v, response.signature_r, response.signature_s
@field('entropy') @field('entropy')
@expect(proto.Entropy) @expect(proto.Entropy)
def get_entropy(self, size): def get_entropy(self, size):
@ -575,13 +593,13 @@ class ProtocolMixin(object):
@expect(proto.Success) @expect(proto.Success)
def apply_settings(self, label=None, language=None, use_passphrase=None, homescreen=None): def apply_settings(self, label=None, language=None, use_passphrase=None, homescreen=None):
settings = proto.ApplySettings() settings = proto.ApplySettings()
if label != None: if label is not None:
settings.label = label settings.label = label
if language: if language:
settings.language = language settings.language = language
if use_passphrase != None: if use_passphrase is not None:
settings.use_passphrase = use_passphrase settings.use_passphrase = use_passphrase
if homescreen != None: if homescreen is not None:
settings.homescreen = homescreen settings.homescreen = homescreen
out = self.call(settings) out = self.call(settings)
@ -618,7 +636,7 @@ class ProtocolMixin(object):
@field('message') @field('message')
@expect(proto.Success) @expect(proto.Success)
def set_u2f_counter(self, u2f_counter): def set_u2f_counter(self, u2f_counter):
ret = self.call(proto.SetU2FCounter(u2f_counter = u2f_counter)) ret = self.call(proto.SetU2FCounter(u2f_counter=u2f_counter))
return ret return ret
def verify_message(self, coin_name, address, signature, message): def verify_message(self, coin_name, address, signature, message):
@ -760,7 +778,7 @@ class ProtocolMixin(object):
serialized_tx += res.serialized.serialized_tx serialized_tx += res.serialized.serialized_tx
if res.HasField('serialized') and res.serialized.HasField('signature_index'): if res.HasField('serialized') and res.serialized.HasField('signature_index'):
if signatures[res.serialized.signature_index] != None: if signatures[res.serialized.signature_index] is not None:
raise Exception("Signature for index %d already filled" % res.serialized.signature_index) raise Exception("Signature for index %d already filled" % res.serialized.signature_index)
signatures[res.serialized.signature_index] = res.serialized.signature signatures[res.serialized.signature_index] = res.serialized.signature
@ -797,7 +815,7 @@ class ProtocolMixin(object):
else: else:
msg.outputs.extend([current_tx.outputs[res.details.request_index], ]) msg.outputs.extend([current_tx.outputs[res.details.request_index], ])
if debug_processor != None: if debug_processor is not None:
# If debug_processor function is provided, # If debug_processor function is provided,
# pass thru it the request and prepared response. # pass thru it the request and prepared response.
# This is useful for unit tests, see test_msg_signtx # This is useful for unit tests, see test_msg_signtx
@ -816,8 +834,8 @@ class ProtocolMixin(object):
if None in signatures: if None in signatures:
raise Exception("Some signatures are missing!") raise Exception("Some signatures are missing!")
log("SIGNED IN %.03f SECONDS, CALLED %d MESSAGES, %d BYTES" % \ log("SIGNED IN %.03f SECONDS, CALLED %d MESSAGES, %d BYTES" %
(time.time() - start, counter, len(serialized_tx))) (time.time() - start, counter, len(serialized_tx)))
return (signatures, serialized_tx) return (signatures, serialized_tx)
@ -844,14 +862,15 @@ class ProtocolMixin(object):
# optimization to load the wordlist once, instead of for each recovery word # optimization to load the wordlist once, instead of for each recovery word
self.mnemonic_wordlist = Mnemonic('english') self.mnemonic_wordlist = Mnemonic('english')
res = self.call(proto.RecoveryDevice(word_count=int(word_count), res = self.call(proto.RecoveryDevice(
passphrase_protection=bool(passphrase_protection), word_count=int(word_count),
pin_protection=bool(pin_protection), passphrase_protection=bool(passphrase_protection),
label=label, pin_protection=bool(pin_protection),
language=language, label=label,
enforce_wordlist=True, language=language,
type=type, enforce_wordlist=True,
dry_run=dry_run)) type=type,
dry_run=dry_run))
self.init_device() self.init_device()
return res return res
@ -963,7 +982,7 @@ class ProtocolMixin(object):
@session @session
def firmware_update(self, fp): def firmware_update(self, fp):
if self.features.bootloader_mode == False: if self.features.bootloader_mode is False:
raise Exception("Device must be in bootloader mode") raise Exception("Device must be in bootloader mode")
data = fp.read() data = fp.read()
@ -1000,11 +1019,14 @@ class ProtocolMixin(object):
raise Exception("Unexpected message %s" % resp) raise Exception("Unexpected message %s" % resp)
class TrezorClient(ProtocolMixin, TextUIMixin, BaseClient): class TrezorClient(ProtocolMixin, TextUIMixin, BaseClient):
pass pass
class TrezorClientDebug(ProtocolMixin, TextUIMixin, DebugWireMixin, BaseClient): class TrezorClientDebug(ProtocolMixin, TextUIMixin, DebugWireMixin, BaseClient):
pass pass
class TrezorDebugClient(ProtocolMixin, DebugLinkMixin, DebugWireMixin, BaseClient): class TrezorDebugClient(ProtocolMixin, DebugLinkMixin, DebugWireMixin, BaseClient):
pass pass

View File

@ -19,17 +19,20 @@
from __future__ import print_function from __future__ import print_function
from . import messages_pb2 as proto from . import messages_pb2 as proto
from .transport import NotImplementedException
def pin_info(pin): def pin_info(pin):
print("Device asks for PIN %s" % pin) print("Device asks for PIN %s" % pin)
def button_press(yes_no): def button_press(yes_no):
print("User pressed", '"y"' if yes_no else '"n"') print("User pressed", '"y"' if yes_no else '"n"')
def pprint(msg): def pprint(msg):
return "<%s> (%d bytes):\n%s" % (msg.__class__.__name__, msg.ByteSize(), msg) return "<%s> (%d bytes):\n%s" % (msg.__class__.__name__, msg.ByteSize(), msg)
class DebugLink(object): class DebugLink(object):
def __init__(self, transport, pin_func=pin_info, button_func=button_press): def __init__(self, transport, pin_func=pin_info, button_func=button_press):
self.transport = transport self.transport = transport
@ -126,4 +129,4 @@ class DebugLink(object):
self._call(proto.DebugLinkMemoryWrite(address=address, memory=memory, flash=flash), nowait=True) self._call(proto.DebugLinkMemoryWrite(address=address, memory=memory, flash=flash), nowait=True)
def flash_erase(self, sector): def flash_erase(self, sector):
obj = self._call(proto.DebugLinkFlashErase(sector=sector), nowait=True) self._call(proto.DebugLinkFlashErase(sector=sector), nowait=True)

View File

@ -21,6 +21,7 @@ from . import messages_pb2 as proto
map_type_to_class = {} map_type_to_class = {}
map_class_to_type = {} map_class_to_type = {}
def build_map(): def build_map():
for msg_type, i in proto.MessageType.items(): for msg_type, i in proto.MessageType.items():
msg_name = msg_type.replace('MessageType_', '') msg_name = msg_type.replace('MessageType_', '')
@ -29,6 +30,7 @@ def build_map():
map_type_to_class[i] = msg_class map_type_to_class[i] = msg_class
map_class_to_type[msg_class] = i map_class_to_type[msg_class] = i
def get_type(msg): def get_type(msg):
return map_class_to_type[msg.__class__] return map_class_to_type[msg.__class__]
@ -36,6 +38,7 @@ def get_type(msg):
def get_class(t): def get_class(t):
return map_type_to_class[t] return map_type_to_class[t]
def check_missing(): def check_missing():
from google.protobuf import reflection from google.protobuf import reflection
@ -47,5 +50,6 @@ def check_missing():
if len(missing): if len(missing):
raise Exception("Following protobuf messages are not defined in mapping: %s" % missing) raise Exception("Following protobuf messages are not defined in mapping: %s" % missing)
build_map() build_map()
check_missing() check_missing()

View File

@ -37,15 +37,16 @@ Provide serialization and de-serialization of Google's protobuf Messages into/fr
# Note that preservation of unknown fields is currently not available for Python (c) google docs # Note that preservation of unknown fields is currently not available for Python (c) google docs
# extensions is not supported from 0.0.5 (due to gpb2.3 changes) # extensions is not supported from 0.0.5 (due to gpb2.3 changes)
__version__='0.0.6' __version__ = '0.0.6'
__author__='Paul Dovbush <dpp@dpp.su>' __author__ = 'Paul Dovbush <dpp@dpp.su>'
import json # py2.6+ TODO: add support for other JSON serialization modules
from google.protobuf.descriptor import FieldDescriptor as FD from google.protobuf.descriptor import FieldDescriptor as FD
from functools import partial from functools import partial
class ParseError(Exception): pass
class ParseError(Exception):
pass
def json2pb(pb, js, useFieldNumber=False): def json2pb(pb, js, useFieldNumber=False):
@ -79,13 +80,12 @@ def json2pb(pb, js, useFieldNumber=False):
return pb return pb
def pb2json(pb, useFieldNumber=False): def pb2json(pb, useFieldNumber=False):
''' convert google.protobuf.descriptor instance to JSON string ''' ''' convert google.protobuf.descriptor instance to JSON string '''
js = {} js = {}
# fields = pb.DESCRIPTOR.fields #all fields # fields = pb.DESCRIPTOR.fields # all fields
fields = pb.ListFields() #only filled (including extensions) fields = pb.ListFields() # only filled (including extensions)
for field,value in fields: for field, value in fields:
if useFieldNumber: if useFieldNumber:
key = field.number key = field.number
else: else:
@ -94,7 +94,8 @@ def pb2json(pb, useFieldNumber=False):
ftype = partial(pb2json, useFieldNumber=useFieldNumber) ftype = partial(pb2json, useFieldNumber=useFieldNumber)
# ---- monkey patching ---- # ---- monkey patching ----
elif field.type == FD.TYPE_ENUM: elif field.type == FD.TYPE_ENUM:
ftype = lambda x: field.enum_type.values[x].name def ftype(x):
return field.enum_type.values[x].name
# ---- end of monkey patching ---- # ---- end of monkey patching ----
elif field.type in _ftype2js: elif field.type in _ftype2js:
ftype = _ftype2js[field.type] ftype = _ftype2js[field.type]
@ -120,7 +121,7 @@ _ftype2js = {
FD.TYPE_FIXED32: float, FD.TYPE_FIXED32: float,
FD.TYPE_BOOL: bool, FD.TYPE_BOOL: bool,
FD.TYPE_STRING: str, FD.TYPE_STRING: str,
#FD.TYPE_MESSAGE: pb2json, #handled specially # FD.TYPE_MESSAGE: pb2json, #handled specially
FD.TYPE_BYTES: lambda x: x.encode('string_escape'), FD.TYPE_BYTES: lambda x: x.encode('string_escape'),
FD.TYPE_UINT32: int, FD.TYPE_UINT32: int,
FD.TYPE_ENUM: int, FD.TYPE_ENUM: int,
@ -140,7 +141,7 @@ _js2ftype = {
FD.TYPE_FIXED32: float, FD.TYPE_FIXED32: float,
FD.TYPE_BOOL: bool, FD.TYPE_BOOL: bool,
FD.TYPE_STRING: str, FD.TYPE_STRING: str,
# FD.TYPE_MESSAGE: json2pb, #handled specially # FD.TYPE_MESSAGE: json2pb, # handled specially
FD.TYPE_BYTES: lambda x: x.decode('string_escape'), FD.TYPE_BYTES: lambda x: x.decode('string_escape'),
FD.TYPE_UINT32: int, FD.TYPE_UINT32: int,
FD.TYPE_ENUM: int, FD.TYPE_ENUM: int,
@ -156,7 +157,7 @@ import binascii
from . import types_pb2 as types from . import types_pb2 as types
_ftype2js[FD.TYPE_BYTES] = lambda x: binascii.hexlify(x) _ftype2js[FD.TYPE_BYTES] = lambda x: binascii.hexlify(x)
del _ftype2js[FD.TYPE_ENUM] # handled specially del _ftype2js[FD.TYPE_ENUM] # handled specially
_js2ftype[FD.TYPE_BYTES] = lambda x: binascii.unhexlify(x) _js2ftype[FD.TYPE_BYTES] = lambda x: binascii.unhexlify(x)
_js2ftype[FD.TYPE_ENUM] = lambda x: getattr(types, x) _js2ftype[FD.TYPE_ENUM] = lambda x: getattr(types, x)

View File

@ -13,6 +13,7 @@ except:
from PyQt5.QtCore import QRegExp, Qt from PyQt5.QtCore import QRegExp, Qt
from PyQt5.Qt import QT_VERSION_STR from PyQt5.Qt import QT_VERSION_STR
class PinButton(QPushButton): class PinButton(QPushButton):
def __init__(self, password, encoded_value): def __init__(self, password, encoded_value):
super(PinButton, self).__init__('?') super(PinButton, self).__init__('?')
@ -30,6 +31,7 @@ class PinButton(QPushButton):
self.password.setText(self.password.text() + str(self.encoded_value)) self.password.setText(self.password.text() + str(self.encoded_value))
self.password.setFocus() self.password.setFocus()
class PinMatrixWidget(QWidget): class PinMatrixWidget(QWidget):
''' '''
Displays widget with nine blank buttons and password box. Displays widget with nine blank buttons and password box.
@ -101,6 +103,7 @@ class PinMatrixWidget(QWidget):
def get_value(self): def get_value(self):
return self.password.text() return self.password.text()
if __name__ == '__main__': if __name__ == '__main__':
''' '''
Demo application showing PinMatrix widget in action Demo application showing PinMatrix widget in action

View File

@ -25,13 +25,18 @@ import sys
if sys.version_info < (3,): if sys.version_info < (3,):
def byteindex(data, index): def byteindex(data, index):
return ord(data[index]) return ord(data[index])
def iterbytes(data): def iterbytes(data):
return (ord (char) for char in data) return (ord(char) for char in data)
else: else:
byteindex = lambda data, index: data[index] def byteindex(data, index):
return data[index]
iterbytes = iter iterbytes = iter
Hash = lambda x: hashlib.sha256(hashlib.sha256(x).digest()).digest()
def Hash(data):
return hashlib.sha256(hashlib.sha256(data).digest()).digest()
def hash_160(public_key): def hash_160(public_key):
md = hashlib.new('ripemd160') md = hashlib.new('ripemd160')
@ -45,11 +50,13 @@ def hash_160_to_bc_address(h160, address_type):
addr = vh160 + h[0:4] addr = vh160 + h[0:4]
return b58encode(addr) return b58encode(addr)
def compress_pubkey(public_key): def compress_pubkey(public_key):
if byteindex(public_key, 0) == 4: if byteindex(public_key, 0) == 4:
return bytes((byteindex(public_key, 64) & 1) + 2) + public_key[1:33] return bytes((byteindex(public_key, 64) & 1) + 2) + public_key[1:33]
raise Exception("Pubkey is already compressed") raise Exception("Pubkey is already compressed")
def public_key_to_bc_address(public_key, address_type, compress=True): def public_key_to_bc_address(public_key, address_type, compress=True):
if public_key[0] == '\x04' and compress: if public_key[0] == '\x04' and compress:
public_key = compress_pubkey(public_key) public_key = compress_pubkey(public_key)
@ -57,9 +64,11 @@ def public_key_to_bc_address(public_key, address_type, compress=True):
h160 = hash_160(public_key) h160 = hash_160(public_key)
return hash_160_to_bc_address(h160, address_type) return hash_160_to_bc_address(h160, address_type)
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' __b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = len(__b58chars) __b58base = len(__b58chars)
def b58encode(v): def b58encode(v):
""" encode v, which is a string of bytes, to base58.""" """ encode v, which is a string of bytes, to base58."""
@ -85,6 +94,7 @@ def b58encode(v):
return (__b58chars[0] * nPad) + result return (__b58chars[0] * nPad) + result
def b58decode(v, length): def b58decode(v, length):
""" decode v into a string of len bytes.""" """ decode v into a string of len bytes."""
long_value = 0 long_value = 0
@ -111,6 +121,7 @@ def b58decode(v, length):
return result return result
def monkeypatch_google_protobuf_text_format(): def monkeypatch_google_protobuf_text_format():
# monkeypatching: text formatting of protobuf messages # monkeypatching: text formatting of protobuf messages
import google.protobuf.text_format import google.protobuf.text_format
@ -125,4 +136,3 @@ def monkeypatch_google_protobuf_text_format():
_oldPrintFieldValue(field, value, out, indent, as_utf8, as_one_line) _oldPrintFieldValue(field, value, out, indent, as_utf8, as_one_line)
google.protobuf.text_format.PrintFieldValue = _customPrintFieldValue google.protobuf.text_format.PrintFieldValue = _customPrintFieldValue

View File

@ -19,15 +19,18 @@
from __future__ import absolute_import from __future__ import absolute_import
import struct import struct
from . import mapping
import binascii import binascii
from . import mapping
class NotImplementedException(Exception): class NotImplementedException(Exception):
pass pass
class ConnectionError(Exception): class ConnectionError(Exception):
pass pass
class Transport(object): class Transport(object):
def __init__(self, device, *args, **kwargs): def __init__(self, device, *args, **kwargs):
self.device = device self.device = device
@ -84,7 +87,7 @@ class Transport(object):
""" """
while True: while True:
data = self._read() data = self._read()
if data != None: if data is not None:
break break
return self._parse_message(data) return self._parse_message(data)
@ -129,6 +132,7 @@ class Transport(object):
def _session_end(self): def _session_end(self):
pass pass
class TransportV1(Transport): class TransportV1(Transport):
def write(self, msg): def write(self, msg):
ser = msg.SerializeToString() ser = msg.SerializeToString()
@ -172,6 +176,7 @@ class TransportV1(Transport):
return chunk[1:] return chunk[1:]
class TransportV2(Transport): class TransportV2(Transport):
def write(self, msg): def write(self, msg):
if not self.session_id: if not self.session_id:

View File

@ -28,9 +28,11 @@ from .transport import TransportV1
TREZORD_HOST = 'https://localback.net:21324' TREZORD_HOST = 'https://localback.net:21324'
CONFIG_URL = 'https://wallet.trezor.io/data/config_signed.bin' CONFIG_URL = 'https://wallet.trezor.io/data/config_signed.bin'
def get_error(resp): def get_error(resp):
return ' (error=%d str=%s)' % (resp.status_code, resp.json()['error']) return ' (error=%d str=%s)' % (resp.status_code, resp.json()['error'])
class BridgeTransport(TransportV1): class BridgeTransport(TransportV1):
CONFIGURED = False CONFIGURED = False
@ -47,7 +49,8 @@ class BridgeTransport(TransportV1):
@staticmethod @staticmethod
def configure(): def configure():
if BridgeTransport.CONFIGURED: return if BridgeTransport.CONFIGURED:
return
r = requests.get(CONFIG_URL, verify=False) r = requests.get(CONFIG_URL, verify=False)
if r.status_code != 200: if r.status_code != 200:
raise Exception('Could not fetch config from %s' % CONFIG_URL) raise Exception('Could not fetch config from %s' % CONFIG_URL)
@ -88,7 +91,7 @@ class BridgeTransport(TransportV1):
self.session = None self.session = None
def _ready_to_read(self): def _ready_to_read(self):
return self.response != None return self.response is not None
def write(self, protobuf_msg): def write(self, protobuf_msg):
# Override main 'write' method, HTTP transport cannot be # Override main 'write' method, HTTP transport cannot be

View File

@ -18,10 +18,11 @@
'''USB HID implementation of Transport.''' '''USB HID implementation of Transport.'''
import hid
import time import time
import hid
from .transport import TransportV1, TransportV2, ConnectionError from .transport import TransportV1, TransportV2, ConnectionError
def enumerate(): def enumerate():
""" """
Return a list of available TREZOR devices. Return a list of available TREZOR devices.
@ -46,9 +47,10 @@ def enumerate():
# List of two-tuples (path_normal, path_debuglink) # List of two-tuples (path_normal, path_debuglink)
return sorted(devices.values()) return sorted(devices.values())
def path_to_transport(path): def path_to_transport(path):
try: try:
device = [ d for d in hid.enumerate(0, 0) if d['path'] == path ][0] device = [d for d in hid.enumerate(0, 0) if d['path'] == path][0]
except IndexError: except IndexError:
raise ConnectionError("Connection failed") raise ConnectionError("Connection failed")
@ -56,10 +58,11 @@ def path_to_transport(path):
try: try:
transport = DEVICE_TRANSPORTS[(device['vendor_id'], device['product_id'])] transport = DEVICE_TRANSPORTS[(device['vendor_id'], device['product_id'])]
except IndexError: except IndexError:
raise Exception("Unknown transport for VID:PID %04x:%04x" % (vid, pid)) raise Exception("Unknown transport for VID:PID %04x:%04x" % (device['vendor_id'], device['product_id']))
return transport return transport
class _HidTransport(object): class _HidTransport(object):
def __init__(self, device, *args, **kwargs): def __init__(self, device, *args, **kwargs):
self.hid = None self.hid = None
@ -134,12 +137,15 @@ class _HidTransport(object):
return bytearray(data) return bytearray(data)
class HidTransportV1(_HidTransport, TransportV1): class HidTransportV1(_HidTransport, TransportV1):
pass pass
class HidTransportV2(_HidTransport, TransportV2): class HidTransportV2(_HidTransport, TransportV2):
pass pass
DEVICE_IDS = [ DEVICE_IDS = [
(0x534c, 0x0001), # TREZOR (0x534c, 0x0001), # TREZOR
(0x1209, 0x53c0), # TREZORv2 Bootloader (0x1209, 0x53c0), # TREZORv2 Bootloader
@ -152,11 +158,13 @@ DEVICE_TRANSPORTS = {
(0x1209, 0x53c1): HidTransportV2, # TREZORv2 (0x1209, 0x53c1): HidTransportV2, # TREZORv2
} }
# Backward compatible wrapper, decides for proper transport # Backward compatible wrapper, decides for proper transport
# based on VID/PID of given path # based on VID/PID of given path
def HidTransport(device, *args, **kwargs): def HidTransport(device, *args, **kwargs):
transport = path_to_transport(device[0]) transport = path_to_transport(device[0])
return transport(device, *args, **kwargs) return transport(device, *args, **kwargs)
# Backward compatibility hack; HidTransport is a function, not a class like before # Backward compatibility hack; HidTransport is a function, not a class like before
HidTransport.enumerate = enumerate HidTransport.enumerate = enumerate

View File

@ -18,36 +18,39 @@
from __future__ import print_function from __future__ import print_function
import os import os
import time
from select import select from select import select
from .transport import TransportV1 from .transport import TransportV1
"""PipeTransport implements fake wire transport over local named pipe. """PipeTransport implements fake wire transport over local named pipe.
Use this transport for talking with trezor simulator.""" Use this transport for talking with trezor simulator."""
class PipeTransport(TransportV1): class PipeTransport(TransportV1):
def __init__(self, device, is_device, *args, **kwargs): def __init__(self, device, is_device, *args, **kwargs):
self.is_device = is_device # Set True if act as device self.is_device = is_device # set True if act as device
super(PipeTransport, self).__init__(device, *args, **kwargs) super(PipeTransport, self).__init__(device, *args, **kwargs)
def _open(self): def _open(self):
if self.is_device: if self.is_device:
self.filename_read = self.device+'.to' self.filename_read = self.device + '.to'
self.filename_write = self.device+'.from' self.filename_write = self.device + '.from'
os.mkfifo(self.filename_read, 0o600) os.mkfifo(self.filename_read, 0o600)
os.mkfifo(self.filename_write, 0o600) os.mkfifo(self.filename_write, 0o600)
else: else:
self.filename_read = self.device+'.from' self.filename_read = self.device + '.from'
self.filename_write = self.device+'.to' self.filename_write = self.device + '.to'
if not os.path.exists(self.filename_write): if not os.path.exists(self.filename_write):
raise Exception("Not connected") raise Exception("Not connected")
self.write_fd = os.open(self.filename_write, os.O_RDWR)#|os.O_NONBLOCK) self.write_fd = os.open(self.filename_write, os.O_RDWR) # |os.O_NONBLOCK)
self.write_f = os.fdopen(self.write_fd, 'w+b', 0) self.write_f = os.fdopen(self.write_fd, 'w+b', 0)
self.read_fd = os.open(self.filename_read, os.O_RDWR)#|os.O_NONBLOCK) self.read_fd = os.open(self.filename_read, os.O_RDWR) # |os.O_NONBLOCK)
self.read_f = os.fdopen(self.read_fd, 'rb', 0) self.read_f = os.fdopen(self.read_fd, 'rb', 0)
def _close(self): def _close(self):

View File

@ -20,7 +20,8 @@
import socket import socket
from select import select from select import select
from .transport import TransportV2, ConnectionError from .transport import TransportV2
class UdpTransport(TransportV2): class UdpTransport(TransportV2):
def __init__(self, device, *args, **kwargs): def __init__(self, device, *args, **kwargs):

View File

@ -25,6 +25,7 @@ from . import types_pb2 as proto_types
cache_dir = None cache_dir = None
class TxApi(object): class TxApi(object):
def __init__(self, network, url): def __init__(self, network, url):
@ -35,7 +36,7 @@ class TxApi(object):
global cache_dir global cache_dir
if cache_dir: if cache_dir:
cache_file = '%s/%s_%s_%s.json' % (cache_dir, self.network, resource, resourceid) cache_file = '%s/%s_%s_%s.json' % (cache_dir, self.network, resource, resourceid)
try: # looking into cache first try: # looking into cache first
j = json.load(open(cache_file)) j = json.load(open(cache_file))
return j return j
except: except:
@ -47,7 +48,7 @@ class TxApi(object):
except: except:
raise Exception('URL error: %s' % url) raise Exception('URL error: %s' % url)
if cache_dir and cache_file: if cache_dir and cache_file:
try: # saving into cache try: # saving into cache
json.dump(j, open(cache_file, 'w')) json.dump(j, open(cache_file, 'w'))
except: except:
pass pass
@ -74,8 +75,8 @@ class TxApiInsight(TxApi):
for vin in data['vin']: for vin in data['vin']:
i = t.inputs.add() i = t.inputs.add()
if 'coinbase' in vin.keys(): if 'coinbase' in vin.keys():
i.prev_hash = b"\0"*32 i.prev_hash = b"\0" * 32
i.prev_index = 0xffffffff # signed int -1 i.prev_index = 0xffffffff # signed int -1
i.script_sig = binascii.unhexlify(vin['coinbase']) i.script_sig = binascii.unhexlify(vin['coinbase'])
i.sequence = vin['sequence'] i.sequence = vin['sequence']
@ -94,7 +95,7 @@ class TxApiInsight(TxApi):
if t.version == 2: if t.version == 2:
joinsplit_cnt = len(data['vjoinsplit']) joinsplit_cnt = len(data['vjoinsplit'])
if joinsplit_cnt == 0: if joinsplit_cnt == 0:
t.extra_data =b'\x00' t.extra_data = b'\x00'
else: else:
if joinsplit_cnt >= 253: if joinsplit_cnt >= 253:
# we assume cnt < 253, so we can treat varIntLen(cnt) as 1 # we assume cnt < 253, so we can treat varIntLen(cnt) as 1
@ -122,8 +123,8 @@ class TxApiSmartbit(TxApi):
for vin in data['inputs']: for vin in data['inputs']:
i = t.inputs.add() i = t.inputs.add()
if 'coinbase' in vin.keys(): if 'coinbase' in vin.keys():
i.prev_hash = b"\0"*32 i.prev_hash = b"\0" * 32
i.prev_index = 0xffffffff # signed int -1 i.prev_index = 0xffffffff # signed int -1
i.script_sig = binascii.unhexlify(vin['coinbase']) i.script_sig = binascii.unhexlify(vin['coinbase'])
i.sequence = vin['sequence'] i.sequence = vin['sequence']
@ -154,8 +155,8 @@ class TxApiBlockCypher(TxApi):
for vin in data['inputs']: for vin in data['inputs']:
i = t.inputs.add() i = t.inputs.add()
if 'prev_hash' not in vin: if 'prev_hash' not in vin:
i.prev_hash = b"\0"*32 i.prev_hash = b"\0" * 32
i.prev_index = 0xffffffff # signed int -1 i.prev_index = 0xffffffff # signed int -1
i.script_sig = binascii.unhexlify(vin['script']) i.script_sig = binascii.unhexlify(vin['script'])
i.sequence = vin['sequence'] i.sequence = vin['sequence']
else: else:
@ -177,4 +178,3 @@ TxApiTestnet = TxApiInsight(network='insight_testnet', url='https://test-insight
TxApiLitecoin = TxApiBlockCypher(network='blockcypher_litecoin', url='https://api.blockcypher.com/v1/ltc/main/') TxApiLitecoin = TxApiBlockCypher(network='blockcypher_litecoin', url='https://api.blockcypher.com/v1/ltc/main/')
TxApiSegnet = TxApiSmartbit(network='smartbit_segnet', url='https://segnet-api.smartbit.com.au/v1/blockchain/') 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) TxApiZcashTestnet = TxApiInsight(network='insight_zcashtestnet', url='https://explorer.testnet.z.cash/api/', zcash=True)