Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion common/protob/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@
for fn in sorted(glob(os.path.join(MYDIR, "messages-*.proto"))):
with open(fn, "rt") as f:
prefix = EXPECTED_PREFIX_RE.search(fn).group(1).capitalize()
if prefix in ("Bitcoin", "Bootloader", "Common", "Crypto", "Management", "Ton"):
if prefix in (
"Bitcoin",
"Bootloader",
"Common",
"Crypto",
"Management",
"Ton",
"Tron",
):
continue
if prefix == "Nem":
prefix = "NEM"
Expand Down
16 changes: 15 additions & 1 deletion common/protob/messages-tron.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ message TronSignTx {
required bytes ref_block_bytes = 2; // Reference block number
required bytes ref_block_hash = 3; // Reference block hash
required uint64 expiration = 4; // Transaction expiration
optional string data = 5; // Extra transaction info
optional bytes data = 5; // Extra transaction info
required TronContract contract = 6; // Contract messages
required uint64 timestamp = 7; // UTC timestamp
optional uint64 fee_limit = 8; // Fee limit for smartcontracts
Expand Down Expand Up @@ -63,6 +63,7 @@ message TronSignTx {
enum TronResourceCode {
BANDWIDTH = 0x00;
ENERGY = 0x01;
TRON_POWER = 0x02;
}

// Freeze TRX balance
Expand Down Expand Up @@ -105,7 +106,17 @@ message TronSignTx {
optional string receiver_address = 4;
}

// Vote Witness Contract
message TronVoteWitnessContract {
message Vote {
required string vote_address = 1;
required uint32 vote_count = 2;
}
repeated Vote votes = 2;
optional bool support = 3;
}
optional TronTransferContract transfer_contract = 2;
optional TronVoteWitnessContract vote_witness_contract = 4;
optional TronFreezeBalanceContract freeze_balance_contract = 11;
optional TronUnfreezeBalanceContract unfreeze_balance_contract = 12;
optional TronWithdrawBalanceContract withdraw_balance_contract = 13;
Expand All @@ -115,6 +126,9 @@ message TronSignTx {
optional TronWithdrawExpireUnfreezeContract withdraw_expire_unfreeze_contract = 56;
optional TronDelegateResourceContract delegate_resource_contract = 57;
optional TronUnDelegateResourceContract undelegate_resource_contract = 58;
optional bytes provider = 3;
optional bytes contract_name = 5;
optional uint32 permission_id = 6;
}
}

Expand Down
8 changes: 4 additions & 4 deletions core/src/apps/tron/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
from trezor.crypto.hashlib import sha3_256


def get_address_from_public_key(pubkey):
def get_address_from_public_key(pubkey: bytes) -> str:
address = b"\x41" + sha3_256(pubkey[1:65], keccak=True).digest()[12:32]
return _address_base58(address)
return address_base58(address)


def _address_base58(address):
def address_base58(address: bytes) -> str:
return base58.encode_check(address)


def address_to_bytes(address):
def address_to_bytes(address: str) -> bytes:
return base58.decode_check(address)
27 changes: 18 additions & 9 deletions core/src/apps/tron/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from trezor.strings import format_amount
from trezor.ui.layouts import confirm_address, confirm_output, should_show_details
from trezor.ui.layouts.lvgl.altcoin import confirm_total_tron
from trezor.utils import chunks

from . import tokens

Expand Down Expand Up @@ -236,6 +235,24 @@ def require_confirm_undelegate(
)


def require_confirm_vote_witness(
ctx: Context,
signer: str,
votes: list[tuple[str, int]],
support: bool | None,
) -> Awaitable[None]:
from trezor.ui.layouts.lvgl import confirm_tron_vote

return confirm_tron_vote(
ctx,
"Vote for Witness"
if (support is None or support)
else "Remove Vote for Witness",
signer,
votes,
)


def format_amount_trx(value: int, token: tokens.TokenInfo | None) -> str:
if token:
suffix = token.symbol
Expand All @@ -245,11 +262,3 @@ def format_amount_trx(value: int, token: tokens.TokenInfo | None) -> str:
decimals = 6

return f"{format_amount(value, decimals)} {suffix}"


def split_address(address):
return chunks(address, 16)


def split_text(text):
return chunks(text, 18)
101 changes: 64 additions & 37 deletions core/src/apps/tron/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
# PROTOBUF3 types
TYPE_VARINT = 0
TYPE_DOUBLE = 1
TYPE_STRING = 2
TYPE_GROUPS = 3
TYPE_GROUPE = 4
TYPE_LEN = 2
TYPE_FLOAT = 5


Expand Down Expand Up @@ -56,22 +54,39 @@ def pack_contract(contract, owner_address):
write_varint(retc, 1)
api = "TransferContract"

add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))
add_field(cmessage, 2, TYPE_STRING)
add_field(cmessage, 2, TYPE_LEN)
write_bytes_with_length(
cmessage, base58.decode_check(contract.transfer_contract.to_address)
)
add_field(cmessage, 3, TYPE_VARINT)
write_varint(cmessage, contract.transfer_contract.amount)
elif contract.vote_witness_contract:
write_varint(retc, 4)
api = "VoteWitnessContract"

