Skip to content
Permalink
Browse files

Merge pull request LedgerHQ#50 from clementperon/dev

Minor Clean / Python3 support
  • Loading branch information...
TamtamHero committed Jan 22, 2019
2 parents 043d1f4 + 52118aa commit d43b530ff1bac20f70728b97256dddc7764febe6
@@ -2,6 +2,6 @@ bin
debug
dep
obj
src_common/glyphs.c
src_common/glyphs.h
src/glyphs.c
src/glyphs.h

This file was deleted.

Oops, something went wrong.
@@ -0,0 +1,74 @@
#!/usr/bin/env python
"""
*******************************************************************************
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************
"""

from rlp.sedes import big_endian_int, binary, Binary
from rlp import Serializable

try:
from Crypto.Hash import keccak

def sha3_256(x): return keccak.new(digest_bits=256, data=x).digest()
except:
import sha3 as _sha3

def sha3_256(x): return _sha3.sha3_256(x).digest()
address = Binary.fixed_length(20, allow_empty=True)


def sha3(seed):
return sha3_256(str(seed))


class Transaction(Serializable):
fields = [
('nonce', big_endian_int),
('gasprice', big_endian_int),
('startgas', big_endian_int),
('to', address),
('value', big_endian_int),
('data', binary),
('v', big_endian_int),
('r', big_endian_int),
('s', big_endian_int),
]

def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0):
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),
]

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,
)
@@ -1,8 +1,8 @@
#!/usr/bin/env python
"""
*******************************************************************************
* Ledger Blue
* (c) 2016 Ledger
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,38 +17,44 @@
* 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 = ""
elements = path.split('/')
for pathElement in elements:
element = pathElement.split('\'')
if len(element) == 1:
result = result + struct.pack(">I", int(element[0]))
else:
result = result + struct.pack(">I", 0x80000000 | int(element[0]))
return result
if len(path) == 0:
return b""
result = b""
elements = path.split('/')
for pathElement in elements:
element = pathElement.split('\'')
if len(element) == 1:
result = result + struct.pack(">I", int(element[0]))
else:
result = result + struct.pack(">I", 0x80000000 | int(element[0]))
return result


parser = argparse.ArgumentParser()
parser.add_argument('--path', help="BIP 32 path to retrieve")
args = parser.parse_args()

if args.path == None:
args.path = "44'/60'/0'/0/0"
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]]
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='')
@@ -1,8 +1,8 @@
#!/usr/bin/env python
"""
*******************************************************************************
* Ledger Blue
* (c) 2016 Ledger
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,28 +22,31 @@
import argparse
import struct


def parse_bip32_path(path):
if len(path) == 0:
return ""
result = ""
elements = path.split('/')
for pathElement in elements:
element = pathElement.split('\'')
if len(element) == 1:
result = result + struct.pack(">I", int(element[0]))
else:
result = result + struct.pack(">I", 0x80000000 | int(element[0]))
return result
if len(path) == 0:
return b""
result = b""
elements = path.split('/')
for pathElement in elements:
element = pathElement.split('\'')
if len(element) == 1:
result = result + struct.pack(">I", int(element[0]))
else:
result = result + struct.pack(">I", 0x80000000 | int(element[0]))
return result


parser = argparse.ArgumentParser()
parser.add_argument('--path', help="BIP 32 path to retrieve")
args = parser.parse_args()

if args.path == None:
args.path = "44'/60'/0'/0/0"
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))
@@ -0,0 +1,97 @@
#!/usr/bin/env python
"""
*******************************************************************************
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* 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
from ethBase import Transaction, UnsignedTransaction, unsigned_tx_from_tx
from rlp import encode

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 b""
result = b""
elements = path.split('/')
for pathElement in elements:
element = pathElement.split('\'')
if len(element) == 1:
result = result + struct.pack(">I", int(element[0]))
else:
result = result + struct.pack(">I", 0x80000000 | int(element[0]))
return result


parser = argparse.ArgumentParser()
parser.add_argument('--nonce', help="Nonce associated to the account", type=int, required=True)
parser.add_argument('--gasprice', help="Network gas price", type=int, required=True)
parser.add_argument('--startgas', help="startgas", default='21000', type=int)
parser.add_argument('--amount', help="Amount to send in ether", type=int, required=True)
parser.add_argument('--to', help="Destination address", type=str, required=True)
parser.add_argument('--path', help="BIP 32 path to sign with")
parser.add_argument('--data', help="Data to add, hex encoded")
args = parser.parse_args()

if args.path == None:
args.path = "44'/60'/0'/0/0"

if args.data == None:
args.data = b""
else:
args.data = decode_hex(args.data[2:])

amount = args.amount * 10**18

tx = Transaction(
nonce=int(args.nonce),
gasprice=int(args.gasprice),
startgas=int(args.startgas),
to=decode_hex(args.to[2:]),
value=int(amount),
data=args.data,
)

encodedTx = encode(unsigned_tx_from_tx(tx), UnsignedTransaction)

donglePath = parse_bip32_path(args.path)
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(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)))
Oops, something went wrong.

0 comments on commit d43b530

Please sign in to comment.
You can’t perform that action at this time.