mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 23:48:12 +00:00
Merge branch 'segwit' of github.com:jhoenicke/python-trezor
This commit is contained in:
commit
828026dd40
223
signtest.py
Normal file
223
signtest.py
Normal 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()
|
@ -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}),
|
||||
)
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user