Merge pull request #62 from Arachnid/ethereum_send_tx

Implement ethereum_send_tx
This commit is contained in:
Pavol Rusnak 2016-05-27 20:49:21 +02:00
commit 6696dcb985

View File

@ -10,6 +10,28 @@ from io import BytesIO
from trezorlib.client import TrezorClient, TrezorClientDebug
ether_units = {
"wei": 1,
"kwei": 1000,
"babbage": 1000,
"femtoether": 1000,
"mwei": 1000000,
"lovelace": 1000000,
"picoether": 1000000,
"gwei": 1000000000,
"shannon": 1000000000,
"nanoether": 1000000000,
"nano": 1000000000,
"szabo": 1000000000000,
"microether": 1000000000000,
"micro": 1000000000000,
"finney": 1000000000000000,
"milliether": 1000000000000000,
"milli": 1000000000000000,
"ether": 1000000000000000000,
"eth": 1000000000000000000,
}
def parse_args(commands):
parser = argparse.ArgumentParser(description='Commandline tool for TREZOR devices.')
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='Prints communication to device')
@ -103,6 +125,58 @@ class Commands(object):
address = self.client.ethereum_get_address(address_n, args.show_display)
return "0x%s" % (binascii.hexlify(address),)
def ethereum_send_tx(self, args):
from ethjsonrpc import EthJsonRpc
from ethjsonrpc.utils import hex_to_dec
import rlp
if not args.to:
raise Exception("Please provide to address in hex format")
value = args.value
if ' ' in value:
value, unit = value.split(' ', 1)
if unit.lower() not in ether_units:
raise Exception("Unrecognized ether unit %r", unit)
value = int(value) * ether_units[unit.lower()]
else:
value = int(value)
if args.to.startswith('0x') or args.to.startswith('0X'):
to_address = args.to[2:].decode('hex')
else:
to_address = args.to.decode('hex')
address_n = self.client.expand_path(args.n)
address = "0x%s" % (binascii.hexlify(self.client.ethereum_get_address(address_n)),)
host, port = args.host.split(':')
eth = EthJsonRpc(host, int(port))
gas_price = eth.eth_gasPrice()
gas_limit = args.gas
if not gas_limit:
gas_limit = hex_to_dec(eth.eth_estimateGas(
to_address=args.to,
from_address=address,
value=value,
data=args.data))
nonce = eth.eth_getTransactionCount(address)
sig = self.client.ethereum_sign_tx(
n=address_n,
nonce=nonce,
gas_price=gas_price,
gas_limit=gas_limit,
to=to_address,
value=value,
data=args.data)
transaction = rlp.encode(
(nonce, gas_price, gas_limit, hex_to_dec(args.to), value, args.data) + sig)
tx_hash = eth.eth_sendRawTransaction("0x%s" % (binascii.hexlify(transaction),))
return "Transaction sent with ID %s" % (tx_hash,)
def get_entropy(self, args):
return binascii.hexlify(self.client.get_entropy(args.size))
@ -250,6 +324,7 @@ class Commands(object):
ping.help = 'Send ping message'
get_address.help = 'Get bitcoin address in base58 encoding'
ethereum_get_address.help = 'Get Ethereum address in hex encoding'
ethereum_send_tx.help = 'Sign and publish Ethereum transaction'
get_entropy.help = 'Get example entropy'
get_features.help = 'Retrieve device features and settings'
get_public_node.help = 'Get public node of given path'
@ -281,6 +356,15 @@ class Commands(object):
(('-d', '--show-display'), {'action': 'store_true', 'default': False}),
)
ethereum_send_tx.arguments = (
(('-a', '--host'), {'type': str, 'default': 'localhost:8545'}),
(('-n', '-address'), {'type': str}),
(('-v', '--value'), {'type': str, 'default': "0"}),
(('-g', '--gas'), {'type': int}),
(('-d', '--data'), {'type': str, 'default': ''}),
(('to',), {'type': str}),
)
get_entropy.arguments = (
(('size',), {'type': int}),
)