1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-14 11:39:03 +00:00

Merge branch 'segwit' of github.com:jhoenicke/python-trezor

This commit is contained in:
Pavol Rusnak 2016-05-19 11:56:38 +02:00
commit 828026dd40
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
3 changed files with 269 additions and 2 deletions

223
signtest.py Normal file
View File

@ -0,0 +1,223 @@
#!/usr/bin/python
import binascii
import os
import random
import trezorlib.messages_pb2 as proto
import trezorlib.types_pb2 as proto_types
import trezorlib.tools as tools
import trezorlib.ckd_public as bip32
import hashlib
from trezorlib.client import TrezorClient
from trezorlib.client import TrezorClientDebug
from trezorlib.tx_api import TXAPITestnet
from trezorlib.tx_api import TXAPIBitcoin
from trezorlib.transport_hid import HidTransport
from trezorlib.transport_bridge import BridgeTransport
def pack_varint(x):
if (x < 0xfd):
return chr(x)
else:
return '\xfd'+chr(x & 0xff) + chr((x >> 8) & 0xff)
def int_to_string(x, pad):
result = ['\x00'] * pad
while x > 0:
pad -= 1
ordinal = x & 0xFF
result[pad] = (chr(ordinal))
x >>= 8
return ''.join(result)
def string_to_int(s):
result = 0
for c in s:
if not isinstance(c, int):
c = ord(c)
result = (result << 8) + c
return result
class MyTXAPIBitcoin(object):
def set_publickey(self, node):
self.node = node.node
def set_client(self, client):
self.client = client
def serialize_tx(self, tx):
ser = ''
ser = ser + int_to_string(tx.version, 4)[::-1]
ser = ser + pack_varint(len(tx.inputs))
for i in tx.inputs:
ser = ser + i.prev_hash[::-1]
ser = ser + int_to_string(i.prev_index, 4)[::-1]
ser = ser + pack_varint(len(i.script_sig)) + i.script_sig
ser = ser + int_to_string(i.sequence, 4)[::-1]
ser = ser + pack_varint(len(tx.bin_outputs))
for o in tx.bin_outputs:
ser = ser + int_to_string(o.amount, 8)[::-1]
ser = ser + pack_varint(len(o.script_pubkey)) + o.script_pubkey
ser = ser + int_to_string(tx.lock_time, 4)[::-1]
return ser
def create_inputs(self, numinputs, txsize):
idx = 0
sum = 0
self.inputs = []
self.txs = {}
for nr in range(numinputs):
t = proto_types.TransactionType()
t.version = 1
t.lock_time = 0
i = t.inputs.add()
i.prev_hash = os.urandom(32)
i.prev_index = random.randint(0,4)
i.script_sig = os.urandom(100)
i.sequence = 0xffffffff
if (nr % 50 == 0):
print nr
myout = random.randint(0, txsize-1)
segwit = 1 #random.randint(0,1)
for vout in range(txsize):
o = t.bin_outputs.add()
o.amount = random.randint(10000,1000000)
if vout == myout:
amount = o.amount
sum = sum + o.amount
node = self.node
path = [0, idx]
node = bip32.public_ckd(node, path)
idx = idx + 1
pubkey = tools.hash_160(node.public_key)
else:
pubkey = os.urandom(20)
if (segwit):
o.script_pubkey = binascii.unhexlify('0014') + pubkey
else:
o.script_pubkey = binascii.unhexlify('76a914') + pubkey + binascii.unhexlify('88ac')
txser = self.serialize_tx(t)
txhash = tools.Hash(txser)[::-1]
if (segwit):
outi = self.inputs.append(
proto_types.TxInputType(
address_n=self.client.expand_path("44'/0'/0'/0/"+str(idx)),
script_type = proto_types.SPENDWADDRESS,
prev_hash=txhash,
prev_index = myout,
amount = amount
))
else:
outi = self.inputs.append(
proto_types.TxInputType(
address_n=self.client.expand_path("44'/0'/0'/0/"+str(idx)),
script_type = proto_types.SPENDADDRESS,
prev_hash=txhash,
prev_index = myout
))
#print binascii.hexlify(txser)
#print binascii.hexlify(txhash)
self.txs[binascii.hexlify(txhash)] = t
self.outputs = [
proto_types.TxOutputType(
amount=sum,
script_type=proto_types.PAYTOADDRESS,
address_n=self.client.expand_path("44'/0'/0'/1/0")
)]
def get_inputs(self):
return self.inputs
def get_outputs(self):
return self.outputs
def get_tx(self, txhash):
t = self.txs[txhash]
#print t
return t
def main():
numinputs = 600
sizeinputtx = 10
# List all connected TREZORs on USB
devices = HidTransport.enumerate()
# Check whether we found any
if len(devices) == 0:
print 'No TREZOR found'
return
# Use first connected device
print devices[0][0]
# transport = BridgeTransport(devices[0][0])
transport = HidTransport(devices[0])
txstore = MyTXAPIBitcoin()
# Creates object for manipulating TREZOR
client = TrezorClient(transport)
# client.set_tx_api(TXAPITestnet())
txstore.set_client(client)
txstore.set_publickey(client.get_public_node(client.expand_path("44'/0'/0'")))
print "creating input txs"
txstore.create_inputs(numinputs, sizeinputtx)
print "go"
client.set_tx_api(txstore)
# client.set_tx_api(MyTXAPIBitcoin())
# Print out TREZOR's features and settings
print client.features
# Get the first address of first BIP44 account
# (should be the same address as shown in mytrezor.com)
outputs = [
proto_types.TxOutputType(
amount=0,
script_type=proto_types.PAYTOADDRESS,
address='p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm'
# op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6')
# address_n=client.expand_path("44'/0'/0'/0/35"),
# address='3PUxV6Cc4udQZQsJhArVUzvvVoKC8ohkAj',
),
# proto_types.TxOutputType(
# amount=0,
# script_type=proto_types.PAYTOOPRETURN,
# op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6')
# ),
# proto_types.TxOutputType(
# amount= 8120,
# script_type=proto_types.PAYTOADDRESS,
# address_n=client.expand_path("44'/1'/0'/1/0"),
# address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
# address='14KRxYgFc7Se8j7MDdrK5PTNv8meq4GivK',
# ),
# proto_types.TxOutputType(
# amount= 18684 - 2000,
# script_type=proto_types.PAYTOADDRESS,
# address_n=client.expand_path("44'/0'/0'/0/7"),
# # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
# # address='1s9TSqr3PHZdXGrYws59Uaf5SPqavH43z',
# ),
# proto_types.TxOutputType(
# amount= 1000,
# script_type=proto_types.PAYTOADDRESS,
# # address_n=client.expand_path("44'/0'/0'/0/18"),
# # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
# address='1NcMqUvyWv1K3Zxwmx5sqfj7ZEmPCSdJFM',
# ),
]
# (signatures, serialized_tx) = client.sign_tx('Testnet', inputs, outputs)
(signatures, serialized_tx) = client.sign_tx('Bitcoin', txstore.get_inputs(), txstore.get_outputs())
print 'Transaction:', binascii.hexlify(serialized_tx)
client.close()
if __name__ == '__main__':
main()