if contract.trigger_smart_contract:
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))
for vote in contract.vote_witness_contract.votes:
v_message = bytearray()
add_field(cmessage, 2, TYPE_LEN)
add_field(v_message, 1, TYPE_LEN)
write_bytes_with_length(v_message, base58.decode_check(vote.vote_address))
add_field(v_message, 2, TYPE_VARINT)
write_varint(v_message, vote.vote_count)
write_bytes_with_length(cmessage, v_message)
if contract.vote_witness_contract.support is not None:
add_field(cmessage, 3, TYPE_VARINT)
write_varint(cmessage, int(contract.vote_witness_contract.support))

elif contract.trigger_smart_contract:
write_varint(retc, 31)
api = "TriggerSmartContract"

add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))
add_field(cmessage, 2, TYPE_STRING)
add_field(cmessage, 2, TYPE_LEN)
write_bytes_with_length(
cmessage,
base58.decode_check(contract.trigger_smart_contract.contract_address),
Expand All @@ -81,7 +96,7 @@ def pack_contract(contract, owner_address):
write_varint(cmessage, contract.trigger_smart_contract.call_value)

# Contract data
add_field(cmessage, 4, TYPE_STRING)
add_field(cmessage, 4, TYPE_LEN)
write_bytes_with_length(cmessage, contract.trigger_smart_contract.data)

if contract.trigger_smart_contract.call_token_value:
Expand All @@ -90,11 +105,11 @@ def pack_contract(contract, owner_address):
add_field(cmessage, 6, TYPE_VARINT)
write_varint(cmessage, contract.trigger_smart_contract.asset_id)

if contract.freeze_balance_contract:
elif contract.freeze_balance_contract:
write_varint(retc, 11)
api = "FreezeBalanceContract"

add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))
add_field(cmessage, 2, TYPE_VARINT)
write_varint(cmessage, contract.freeze_balance_contract.frozen_balance)
Expand All @@ -104,41 +119,41 @@ def pack_contract(contract, owner_address):
add_field(cmessage, 4, TYPE_VARINT)
write_varint(cmessage, contract.freeze_balance_contract.resource)
if contract.freeze_balance_contract.receiver_address is not None:
add_field(cmessage, 5, TYPE_STRING)
add_field(cmessage, 5, TYPE_LEN)
write_bytes_with_length(
cmessage,
base58.decode_check(contract.freeze_balance_contract.receiver_address),
)

if contract.unfreeze_balance_contract:
elif contract.unfreeze_balance_contract:
write_varint(retc, 12)
api = "UnfreezeBalanceContract"

add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))

if contract.unfreeze_balance_contract.resource is not None:
add_field(cmessage, 2, TYPE_VARINT)
write_varint(cmessage, contract.unfreeze_balance_contract.resource)
if contract.unfreeze_balance_contract.receiver_address is not None:
add_field(cmessage, 3, TYPE_STRING)
add_field(cmessage, 3, TYPE_LEN)
write_bytes_with_length(
cmessage,
base58.decode_check(
contract.unfreeze_balance_contract.receiver_address
),
)

if contract.withdraw_balance_contract:
elif contract.withdraw_balance_contract:
write_varint(retc, 13)
api = "WithdrawBalanceContract"
add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))

if contract.freeze_balance_v2_contract:
elif contract.freeze_balance_v2_contract:
write_varint(retc, 54)
api = "FreezeBalanceV2Contract"
add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))

add_field(cmessage, 2, TYPE_VARINT)
Expand All @@ -147,10 +162,10 @@ def pack_contract(contract, owner_address):
add_field(cmessage, 3, TYPE_VARINT)
write_varint(cmessage, contract.freeze_balance_v2_contract.resource)

