1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-30 19:38:15 +00:00
trezor-firmware/trezorlib/ethereum.py

86 lines
2.2 KiB
Python
Raw Normal View History

from . import messages as proto
2018-08-13 16:21:24 +00:00
from .tools import CallException, expect, normalize_nfc, session
def int_to_big_endian(value):
2018-08-13 16:21:24 +00:00
return value.to_bytes((value.bit_length() + 7) // 8, "big")
# ====== Client functions ====== #
@expect(proto.EthereumAddress, field="address")
def get_address(client, n, show_display=False, multisig=None):
return client.call(proto.EthereumGetAddress(address_n=n, show_display=show_display))
@session
2018-08-13 16:21:24 +00:00
def sign_tx(
client,
n,
nonce,
gas_price,
gas_limit,
to,
value,
data=None,
chain_id=None,
tx_type=None,
):
msg = proto.EthereumSignTx(
address_n=n,
nonce=int_to_big_endian(nonce),
gas_price=int_to_big_endian(gas_price),
gas_limit=int_to_big_endian(gas_limit),
2018-08-13 16:21:24 +00:00
value=int_to_big_endian(value),
)
if to:
msg.to = to
if data:
msg.data_length = len(data)
data, chunk = data[1024:], data[:1024]
msg.data_initial_chunk = chunk
if chain_id:
msg.chain_id = chain_id
if tx_type is not None:
msg.tx_type = tx_type
response = client.call(msg)
while response.data_length is not None:
data_length = response.data_length
data, chunk = data[data_length:], data[:data_length]
response = client.call(proto.EthereumTxAck(data_chunk=chunk))
2018-08-20 13:51:31 +00:00
# https://github.com/trezor/trezor-core/pull/311
2018-08-15 09:31:30 +00:00
# only signature bit returned. recalculate signature_v
if response.signature_v <= 1:
response.signature_v += 2 * chain_id + 35
return response.signature_v, response.signature_r, response.signature_s
@expect(proto.EthereumMessageSignature)
def sign_message(client, n, message):
message = normalize_nfc(message)
return client.call(proto.EthereumSignMessage(address_n=n, message=message))
def verify_message(client, address, signature, message):
message = normalize_nfc(message)
try:
2018-08-13 16:21:24 +00:00
resp = client.call(
proto.EthereumVerifyMessage(
address=address, signature=signature, message=message
)
)
except CallException as e:
resp = e
if isinstance(resp, proto.Success):
return True
return False