View File

@ -111,7 +111,7 @@ class Commands(object):
def get_public_node(self, args):
address_n = self.client.expand_path(args.n)
return self.client.get_public_node(address_n, args.ecdsa_curve_name, args.show_display)
return self.client.get_public_node(address_n, ecdsa_curve_name=args.curve, show_display=args.show_display)
def set_label(self, args):
return self.client.apply_settings(label=args.label)
@ -368,7 +368,7 @@ class Commands(object):
get_public_node.arguments = (
(('-n', '-address'), {'type': str}),
(('-e', '--ecdsa-curve-name'), {'type': str}),
(('-e', '--curve'), {'type': str}),
(('-d', '--show-display'), {'action': 'store_true', 'default': False}),
)

View File

@ -40,6 +40,43 @@ def insight_tx(url, rawdata=False):
return t
def smartbit_tx(url, rawdata=False):
if not rawdata:
try:
f = urllib2.urlopen(url)
data = json.load(f)
except:
raise Exception('URL error: %s' % url)
else:
data = url
data = data['transaction']
t = proto_types.TransactionType()
t.version = int(data['version'])
t.lock_time = data['locktime']
for vin in data['inputs']:
i = t.inputs.add()
if 'coinbase' in vin.keys():
i.prev_hash = "\0"*32
i.prev_index = 0xffffffff # signed int -1
i.script_sig = binascii.unhexlify(vin['coinbase'])
i.sequence = vin['sequence']
else:
i.prev_hash = binascii.unhexlify(vin['txid'])
i.prev_index = vin['vout']
i.script_sig = binascii.unhexlify(vin['script_sig']['hex'])
i.sequence = vin['sequence']
for vout in data['outputs']:
o = t.bin_outputs.add()
o.amount = int(Decimal(vout['value']) * 100000000)
o.script_pubkey = binascii.unhexlify(vout['script_pub_key']['hex'])
return t
class TXAPIBitcoin(object):
# @filecache(DAY)
@ -53,3 +90,10 @@ class TXAPITestnet(object):
def get_tx(self, txhash):
url = 'https://test-insight.bitpay.com/api/tx/%s' % txhash
return insight_tx(url)
class TXAPISegnet(object):
# @filecache(DAY)
def get_tx(self, txhash):
url = 'https://segnet-api.smartbit.com.au/v1/blockchain/tx/%s' % txhash
return smartbit_tx(url)