Merge pull request #50 from clementperon/dev
Minor Clean / Python3 support
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,6 +2,6 @@ bin
|
||||
debug
|
||||
dep
|
||||
obj
|
||||
src_common/glyphs.c
|
||||
src_common/glyphs.h
|
||||
src/glyphs.c
|
||||
src/glyphs.h
|
||||
|
||||
|
||||
51
ethBase.py
51
ethBase.py
@@ -1,51 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 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
|
||||
sha3_256 = lambda x: keccak.new(digest_bits=256, data=x).digest()
|
||||
except:
|
||||
import sha3 as _sha3
|
||||
sha3_256 = lambda x: _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)
|
||||
|
||||
UnsignedTransaction = Transaction.exclude(['v', 'r', 's'])
|
||||
74
examples/ethBase.py
Executable file
74
examples/ethBase.py
Executable file
@@ -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,
|
||||
)
|
||||
42
getPublicKey.py → examples/getPublicKey.py
Normal file → Executable file
42
getPublicKey.py → examples/getPublicKey.py
Normal file → Executable file
@@ -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='')
|
||||
33
setSelfAddress.py → examples/setSelfAddress.py
Normal file → Executable file
33
setSelfAddress.py → examples/setSelfAddress.py
Normal file → Executable file
@@ -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 @@ from ledgerblue.commException import CommException
|
||||
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))
|
||||
97
examples/signTx.py
Executable file
97
examples/signTx.py
Executable file
@@ -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)))
|
||||
194
examples/splitEther.py
Executable file
194
examples/splitEther.py
Executable file
@@ -0,0 +1,194 @@
|
||||
#!/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 requests
|
||||
import json
|
||||
from decimal import Decimal
|
||||
from rlp import encode
|
||||
from rlp.utils import decode_hex, encode_hex, str_to_bytes
|
||||
from ethBase import Transaction, UnsignedTransaction, sha3
|
||||
|
||||
# https://etherscan.io/address/0x5dc8108fc79018113a58328f5283b376b83922ef#code
|
||||
SPLIT_CONTRACT_FUNCTION = decode_hex("9c709343")
|
||||
SPLIT_CONTRACT_ADDRESS = "5dc8108fc79018113a58328f5283b376b83922ef"
|
||||
|
||||
|
||||
def rpc_call(http, url, methodDebug):
|
||||
req = http.get(url)
|
||||
if req.status_code == 200:
|
||||
result = json.loads(req.text)
|
||||
if 'error' in result:
|
||||
raise Exception("Server error - " + methodDebug +
|
||||
" - " + result['error']['message'])
|
||||
return result
|
||||
else:
|
||||
raise Exception("Server error - " + methodDebug +
|
||||
" got status " + req.status)
|
||||
|
||||
|
||||
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 (default : query account)")
|
||||
parser.add_argument(
|
||||
'--gasprice', help="Network gas price (default : query network)")
|
||||
parser.add_argument('--startgas', help="startgas", default='80000')
|
||||
parser.add_argument('--startgas-delta',
|
||||
help="difference applied to startgas if gasprice is automatically fetched", default='1000')
|
||||
parser.add_argument(
|
||||
'--amount', help="Amount to send in ether (default : query amount, use maximum)")
|
||||
parser.add_argument(
|
||||
'--to', help="BIP 32 destination path (default : default ETC path)")
|
||||
parser.add_argument(
|
||||
'--split-to-eth', help="Split to the ETH chain (default : spit to ETC chain)", action='store_true')
|
||||
parser.add_argument(
|
||||
'--path', help="BIP 32 path to sign with (default : default ETH path)")
|
||||
parser.add_argument(
|
||||
'--broadcast', help="Broadcast generated transaction (default : false)", action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.path == None:
|
||||
if args.split_to_eth: # sign from ETC
|
||||
#args.path = "44'/60'/160720'/0'/0"
|
||||
args.path = "44'/60'/0'/0"
|
||||
else: # sign from ETH
|
||||
args.path = "44'/60'/0'/0"
|
||||
|
||||
if args.to == None:
|
||||
if args.split_to_eth: # target ETH
|
||||
args.to = "44'/60'/0'/0"
|
||||
else: # target ETC transitional
|
||||
args.to = "44'/60'/160720'/0'/0"
|
||||
|
||||
dongle = getDongle(True)
|
||||
|
||||
donglePath = parse_bip32_path(args.to)
|
||||
apdu = bytearray.fromhex("e0060000") + chr(len(donglePath) + 1).encode() + \
|
||||
chr(len(donglePath) // 4).encode() + donglePath
|
||||
dongle.exchange(bytes(apdu))
|
||||
|
||||
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 = 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:]
|
||||
|
||||
|
||||
http = None
|
||||
if (args.gasprice == None) or (args.nonce == None) or (args.amount == None) or (args.broadcast):
|
||||
http = requests.session()
|
||||
|
||||
if args.gasprice == None:
|
||||
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))
|
||||
|
||||
if args.nonce == None:
|
||||
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'), " ", args.nonce, sep='')
|
||||
|
||||
if args.amount == None:
|
||||
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 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'))
|
||||
|
||||
txData = SPLIT_CONTRACT_FUNCTION
|
||||
txData += "\x00" * 31
|
||||
if (args.split_to_eth):
|
||||
txData += "\x01"
|
||||
else:
|
||||
txData += "\x00"
|
||||
txData += "\x00" * 12
|
||||
txData += encodedPublicKey
|
||||
|
||||
tx = Transaction(
|
||||
nonce=int(args.nonce),
|
||||
gasprice=int(args.gasprice),
|
||||
startgas=int(args.startgas),
|
||||
to=decode_hex(SPLIT_CONTRACT_ADDRESS),
|
||||
value=int(amount),
|
||||
data=txData
|
||||
)
|
||||
|
||||
encodedTx = encode(tx, UnsignedTransaction)
|
||||
|
||||
donglePath = parse_bip32_path(args.path)
|
||||
apdu = "e0040000".decode('hex') + chr(len(donglePath) + 1 +
|
||||
len(encodedTx)) + chr(len(donglePath) / 4) + donglePath + encodedTx
|
||||
|
||||
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)
|
||||
|
||||
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'))
|
||||
|
||||
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)
|
||||
85
signTx.py
85
signTx.py
@@ -1,85 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 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 ledgerblue.comm import getDongle
|
||||
from ledgerblue.commException import CommException
|
||||
import argparse
|
||||
import struct
|
||||
from decimal import Decimal
|
||||
from ethBase import Transaction, UnsignedTransaction
|
||||
from rlp import encode
|
||||
from rlp.utils import decode_hex, encode_hex, str_to_bytes
|
||||
|
||||
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
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--nonce', help="Nonce associated to the account")
|
||||
parser.add_argument('--gasprice', help="Network gas price")
|
||||
parser.add_argument('--startgas', help="startgas", default='21000')
|
||||
parser.add_argument('--amount', help="Amount to send in ether")
|
||||
parser.add_argument('--to', help="Destination address")
|
||||
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 = ""
|
||||
else:
|
||||
args.data = decode_hex(args.data[2:])
|
||||
|
||||
amount = Decimal(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(tx, UnsignedTransaction)
|
||||
|
||||
donglePath = parse_bip32_path(args.path)
|
||||
apdu = "e0040000".decode('hex') + chr(len(donglePath) + 1 + len(encodedTx)) + chr(len(donglePath) / 4) + 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)
|
||||
|
||||
tx = Transaction(tx.nonce, tx.gasprice, tx.startgas, tx.to, tx.value, tx.data, v, r, s)
|
||||
|
||||
print "Signed transaction " + encode_hex(encode(tx))
|
||||
168
splitEther.py
168
splitEther.py
@@ -1,168 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 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 ledgerblue.comm import getDongle
|
||||
from ledgerblue.commException import CommException
|
||||
import argparse
|
||||
import struct
|
||||
import requests
|
||||
import json
|
||||
from decimal import Decimal
|
||||
from rlp import encode
|
||||
from rlp.utils import decode_hex, encode_hex, str_to_bytes
|
||||
from ethBase import Transaction, UnsignedTransaction, sha3
|
||||
|
||||
# https://etherscan.io/address/0x5dc8108fc79018113a58328f5283b376b83922ef#code
|
||||
SPLIT_CONTRACT_FUNCTION = decode_hex("9c709343")
|
||||
SPLIT_CONTRACT_ADDRESS = "5dc8108fc79018113a58328f5283b376b83922ef"
|
||||
|
||||
def rpc_call(http, url, methodDebug):
|
||||
req = http.get(url)
|
||||
if req.status_code == 200:
|
||||
result = json.loads(req.text)
|
||||
if 'error' in result:
|
||||
raise Exception("Server error - " + methodDebug + " - " + result['error']['message'])
|
||||
return result
|
||||
else:
|
||||
raise Exception("Server error - " + methodDebug + " got status " + req.status)
|
||||
|
||||
|
||||
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
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--nonce', help="Nonce associated to the account (default : query account)")
|
||||
parser.add_argument('--gasprice', help="Network gas price (default : query network)")
|
||||
parser.add_argument('--startgas', help="startgas", default='80000')
|
||||
parser.add_argument('--startgas-delta', help="difference applied to startgas if gasprice is automatically fetched", default='1000')
|
||||
parser.add_argument('--amount', help="Amount to send in ether (default : query amount, use maximum)")
|
||||
parser.add_argument('--to', help="BIP 32 destination path (default : default ETC path)")
|
||||
parser.add_argument('--split-to-eth', help="Split to the ETH chain (default : spit to ETC chain)", action='store_true')
|
||||
parser.add_argument('--path', help="BIP 32 path to sign with (default : default ETH path)")
|
||||
parser.add_argument('--broadcast', help="Broadcast generated transaction (default : false)", action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.path == None:
|
||||
if args.split_to_eth: #sign from ETC
|
||||
#args.path = "44'/60'/160720'/0'/0"
|
||||
args.path = "44'/60'/0'/0"
|
||||
else: #sign from ETH
|
||||
args.path = "44'/60'/0'/0"
|
||||
|
||||
if args.to == None:
|
||||
if args.split_to_eth: #target ETH
|
||||
args.to = "44'/60'/0'/0"
|
||||
else: #target ETC transitional
|
||||
args.to = "44'/60'/160720'/0'/0"
|
||||
|
||||
dongle = getDongle(True)
|
||||
|
||||
donglePath = parse_bip32_path(args.to)
|
||||
apdu = "e0060000".decode('hex') + chr(len(donglePath) + 1) + chr(len(donglePath) / 4) + donglePath
|
||||
dongle.exchange(bytes(apdu))
|
||||
|
||||
apdu = "e0020000".decode('hex') + chr(len(donglePath) + 1) + chr(len(donglePath) / 4) + 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
|
||||
result = dongle.exchange(bytes(apdu))
|
||||
publicKeyFrom = str(result[1 : 1 + result[0]])
|
||||
encodedPublicKeyFrom = sha3(publicKeyFrom[1:])[12:]
|
||||
|
||||
|
||||
http = None
|
||||
if (args.gasprice == None) or (args.nonce == None) or (args.amount == None) or (args.broadcast):
|
||||
http = requests.session()
|
||||
|
||||
if args.gasprice == None:
|
||||
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)
|
||||
|
||||
if args.nonce == None:
|
||||
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)
|
||||
|
||||
if args.amount == None:
|
||||
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)
|
||||
amount -= (int(args.startgas) - int(args.startgas_delta)) * int(args.gasprice)
|
||||
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')
|
||||
|
||||
txData = SPLIT_CONTRACT_FUNCTION
|
||||
txData += "\x00" * 31
|
||||
if (args.split_to_eth):
|
||||
txData += "\x01"
|
||||
else:
|
||||
txData += "\x00"
|
||||
txData += "\x00" * 12
|
||||
txData += encodedPublicKey
|
||||
|
||||
tx = Transaction(
|
||||
nonce=int(args.nonce),
|
||||
gasprice=int(args.gasprice),
|
||||
startgas=int(args.startgas),
|
||||
to=decode_hex(SPLIT_CONTRACT_ADDRESS),
|
||||
value=int(amount),
|
||||
data=txData
|
||||
)
|
||||
|
||||
encodedTx = encode(tx, UnsignedTransaction)
|
||||
|
||||
donglePath = parse_bip32_path(args.path)
|
||||
apdu = "e0040000".decode('hex') + chr(len(donglePath) + 1 + len(encodedTx)) + chr(len(donglePath) / 4) + donglePath + encodedTx
|
||||
|
||||
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)
|
||||
|
||||
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')
|
||||
|
||||
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
|
||||
@@ -1,9 +1,27 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef _CHAIN_CONFIG_H_
|
||||
#define _CHAIN_CONFIG_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#ifndef CHAIN_CONFIG_H
|
||||
|
||||
#define CHAIN_CONFIG_H
|
||||
|
||||
typedef enum chain_kind_e {
|
||||
CHAIN_KIND_ETHEREUM,
|
||||
CHAIN_KIND_ETHEREUM_CLASSIC,
|
||||
@@ -32,7 +50,6 @@ typedef struct chain_config_s {
|
||||
const char* coinName; // ticker
|
||||
uint32_t chainId;
|
||||
chain_kind_t kind;
|
||||
|
||||
#ifdef TARGET_BLUE
|
||||
const char* header_text;
|
||||
unsigned int color_header;
|
||||
@@ -41,5 +58,4 @@ typedef struct chain_config_s {
|
||||
|
||||
} chain_config_t;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _CHAIN_CONFIG_H_ */
|
||||
|
||||
77
src/main.c
77
src/main.c
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
@@ -15,9 +15,12 @@
|
||||
* limitations under the License.
|
||||
********************************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "cx.h"
|
||||
#include "stdbool.h"
|
||||
#include "ethUstream.h"
|
||||
#include "ethUtils.h"
|
||||
#include "uint256.h"
|
||||
@@ -25,16 +28,12 @@
|
||||
#include "chainConfig.h"
|
||||
|
||||
#include "os_io_seproxyhal.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "glyphs.h"
|
||||
|
||||
#define __NAME3(a, b, c) a##b##c
|
||||
#define NAME3(a, b, c) __NAME3(a, b, c)
|
||||
#include "utils.h"
|
||||
|
||||
unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B];
|
||||
|
||||
|
||||
unsigned int io_seproxyhal_touch_settings(const bagl_element_t *e);
|
||||
unsigned int io_seproxyhal_touch_exit(const bagl_element_t *e);
|
||||
unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e);
|
||||
@@ -167,21 +166,8 @@ static const char const CONTRACT_ADDRESS[] = "New contract";
|
||||
static const char const SIGN_MAGIC[] = "\x19"
|
||||
"Ethereum Signed Message:\n";
|
||||
|
||||
const unsigned char hex_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
chain_config_t *chainConfig;
|
||||
|
||||
void array_hexstr(char *strbuf, const void *bin, unsigned int len) {
|
||||
while (len--) {
|
||||
*strbuf++ = hex_digits[((*((char *)bin)) >> 4) & 0xF];
|
||||
*strbuf++ = hex_digits[(*((char *)bin)) & 0xF];
|
||||
bin = (const void *)((unsigned int)bin + 1);
|
||||
}
|
||||
*strbuf = 0; // EOS
|
||||
}
|
||||
|
||||
|
||||
const bagl_element_t* ui_menu_item_out_over(const bagl_element_t* e) {
|
||||
// the selection rectangle is after the none|touchable
|
||||
e = (const bagl_element_t*)(((unsigned int)e)+sizeof(bagl_element_t));
|
||||
@@ -238,9 +224,6 @@ const bagl_element_t ui_idle_blue[] = {
|
||||
{{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 0, 19, 56, 44, 0, 0, BAGL_FILL, COLOR_APP, COLOR_APP_LIGHT, BAGL_FONT_SYMBOLS_0|BAGL_FONT_ALIGNMENT_CENTER|BAGL_FONT_ALIGNMENT_MIDDLE, 0 }, BAGL_FONT_SYMBOLS_0_SETTINGS, 0, COLOR_APP, 0xFFFFFF, io_seproxyhal_touch_settings, NULL, NULL},
|
||||
{{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 264, 19, 56, 44, 0, 0, BAGL_FILL, COLOR_APP, COLOR_APP_LIGHT, BAGL_FONT_SYMBOLS_0|BAGL_FONT_ALIGNMENT_CENTER|BAGL_FONT_ALIGNMENT_MIDDLE, 0 }, BAGL_FONT_SYMBOLS_0_DASHBOARD, 0, COLOR_APP, 0xFFFFFF, io_seproxyhal_touch_exit, NULL, NULL},
|
||||
|
||||
// BADGE_<CHAINID>.GIF
|
||||
//{{BAGL_ICON , 0x00, 135, 178, 50, 50, 0, 0, BAGL_FILL, 0 , COLOR_BG_1, 0 ,0 } , &NAME3(C_blue_badge_, CHAINID, ), 0, 0, 0, NULL, NULL, NULL },
|
||||
|
||||
{{BAGL_LABELINE , 0x00, 0, 270, 320, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_LIGHT_16_22PX|BAGL_FONT_ALIGNMENT_CENTER, 0 }, "Open your wallet", 0, 0, 0, NULL, NULL, NULL},
|
||||
{{BAGL_LABELINE , 0x00, 0, 308, 320, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX|BAGL_FONT_ALIGNMENT_CENTER, 0 }, "Connect your Ledger Blue and open your", 0, 0, 0, NULL, NULL, NULL},
|
||||
{{BAGL_LABELINE , 0x00, 0, 331, 320, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX|BAGL_FONT_ALIGNMENT_CENTER, 0 }, "preferred wallet to view your accounts.", 0, 0, 0, NULL, NULL, NULL},
|
||||
@@ -318,7 +301,6 @@ const ux_menu_entry_t menu_about[] = {
|
||||
};
|
||||
|
||||
const ux_menu_entry_t menu_main[] = {
|
||||
//{NULL, NULL, 0, &NAME3(C_nanos_badge_, CHAINID, ), "Use wallet to", "view accounts", 33, 12},
|
||||
{NULL, NULL, 0, NULL, "Use wallet to", "view accounts", 0, 0},
|
||||
{menu_settings, NULL, 0, NULL, "Settings", NULL, 0, 0},
|
||||
{menu_about, NULL, 0, NULL, "About", NULL, 0, 0},
|
||||
@@ -971,17 +953,6 @@ const bagl_element_t ui_data_parameter_blue[] = {
|
||||
{{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0,18, BAGL_FILL, 0x41ccb4, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_11_14PX|BAGL_FONT_ALIGNMENT_CENTER|BAGL_FONT_ALIGNMENT_MIDDLE, 0 }, "CONFIRM", 0, 0x3ab7a2, COLOR_BG_1, io_seproxyhal_touch_data_ok, NULL, NULL},
|
||||
};
|
||||
|
||||
int local_strchr(char *string, char ch) {
|
||||
unsigned int length = strlen(string);
|
||||
unsigned int i;
|
||||
for (i=0; i<length; i++) {
|
||||
if (string[i] == ch) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int ui_data_parameter_blue_prepro(const bagl_element_t* element) {
|
||||
copy_element_and_map_coin_colors(element);
|
||||
if(element->component.userid > 0) {
|
||||
@@ -1114,33 +1085,6 @@ unsigned int ui_address_nanos_button(unsigned int button_mask, unsigned int butt
|
||||
}
|
||||
#endif // #if defined(TARGET_NANOS)
|
||||
|
||||
uint32_t getV(txContent_t *txContent) {
|
||||
uint32_t v = 0;
|
||||
if (txContent->vLength == 1) {
|
||||
v = txContent->v[0];
|
||||
}
|
||||
else
|
||||
if (txContent->vLength == 2) {
|
||||
v = (txContent->v[0] << 8) | txContent->v[1];
|
||||
}
|
||||
else
|
||||
if (txContent->vLength == 3) {
|
||||
v = (txContent->v[0] << 16) | (txContent->v[1] << 8) | txContent->v[2];
|
||||
}
|
||||
else
|
||||
if (txContent->vLength == 4) {
|
||||
v = (txContent->v[0] << 24) | (txContent->v[1] << 16) |
|
||||
(txContent->v[2] << 8) | txContent->v[3];
|
||||
}
|
||||
else
|
||||
if (txContent->vLength != 0) {
|
||||
PRINTF("Unexpected v format\n");
|
||||
THROW(EXCEPTION);
|
||||
}
|
||||
return v;
|
||||
|
||||
}
|
||||
|
||||
void io_seproxyhal_send_status(uint32_t sw) {
|
||||
G_io_apdu_buffer[0] = ((sw >> 8) & 0xff);
|
||||
G_io_apdu_buffer[1] = (sw & 0xff);
|
||||
@@ -1429,13 +1373,6 @@ uint32_t set_result_get_publicKey() {
|
||||
return tx;
|
||||
}
|
||||
|
||||
void convertUint256BE(uint8_t *data, uint32_t length, uint256_t *target) {
|
||||
uint8_t tmp[32];
|
||||
os_memset(tmp, 0, 32);
|
||||
os_memmove(tmp + 32 - length, data, length);
|
||||
readu256BE(tmp, target);
|
||||
}
|
||||
|
||||
uint32_t splitBinaryParameterPart(char *result, uint8_t *parameter) {
|
||||
uint32_t i;
|
||||
for (i=0; i<8; i++) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
|
||||
11
src/tokens.h
11
src/tokens.h
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
@@ -15,7 +15,10 @@
|
||||
* limitations under the License.
|
||||
********************************************************************************/
|
||||
|
||||
#include "os.h"
|
||||
#ifndef _TOKENS_H_
|
||||
#define _TOKENS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct tokenDefinition_t {
|
||||
uint8_t address[20];
|
||||
@@ -66,3 +69,5 @@ extern tokenDefinition_t const TOKENS_GOCHAIN[NUM_TOKENS_GOCHAIN];
|
||||
extern tokenDefinition_t const TOKENS_MIX[NUM_TOKENS_MIX];
|
||||
extern tokenDefinition_t const TOKENS_REOSC[NUM_TOKENS_REOSC];
|
||||
extern tokenDefinition_t const TOKENS_HPB[NUM_TOKENS_HPB];
|
||||
|
||||
#endif /* _TOKENS_H_ */
|
||||
|
||||
78
src/utils.c
Normal file
78
src/utils.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
********************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ethUstream.h"
|
||||
#include "uint256.h"
|
||||
|
||||
static const unsigned char hex_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
void array_hexstr(char *strbuf, const void *bin, unsigned int len) {
|
||||
while (len--) {
|
||||
*strbuf++ = hex_digits[((*((char *)bin)) >> 4) & 0xF];
|
||||
*strbuf++ = hex_digits[(*((char *)bin)) & 0xF];
|
||||
bin = (const void *)((unsigned int)bin + 1);
|
||||
}
|
||||
*strbuf = 0; // EOS
|
||||
}
|
||||
|
||||
void convertUint256BE(uint8_t *data, uint32_t length, uint256_t *target) {
|
||||
uint8_t tmp[32];
|
||||
os_memset(tmp, 0, 32);
|
||||
os_memmove(tmp + 32 - length, data, length);
|
||||
readu256BE(tmp, target);
|
||||
}
|
||||
|
||||
int local_strchr(char *string, char ch) {
|
||||
unsigned int length = strlen(string);
|
||||
unsigned int i;
|
||||
for (i=0; i<length; i++) {
|
||||
if (string[i] == ch) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t getV(txContent_t *txContent) {
|
||||
uint32_t v = 0;
|
||||
if (txContent->vLength == 1) {
|
||||
v = txContent->v[0];
|
||||
}
|
||||
else
|
||||
if (txContent->vLength == 2) {
|
||||
v = (txContent->v[0] << 8) | txContent->v[1];
|
||||
}
|
||||
else
|
||||
if (txContent->vLength == 3) {
|
||||
v = (txContent->v[0] << 16) | (txContent->v[1] << 8) | txContent->v[2];
|
||||
}
|
||||
else
|
||||
if (txContent->vLength == 4) {
|
||||
v = (txContent->v[0] << 24) | (txContent->v[1] << 16) |
|
||||
(txContent->v[2] << 8) | txContent->v[3];
|
||||
}
|
||||
else
|
||||
if (txContent->vLength != 0) {
|
||||
PRINTF("Unexpected v format\n");
|
||||
THROW(EXCEPTION);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
33
src/utils.h
Normal file
33
src/utils.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef _UTILS_H_
|
||||
#define _UTILS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "uint256.h"
|
||||
|
||||
void array_hexstr(char *strbuf, const void *bin, unsigned int len);
|
||||
|
||||
void convertUint256BE(uint8_t *data, uint32_t length, uint256_t *target);
|
||||
|
||||
int local_strchr(char *string, char ch);
|
||||
|
||||
uint32_t getV(txContent_t *txContent);
|
||||
|
||||
#endif /* _UTILS_H_ */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
@@ -15,6 +15,8 @@
|
||||
* limitations under the License.
|
||||
********************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ethUstream.h"
|
||||
#include "ethUtils.h"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
@@ -15,9 +15,14 @@
|
||||
* limitations under the License.
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef _ETHUSTREAM_H_
|
||||
#define _ETHUSTREAM_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "cx.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
struct txContext_t;
|
||||
|
||||
@@ -96,3 +101,5 @@ parserStatus_e processTx(txContext_t *context, uint8_t *buffer,
|
||||
parserStatus_e continueTx(txContext_t *context);
|
||||
void copyTxData(txContext_t *context, uint8_t *out, uint32_t length);
|
||||
uint8_t readTxByte(txContext_t *context);
|
||||
|
||||
#endif /* _ETHUSTREAM_H_ */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
@@ -23,9 +23,12 @@
|
||||
* @date 8th of March 2016
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "cx.h"
|
||||
#include <stdbool.h>
|
||||
#include "ethUtils.h"
|
||||
#include "chainConfig.h"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
@@ -15,7 +15,11 @@
|
||||
* limitations under the License.
|
||||
********************************************************************************/
|
||||
|
||||
#include "os.h"
|
||||
#ifndef _ETHUTILS_H_
|
||||
#define _ETHUTILS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cx.h"
|
||||
|
||||
/**
|
||||
@@ -46,3 +50,5 @@ void getEthAddressStringFromBinary(uint8_t *address, uint8_t *out,
|
||||
|
||||
bool adjustDecimals(char *src, uint32_t srcLength, char *target,
|
||||
uint32_t targetLength, uint8_t decimals);
|
||||
|
||||
#endif /* _ETHUTILS_H_ */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "uint256.h"
|
||||
|
||||
static const char HEXDIGITS[] = "0123456789abcdef";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* 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,6 +17,9 @@
|
||||
|
||||
// Adapted from https://github.com/calccrypto/uint256_t
|
||||
|
||||
#ifndef _UINT256_H_
|
||||
#define _UINT256_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -63,3 +66,5 @@ bool tostring128(uint128_t *number, uint32_t base, char *out,
|
||||
uint32_t outLength);
|
||||
bool tostring256(uint256_t *number, uint32_t base, char *out,
|
||||
uint32_t outLength);
|
||||
|
||||
#endif /* _UINT256_H_ */
|
||||
Reference in New Issue
Block a user