Skip to content

Commit

Permalink
feat(core/cardano): Implement bech32 asset ids based on CIP-0014
Browse files Browse the repository at this point in the history
  • Loading branch information
refi93 authored and matejcik committed Mar 17, 2021
1 parent e254d61 commit 1b4f114
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 43 deletions.
4 changes: 2 additions & 2 deletions common/tests/fixtures/cardano/sign_tx.json
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@
"certificates": [],
"withdrawals": [],
"metadata": "",
"input_flow": [["YES"], ["YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
"input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"]],
"inputs": [
{
"path": "m/1852'/1815'/0'/0/0",
Expand Down Expand Up @@ -711,7 +711,7 @@
"certificates": [],
"withdrawals": [],
"metadata": "",
"input_flow": [["YES"], ["YES"], ["YES"], ["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "SWIPE", "YES"], ["YES"]],
"input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"]],
"inputs": [
{
"path": "m/1852'/1815'/0'/0/0",
Expand Down
13 changes: 13 additions & 0 deletions core/src/apps/cardano/helpers/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from trezor.crypto import hashlib

from apps.cardano.helpers.paths import ACCOUNT_PATH_INDEX, unharden

from . import bech32
Expand Down Expand Up @@ -48,3 +50,14 @@ def format_optional_int(number: Optional[int]) -> str:

def format_stake_pool_id(pool_id_bytes: bytes) -> str:
return bech32.encode("pool", pool_id_bytes)


def format_asset_fingerprint(policy_id: bytes, asset_name_bytes: bytes) -> str:
fingerprint = hashlib.blake2b(
# bytearrays are being promoted to bytes: https://github.com/python/mypy/issues/654
# but bytearrays are not concatenable, this casting works around this limitation
data=bytes(policy_id) + bytes(asset_name_bytes),
outlen=20,
).digest()

return bech32.encode("asset", fingerprint)
56 changes: 18 additions & 38 deletions core/src/apps/cardano/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from .helpers import protocol_magics
from .helpers.utils import (
format_account_number,
format_asset_fingerprint,
format_optional_int,
format_stake_pool_id,
to_account_path,
Expand All @@ -42,7 +43,6 @@
from trezor.messages.CardanoPoolOwnerType import CardanoPoolOwnerType
from trezor.messages.CardanoPoolMetadataType import CardanoPoolMetadataType
from trezor.messages.CardanoAssetGroupType import CardanoAssetGroupType
from trezor.messages.CardanoTokenType import CardanoTokenType
from trezor.messages.CardanoAddressParametersType import EnumTypeCardanoAddressType


Expand Down Expand Up @@ -79,8 +79,7 @@ async def confirm_sending(
token_bundle: List[CardanoAssetGroupType],
to: str,
) -> None:
for token_group in token_bundle:
await confirm_sending_token_group(ctx, token_group)
await confirm_sending_token_bundle(ctx, token_bundle)

page1 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
page1.normal("Confirm sending:")
Expand All @@ -96,42 +95,23 @@ async def confirm_sending(
await require_confirm(ctx, Paginated(pages))


async def confirm_sending_token_group(
ctx: wire.Context, token_group: CardanoAssetGroupType
) -> None:
page1 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
page1.bold("Policy id: ")
page1.mono(hexlify(token_group.policy_id).decode())
await require_confirm(ctx, page1)

for token_number, token in enumerate(token_group.tokens, 1):
if is_printable_ascii_bytestring(token.asset_name_bytes):
await confirm_sending_token_ascii(ctx, token, token_number)
else:
await confirm_sending_token_hex(ctx, token, token_number)


async def confirm_sending_token_ascii(
ctx: wire.Context, token: CardanoTokenType, token_number: int
async def confirm_sending_token_bundle(
ctx: wire.Context, token_bundle: List[CardanoAssetGroupType]
) -> None:
page1 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
page1.normal("Asset #%s name (ASCII):" % (token_number))
page1.bold(token.asset_name_bytes.decode("ascii"))
page1.normal("Amount sent:")
page1.bold(format_amount(token.amount, 0))
await require_confirm(ctx, page1)


async def confirm_sending_token_hex(
ctx: wire.Context, token: CardanoTokenType, token_number: int
) -> None:
page1 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
page1.bold("Asset #%s name (hex):" % (token_number))
page1.mono(hexlify(token.asset_name_bytes).decode())
page2 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
page2.normal("Amount sent:")
page2.bold(format_amount(token.amount, 0))
await require_confirm(ctx, Paginated([page1, page2]))
for token_group in token_bundle:
for token in token_group.tokens:
page1 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
page1.normal("Asset fingerprint:")
page1.bold(
format_asset_fingerprint(
policy_id=token_group.policy_id,
asset_name_bytes=token.asset_name_bytes,
)
)
page2 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
page2.normal("Amount sent:")
page2.bold(format_amount(token.amount, 0))
await require_confirm(ctx, Paginated([page1, page2]))


async def show_warning_tx_output_contains_tokens(ctx: wire.Context) -> None:
Expand Down
14 changes: 13 additions & 1 deletion core/tests/test_apps.cardano.utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from common import *

if not utils.BITCOIN_ONLY:
from apps.cardano.helpers.utils import variable_length_encode
from apps.cardano.helpers.utils import variable_length_encode, format_asset_fingerprint


@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
Expand All @@ -27,6 +27,18 @@ def test_variable_length_encode(self):
def test_variable_length_encode_negative_number(self):
with self.assertRaises(ValueError):
variable_length_encode(-1)

def test_format_asset_fingerprint(self):
# source: https://github.com/cardano-foundation/CIPs/pull/64
test_vectors = [
(("7eae28af2208be856f7a119668ae52a49b73725e326dc16579dcc373", ""), "asset1rjklcrnsdzqp65wjgrg55sy9723kw09mlgvlc3"),
(("7eae28af2208be856f7a119668ae52a49b73725e326dc16579dcc373", "504154415445"), "asset13n25uv0yaf5kus35fm2k86cqy60z58d9xmde92"),
(("1e349c9bdea19fd6c147626a5260bc44b71635f398b67c59881df209", "7eae28af2208be856f7a119668ae52a49b73725e326dc16579dcc373"), "asset1aqrdypg669jgazruv5ah07nuyqe0wxjhe2el6f"),
]

for params, expected in test_vectors:
actual = format_asset_fingerprint(policy_id=unhexlify(params[0]), asset_name_bytes=unhexlify(params[1]))
self.assertEqual(actual, expected)


if __name__ == '__main__':
Expand Down
4 changes: 2 additions & 2 deletions tests/ui_tests/fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_with_multiple_inputs]": "5ba2589aeda7cb2b707b5dd0d40ac26a5abe6eb0c3ec3d47d834701ef07a42bc",
"cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_without_change0]": "5ba2589aeda7cb2b707b5dd0d40ac26a5abe6eb0c3ec3d47d834701ef07a42bc",
"cardano-test_sign_tx.py::test_cardano_sign_tx[mainnet_transaction_without_change1]": "c57c4097446de48b1f79850854a83410816ac05c8a7476452771cdc71e0aeefa",
"cardano-test_sign_tx.py::test_cardano_sign_tx[mary_era_transaction_with_different_policies_-1dbb1bfb": "0f14d371c83adf4ceaa05530581df86eb653b9e8226be61fcd2bc1cc97e3581a",
"cardano-test_sign_tx.py::test_cardano_sign_tx[mary_era_transaction_with_multiasset_output]": "a24edeaaefca10b45235836264b8385148048a23bd34c56570c3de69de4f3d06",
"cardano-test_sign_tx.py::test_cardano_sign_tx[mary_era_transaction_with_different_policies_-1dbb1bfb": "02f8517926fe8d38d96606929df43372d8949e917299199d37e648672fed9256",
"cardano-test_sign_tx.py::test_cardano_sign_tx[mary_era_transaction_with_multiasset_output]": "d0a58ab8b68fcd9f1191f309de52efb6be9157383357f5f9c0e0d116fccc08e4",
"cardano-test_sign_tx.py::test_cardano_sign_tx[mary_era_transaction_with_no_ttl-validity_start]": "db76676358164a3b3dab5148f09ba5515d079212366b79c44f95e2ba613abc71",
"cardano-test_sign_tx.py::test_cardano_sign_tx[sample_stake_pool_registration_certificate]": "f56482d4a0f2c07fe04291a7d9c29ed4aedfd31e6a80fed1563d80e3a4c4005c",
"cardano-test_sign_tx.py::test_cardano_sign_tx[sample_stake_pool_registration_certificate_wi-d3427614": "629ccaa5b660247843b366582c1bc505831c1800e028474a784b0f8b35fc473a",
Expand Down

0 comments on commit 1b4f114

Please sign in to comment.