if contract.unfreeze_balance_v2_contract:
elif contract.unfreeze_balance_v2_contract:
write_varint(retc, 55)
api = "UnfreezeBalanceV2Contract"
add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))

add_field(cmessage, 2, TYPE_VARINT)
Expand All @@ -159,23 +174,23 @@ def pack_contract(contract, owner_address):
add_field(cmessage, 3, TYPE_VARINT)
write_varint(cmessage, contract.unfreeze_balance_v2_contract.resource)

if contract.withdraw_expire_unfreeze_contract:
elif contract.withdraw_expire_unfreeze_contract:
write_varint(retc, 56)
api = "WithdrawExpireUnfreezeContract"
add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))

if contract.delegate_resource_contract:
elif contract.delegate_resource_contract:
write_varint(retc, 57)
api = "DelegateResourceContract"
add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))

add_field(cmessage, 2, TYPE_VARINT)
write_varint(cmessage, contract.delegate_resource_contract.resource)
add_field(cmessage, 3, TYPE_VARINT)
write_varint(cmessage, contract.delegate_resource_contract.balance)
add_field(cmessage, 4, TYPE_STRING)
add_field(cmessage, 4, TYPE_LEN)
write_bytes_with_length(
cmessage,
base58.decode_check(contract.delegate_resource_contract.receiver_address),
Expand All @@ -184,55 +199,67 @@ def pack_contract(contract, owner_address):
add_field(cmessage, 5, TYPE_VARINT)
write_varint(cmessage, contract.delegate_resource_contract.lock)

if contract.undelegate_resource_contract:
elif contract.undelegate_resource_contract:
write_varint(retc, 58)
api = "UnDelegateResourceContract"
add_field(cmessage, 1, TYPE_STRING)
add_field(cmessage, 1, TYPE_LEN)
write_bytes_with_length(cmessage, base58.decode_check(owner_address))

add_field(cmessage, 2, TYPE_VARINT)
write_varint(cmessage, contract.undelegate_resource_contract.resource)
add_field(cmessage, 3, TYPE_VARINT)
write_varint(cmessage, contract.undelegate_resource_contract.balance)
add_field(cmessage, 4, TYPE_STRING)
add_field(cmessage, 4, TYPE_LEN)
write_bytes_with_length(
cmessage,
base58.decode_check(contract.undelegate_resource_contract.receiver_address),
)
else:
raise ValueError("Invalid contract type")

# write API
capi = bytearray()
add_field(capi, 1, TYPE_STRING)
add_field(capi, 1, TYPE_LEN)
# write_bytes_with_length(capi, "type.googleapis.com/protocol." + api)
write_bytes_with_length(capi, bytes("type.googleapis.com/protocol." + api, "ascii"))

# extend to capi
add_field(capi, 2, TYPE_STRING)
add_field(capi, 2, TYPE_LEN)
write_bytes_with_length(capi, cmessage)

# extend to contract
add_field(retc, 2, TYPE_STRING)
add_field(retc, 2, TYPE_LEN)
write_bytes_with_length(retc, capi)

if contract.provider:
add_field(retc, 3, TYPE_LEN)
write_bytes_with_length(retc, contract.provider)
if contract.contract_name:
add_field(retc, 4, TYPE_LEN)
write_bytes_with_length(retc, contract.contract_name)
if contract.permission_id is not None:
add_field(retc, 5, TYPE_VARINT)
write_varint(retc, contract.permission_id)
return retc


def serialize(transaction: TronSignTx, owner_address: str):
# transaction parameters
ret = bytearray()
add_field(ret, 1, TYPE_STRING)
add_field(ret, 1, TYPE_LEN)
write_bytes_with_length(ret, transaction.ref_block_bytes)
add_field(ret, 4, TYPE_STRING)
add_field(ret, 4, TYPE_LEN)
write_bytes_with_length(ret, transaction.ref_block_hash)
add_field(ret, 8, TYPE_VARINT)
write_varint(ret, transaction.expiration)
if transaction.data is not None:
add_field(ret, 10, TYPE_STRING)
write_bytes_with_length(ret, bytes(transaction.data, "ascii"))
add_field(ret, 10, TYPE_LEN)
write_bytes_with_length(ret, transaction.data)

# add Contract
retc = pack_contract(transaction.contract, owner_address)

add_field(ret, 11, TYPE_STRING)
add_field(ret, 11, TYPE_LEN)
write_bytes_with_length(ret, retc)
# add timestamp
add_field(ret, 14, TYPE_VARINT)
Expand Down
Loading
Loading