diff --git a/examples/ethBase.py b/examples/ethBase.py index d530385..95fb143 100755 --- a/examples/ethBase.py +++ b/examples/ethBase.py @@ -53,5 +53,22 @@ class Transaction(Serializable): super(Transaction, self).__init__( nonce, gasprice, startgas, to, value, data, v, r, s) +class UnsignedTransaction(Serializable): + fields = [ + ('nonce', big_endian_int), + ('gasprice', big_endian_int), + ('startgas', big_endian_int), + ('to', address), + ('value', big_endian_int), + ('data', binary), + ] -UnsignedTransaction = Transaction.exclude(['v', 'r', 's']) +def unsigned_tx_from_tx(tx): + return UnsignedTransaction( + nonce=tx.nonce, + gasprice=tx.gasprice, + startgas=tx.startgas, + to=tx.to, + value=tx.value, + data=tx.data, + ) \ No newline at end of file diff --git a/examples/getPublicKey.py b/examples/getPublicKey.py index 7182102..f602b1d 100755 --- a/examples/getPublicKey.py +++ b/examples/getPublicKey.py @@ -17,16 +17,19 @@ * limitations under the License. ******************************************************************************** """ +from __future__ import print_function + from ledgerblue.comm import getDongle from ledgerblue.commException import CommException import argparse import struct +import binascii def parse_bip32_path(path): if len(path) == 0: - return "" - result = "" + return b"" + result = b"" elements = path.split('/') for pathElement in elements: element = pathElement.split('\'') @@ -45,13 +48,13 @@ if args.path == None: args.path = "44'/60'/0'/0/0" donglePath = parse_bip32_path(args.path) -apdu = "e0020100".decode('hex') + chr(len(donglePath) + 1) + \ - chr(len(donglePath) / 4) + donglePath +apdu = bytearray.fromhex("e0020100") + chr(len(donglePath) + 1).encode() + \ + chr(len(donglePath) // 4).encode() + donglePath dongle = getDongle(True) result = dongle.exchange(bytes(apdu)) offset = 1 + result[0] address = result[offset + 1: offset + 1 + result[offset]] -print "Public key " + str(result[1: 1 + result[0]]).encode('hex') -print "Address 0x" + str(address) +print("Public key", binascii.hexlify(result[1: 1 + result[0]]).decode()) +print("Address 0x", address.decode(), sep='') diff --git a/examples/setSelfAddress.py b/examples/setSelfAddress.py index 7246951..3623750 100755 --- a/examples/setSelfAddress.py +++ b/examples/setSelfAddress.py @@ -25,8 +25,8 @@ import struct def parse_bip32_path(path): if len(path) == 0: - return "" - result = "" + return b"" + result = b"" elements = path.split('/') for pathElement in elements: element = pathElement.split('\'') @@ -45,8 +45,8 @@ if args.path == None: args.path = "44'/60'/0'/0/0" donglePath = parse_bip32_path(args.path) -apdu = "e0060000".decode('hex') + chr(len(donglePath) + 1) + \ - chr(len(donglePath) / 4) + donglePath +apdu = bytearray.fromhex("e0060000") + chr(len(donglePath) + 1).encode() + \ + chr(len(donglePath) // 4).encode() + donglePath dongle = getDongle(True) dongle.exchange(bytes(apdu)) diff --git a/examples/signTx.py b/examples/signTx.py index 230759e..1973a0d 100755 --- a/examples/signTx.py +++ b/examples/signTx.py @@ -17,20 +17,26 @@ * limitations under the License. ******************************************************************************** """ +from __future__ import print_function + from ledgerblue.comm import getDongle from ledgerblue.commException import CommException import argparse import struct -from decimal import Decimal -from ethBase import Transaction, UnsignedTransaction +import binascii +from ethBase import Transaction, UnsignedTransaction, unsigned_tx_from_tx from rlp import encode -from rlp.utils import decode_hex, encode_hex, str_to_bytes +try: + from rlp.utils import decode_hex, encode_hex, str_to_bytes +except: + #Python3 hack import for pyethereum + from ethereum.utils import decode_hex, encode_hex, str_to_bytes def parse_bip32_path(path): if len(path) == 0: - return "" - result = "" + return b"" + result = b"" elements = path.split('/') for pathElement in elements: element = pathElement.split('\'') @@ -55,11 +61,11 @@ if args.path == None: args.path = "44'/60'/0'/0/0" if args.data == None: - args.data = "" + args.data = b"" else: args.data = decode_hex(args.data[2:]) -amount = Decimal(args.amount) * 10**18 +amount = args.amount * 10**18 tx = Transaction( nonce=int(args.nonce), @@ -67,23 +73,25 @@ tx = Transaction( startgas=int(args.startgas), to=decode_hex(args.to[2:]), value=int(amount), - data=args.data + data=args.data, ) -encodedTx = encode(tx, UnsignedTransaction) +encodedTx = encode(unsigned_tx_from_tx(tx), UnsignedTransaction) donglePath = parse_bip32_path(args.path) -apdu = "e0040000".decode('hex') + chr(len(donglePath) + 1 + - len(encodedTx)) + chr(len(donglePath) / 4) + donglePath + encodedTx +apdu = bytearray.fromhex("e0040000") +apdu.append(len(donglePath) + 1 + len(encodedTx)) +apdu.append(len(donglePath) // 4) +apdu += donglePath + encodedTx dongle = getDongle(True) result = dongle.exchange(bytes(apdu)) v = result[0] -r = int(str(result[1:1 + 32]).encode('hex'), 16) -s = int(str(result[1 + 32: 1 + 32 + 32]).encode('hex'), 16) +r = int(binascii.hexlify(result[1:1 + 32]), 16) +s = int(binascii.hexlify(result[1 + 32: 1 + 32 + 32]), 16) tx = Transaction(tx.nonce, tx.gasprice, tx.startgas, tx.to, tx.value, tx.data, v, r, s) -print "Signed transaction " + encode_hex(encode(tx)) +print("Signed transaction", encode_hex(encode(tx))) diff --git a/examples/splitEther.py b/examples/splitEther.py index f80cfd1..1b8f034 100755 --- a/examples/splitEther.py +++ b/examples/splitEther.py @@ -17,6 +17,8 @@ * limitations under the License. ******************************************************************************** """ +from __future__ import print_function + from ledgerblue.comm import getDongle from ledgerblue.commException import CommException import argparse @@ -48,8 +50,8 @@ def rpc_call(http, url, methodDebug): def parse_bip32_path(path): if len(path) == 0: - return "" - result = "" + return b"" + result = b"" elements = path.split('/') for pathElement in elements: element = pathElement.split('\'') @@ -96,20 +98,20 @@ if args.to == None: dongle = getDongle(True) donglePath = parse_bip32_path(args.to) -apdu = "e0060000".decode('hex') + chr(len(donglePath) + 1) + \ - chr(len(donglePath) / 4) + donglePath +apdu = bytearray.fromhex("e0060000") + chr(len(donglePath) + 1).encode() + \ + chr(len(donglePath) // 4).encode() + donglePath dongle.exchange(bytes(apdu)) -apdu = "e0020000".decode('hex') + chr(len(donglePath) + 1) + \ - chr(len(donglePath) / 4) + donglePath +apdu = bytearray.fromhex("e0020000") + chr(len(donglePath) + 1).encode() + \ + chr(len(donglePath) // 4).encode() + donglePath result = dongle.exchange(bytes(apdu)) publicKey = str(result[1: 1 + result[0]]) encodedPublicKey = sha3(publicKey[1:])[12:] if (args.nonce == None) or (args.amount == None): donglePathFrom = parse_bip32_path(args.path) - apdu = "e0020000".decode('hex') + chr(len(donglePathFrom) + 1) + \ - chr(len(donglePathFrom) / 4) + donglePathFrom + apdu = bytearray.fromhex("e0020000") + chr(len(donglePathFrom) + 1).encode() + \ + chr(len(donglePathFrom) // 4).encode() + donglePathFrom result = dongle.exchange(bytes(apdu)) publicKeyFrom = str(result[1: 1 + result[0]]) encodedPublicKeyFrom = sha3(publicKeyFrom[1:])[12:] @@ -120,36 +122,35 @@ if (args.gasprice == None) or (args.nonce == None) or (args.amount == None) or ( http = requests.session() if args.gasprice == None: - print "Fetching gas price" + print("Fetching gas price") result = rpc_call( http, "https://api.etherscan.io/api?module=proxy&action=eth_gasPrice", "gasPrice") args.gasprice = int(result['result'], 16) - print "Gas price " + str(args.gasprice) + print("Gas price:", str(args.gasprice)) if args.nonce == None: - print "Fetching nonce" + print("Fetching nonce") result = rpc_call(http, "https://api.etherscan.io/api?module=proxy&action=eth_getTransactionCount&address=0x" + encodedPublicKeyFrom.encode('hex'), "getTransactionCount") args.nonce = int(result['result'], 16) - print "Nonce for 0x" + \ - encodedPublicKeyFrom.encode('hex') + " " + str(args.nonce) + print("Nonce for 0x", encodedPublicKeyFrom.encode('hex'), " ", args.nonce, sep='') if args.amount == None: - print "Fetching balance" + print("Fetching balance") result = rpc_call(http, "https://api.etherscan.io/api?module=account&action=balance&address=0x" + encodedPublicKeyFrom.encode('hex'), "getBalance") amount = int(result['result']) - print "Balance for " + \ - encodedPublicKeyFrom.encode('hex') + " " + str(amount) + print("Balance for 0x", encodedPublicKeyFrom.encode('hex'), " ", str(amount), sep='') amount -= (int(args.startgas) - int(args.startgas_delta)) * \ int(args.gasprice) + amount = 2 if amount < 0: raise Exception("Remaining amount too small to pay for contract fees") else: amount = Decimal(args.amount) * 10**18 -print "Amount transferred " + \ - str((Decimal(amount) / 10 ** 18)) + " to " + encodedPublicKey.encode('hex') +print("Amount transferred", str((Decimal(amount) / 10 ** 18)), + "to", encodedPublicKey.encode('hex')) txData = SPLIT_CONTRACT_FUNCTION txData += "\x00" * 31 @@ -185,9 +186,9 @@ tx = Transaction(tx.nonce, tx.gasprice, tx.startgas, tx.to, tx.value, tx.data, v, r, s) serializedTx = encode(tx) -print "Signed transaction " + serializedTx.encode('hex') +print("Signed transaction", serializedTx.encode('hex')) if (args.broadcast): result = rpc_call(http, "https://api.etherscan.io/api?module=proxy&action=eth_sendRawTransaction&hex=0x" + serializedTx.encode('hex'), "sendRawTransaction") - print result + print(result)