class TrezorIdentityProvider(IdentityProvider): def __init__(self, w3, index): self.w3 = w3 self.client = TrezorClient(HidTransport.enumerate()[0]) self.index = index self.address = self.w3.toChecksumAddress("0x" + bytes( self.client.ethereum_get_address([ 44 + bip32utils.BIP32_HARDEN, 60 + bip32utils.BIP32_HARDEN, bip32utils.BIP32_HARDEN, 0, index ])).hex()) def get_address(self): return self.address def transact(self, transaction, out_f): print("Sending transaction to trezor for signature...\n", file=out_f) signature = self.client.ethereum_sign_tx( n=[ 44 + bip32utils.BIP32_HARDEN, 60 + bip32utils.BIP32_HARDEN, bip32utils.BIP32_HARDEN, 0, self.index ], nonce=transaction["nonce"], gas_price=transaction["gasPrice"], gas_limit=transaction["gas"], to=bytearray.fromhex(transaction["to"][2:]), value=transaction["value"], data=bytearray.fromhex(transaction["data"][2:])) transaction.pop("from") unsigned_transaction = serializable_unsigned_transaction_from_dict( transaction) raw_transaction = encode_transaction(unsigned_transaction, vrs=(signature[0], int(signature[1].hex(), 16), int(signature[2].hex(), 16))) print("Submitting transaction...\n", file=out_f) txn_hash = self.w3.eth.sendRawTransaction(raw_transaction) # Wait for transaction to be mined receipt = None while receipt is None: time.sleep(1) receipt = self.w3.eth.getTransactionReceipt(txn_hash) return receipt # Currently broken (see https://github.com/ethereum/go-ethereum/issues/14794) def sign_message(self, message, out_f): # n = self.client._convert_prime([44 + bip32utils.BIP32_HARDEN, # 60 + bip32utils.BIP32_HARDEN, # bip32utils.BIP32_HARDEN, # 0, # self.index]) # print("Sending message to trezor for signature...\n", file=out_f) # return self.client.call(proto.EthereumSignMessage(address_n=n, message=web3.Web3.sha3(hexstr=message))) raise RuntimeError( "Trezor's dogmatic developers have chosen to break message signing compatibility with no " "security benefit to end users. Buy a ledger wallet here: https://www.ledgerwallet.com/" )
class TrezorIdentityProvider(IdentityProvider): def __init__(self, w3, index): self.w3 = w3 self.client = TrezorClient(HidTransport.enumerate()[0]) self.index = index self.address = self.w3.toChecksumAddress("0x" + bytes( self.client.ethereum_get_address([ 44 + bip32utils.BIP32_HARDEN, 60 + bip32utils.BIP32_HARDEN, bip32utils.BIP32_HARDEN, 0, index ])).hex()) def get_address(self): return self.address def transact(self, transaction, out_f): print("Sending transaction to trezor for signature...\n", file=out_f) signature = self.client.ethereum_sign_tx( n=[ 44 + bip32utils.BIP32_HARDEN, 60 + bip32utils.BIP32_HARDEN, bip32utils.BIP32_HARDEN, 0, self.index ], nonce=transaction["nonce"], gas_price=transaction["gasPrice"], gas_limit=transaction["gas"], to=bytearray.fromhex(transaction["to"][2:]), value=transaction["value"], data=bytearray.fromhex(transaction["data"][2:])) transaction.pop("from") unsigned_transaction = serializable_unsigned_transaction_from_dict( transaction) raw_transaction = encode_transaction(unsigned_transaction, vrs=(signature[0], int(signature[1].hex(), 16), int(signature[2].hex(), 16))) print("Submitting transaction...\n", file=out_f) txn_hash = self.w3.eth.sendRawTransaction(raw_transaction) # Wait for transaction to be mined receipt = None while receipt is None: time.sleep(1) receipt = self.w3.eth.getTransactionReceipt(txn_hash) return receipt def sign_message(self, message, out_f, agent_version=2): n = self.client._convert_prime([ 44 + bip32utils.BIP32_HARDEN, 60 + bip32utils.BIP32_HARDEN, bip32utils.BIP32_HARDEN, 0, self.index ]) print("Sending message to trezor for signature...\n", file=out_f) if agent_version == 1: message = self.w3.sha3(hexstr=message) else: message = message.lower().encode("utf-8") return self.client.call( proto.EthereumSignMessage(address_n=n, message=message)).signature
class TrezorIdentityProvider(IdentityProvider): def __init__(self, w3, index): self.w3 = w3 self.client = TrezorClient(HidTransport.enumerate()[0]) self.index = index self.address = self.w3.toChecksumAddress( "0x" + bytes(self.client.ethereum_get_address([44 + BIP32_HARDEN, 60 + BIP32_HARDEN, BIP32_HARDEN, 0, index])).hex()) def get_address(self): return self.address def transact(self, transaction, out_f): print("Sending transaction to trezor for signature...\n", file=out_f) signature = self.client.ethereum_sign_tx(n=[44 + BIP32_HARDEN, 60 + BIP32_HARDEN, BIP32_HARDEN, 0, self.index], nonce=transaction["nonce"], gas_price=transaction["gasPrice"], gas_limit=transaction["gas"], to=bytearray.fromhex( transaction["to"][2:]), value=transaction["value"], data=bytearray.fromhex(transaction["data"][2:])) transaction.pop("from") unsigned_transaction = serializable_unsigned_transaction_from_dict( transaction) raw_transaction = encode_transaction(unsigned_transaction, vrs=(signature[0], int(signature[1].hex(), 16), int(signature[2].hex(), 16))) return send_and_wait_for_transaction(raw_transaction, self.w3, out_f) def sign_message_after_soliditySha3(self, message): n = self.client._convert_prime([44 + BIP32_HARDEN, 60 + BIP32_HARDEN, BIP32_HARDEN, 0, self.index]) return self.client.call(proto.EthereumSignMessage(address_n=n, message=message)).signature
import sys from subprocess import Popen, PIPE ADRS_TOTAL = 5000 devices = HidTransport.enumerate() # Check whether we found any if len(devices) == 0: print('No TREZOR found') sys.exit() # Use first connected device transport = devices[0] # Creates object for manipulating TREZOR client = TrezorClient(transport) adrs = [] for i in tqdm(range(ADRS_TOTAL)): bip32_path = client.expand_path("44'/60'/0'/0/{0}".format(i)) adr = client.ethereum_get_address(bip32_path) adr_ascii = binascii.b2a_hex(adr) call = ['node', 'eth.js', adr_ascii] p = Popen(call, stdout=PIPE, stderr=PIPE) out, err = p.communicate() adrs.append(out[:-1].decode()) client.close() pickle.dump(adrs, open('ETH.pickle', 'wb')) # trezorctl ethereum_get_address -n "m/44'/60'/0'/0/0"