Skip to content

Commit

Permalink
feat(cardano): allow device-owned outputs in plutus txs
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmisiak committed Mar 11, 2022
1 parent f6aa620 commit 7513776
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 44 deletions.
51 changes: 50 additions & 1 deletion common/tests/fixtures/cardano/sign_tx.json
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@
}
},
{
"description": "simple transaction with base script address change output",
"description": "simple transaction with base script address and change output",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
Expand Down Expand Up @@ -418,6 +418,55 @@
]
}
},
{
"description": "simple transaction with base address change output with staking script hash",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
"fee": 42,
"ttl": 10,
"certificates": [],
"withdrawals": [],
"auxiliary_data": null,
"inputs": [
{
"path": "m/1852'/1815'/0'/0/0",
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"prev_index": 0
}
],
"outputs": [
{
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
"amount": "1"
},
{
"addressType": 2,
"path": "m/1852'/1815'/0'/0/0",
"scriptStakingHash": "8d7bebc7a58f1c7b5fb7c9391071ecd3b51b032695522f8c555343a9",
"amount": "7120787"
}
],
"mint": [],
"script_data_hash": null,
"collateral_inputs": [],
"required_signers": [],
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"tx_hash": "1d6fc2044d54d4af5b44e4be4c1ce3670fe4d2e37523a945d087252c27b215f2",
"witnesses": [
{
"type": 1,
"pub_key": "5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1",
"signature": "d301e21dccbc0cf5122629476795f993eb14160ca22a590d5e1ac3bf6996f3bd35c83646c1c8eacbb2dac3367f27e057a340aa19e77e008851274fdb19ab000f",
"chain_code": null
}
]
}
},
{
"description": "simple transaction with pointer address change output",
"parameters": {
Expand Down
8 changes: 4 additions & 4 deletions common/tests/fixtures/cardano/sign_tx.plutus.failed.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
}
},
{
"description": "Plutus transaction with output containing address parameters",
"description": "Plutus transaction with output containing forbidden address parameters",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
Expand All @@ -63,8 +63,8 @@
],
"outputs": [
{
"addressType": 0,
"path": "m/1852'/1815'/0'/0/0",
"addressType": 1,
"scriptPaymentHash": "8d7bebc7a58f1c7b5fb7c9391071ecd3b51b032695522f8c555343a9",
"stakingPath": "m/1852'/1815'/0'/2/0",
"amount": "7120787"
}
Expand All @@ -84,7 +84,7 @@
"include_network_id": false
},
"result": {
"error_message": "Invalid output"
"error_message": "Invalid address parameters"
}
},
{
Expand Down
150 changes: 150 additions & 0 deletions common/tests/fixtures/cardano/sign_tx.plutus.json
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,156 @@
}
]
}
},
{
"description": "Plutus transaction with base address device-owned output",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
"fee": 42,
"ttl": 10,
"certificates": [],
"withdrawals": [],
"auxiliary_data": null,
"inputs": [
{
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"prev_index": 0
}
],
"outputs": [
{
"addressType": 0,
"path": "m/1852'/1815'/0'/0/0",
"stakingPath": "m/1852'/1815'/0'/2/0",
"amount": "7120787"
}
],
"mint": [],
"script_data_hash": "d593fd793c377ac50a3169bb8378ffc257c944da31aa8f355dfa5a4f6ff89e02",
"collateral_inputs": [
{
"path": "m/1852'/1815'/0'/0/0",
"prev_hash": "1af8fa0b754ff99253d983894e63a2b09cbb56c833ba18c3384210163f63dcfc",
"prev_index": 0
}
],
"required_signers": [],
"signing_mode": "PLUTUS_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"tx_hash": "5581fb7a99b8e0ebaf552a5d7157cebb37c9624602d78d86337dfbf838fb2e13",
"witnesses": [
{
"type": 1,
"pub_key": "5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1",
"signature": "9f5432c85adaf7191e77388a75ff4ee57ce86b382e99b561e1e2dbcb263732bfcc5a726f268d3a5833e37468e1c7baa64ffd88044b59b3f7b67d59502108be0c",
"chain_code": null
}
]
}
},
{
"description": "Plutus transaction with base address device-owned output with path mismatch",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
"fee": 42,
"ttl": 10,
"certificates": [],
"withdrawals": [],
"auxiliary_data": null,
"inputs": [
{
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"prev_index": 0
}
],
"outputs": [
{
"addressType": 0,
"path": "m/1852'/1815'/0'/0/0",
"stakingPath": "m/1852'/1815'/1'/2/0",
"amount": "7120787"
}
],
"mint": [],
"script_data_hash": "d593fd793c377ac50a3169bb8378ffc257c944da31aa8f355dfa5a4f6ff89e02",
"collateral_inputs": [
{
"path": "m/1852'/1815'/0'/0/0",
"prev_hash": "1af8fa0b754ff99253d983894e63a2b09cbb56c833ba18c3384210163f63dcfc",
"prev_index": 0
}
],
"required_signers": [],
"signing_mode": "PLUTUS_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"tx_hash": "e5beff2153154ab3dba4ff5c638f40ae8c1594c67aee3310bd19997f5013e47b",
"witnesses": [
{
"type": 1,
"pub_key": "5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1",
"signature": "29032600142f199c144a6270fb64632468e6ca4ed217e6b5d5b459e8fa41c3f91a6fc73d3cf14a609e9edd863a485ceab549200daa8f50926cf16e1526dc220f",
"chain_code": null
}
]
}
},
{
"description": "Plutus transaction with BASE_KEY_SCRIPT address device-owned output",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
"fee": 42,
"ttl": 10,
"certificates": [],
"withdrawals": [],
"auxiliary_data": null,
"inputs": [
{
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"prev_index": 0
}
],
"outputs": [
{
"addressType": 2,
"path": "m/1852'/1815'/0'/0/0",
"scriptStakingHash": "8d7bebc7a58f1c7b5fb7c9391071ecd3b51b032695522f8c555343a9",
"amount": "7120787"
}
],
"mint": [],
"script_data_hash": "d593fd793c377ac50a3169bb8378ffc257c944da31aa8f355dfa5a4f6ff89e02",
"collateral_inputs": [
{
"path": "m/1852'/1815'/0'/0/0",
"prev_hash": "1af8fa0b754ff99253d983894e63a2b09cbb56c833ba18c3384210163f63dcfc",
"prev_index": 0
}
],
"required_signers": [],
"signing_mode": "PLUTUS_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"tx_hash": "8c131e38f378d141deb05d4bf2eb2d13bb75d6363dd470a1f524ba027eff566a",
"witnesses": [
{
"type": 1,
"pub_key": "5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1",
"signature": "e82967f5030f8d2c8b986f75e5744fa92e77444f0eff4aa440492c6aad0b0639ada1501fcbb01db5cfb4b39333aff96362adec4620db6f7f9771039600b24300",
"chain_code": null
}
]
}
}
]
}
13 changes: 6 additions & 7 deletions core/src/apps/cardano/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,12 @@ def validate_output_address_parameters(
) -> None:
validate_address_parameters(parameters)

if parameters.address_type in (
CardanoAddressType.BASE_SCRIPT_KEY,
CardanoAddressType.BASE_SCRIPT_SCRIPT,
CardanoAddressType.POINTER_SCRIPT,
CardanoAddressType.ENTERPRISE_SCRIPT,
CardanoAddressType.REWARD,
CardanoAddressType.REWARD_SCRIPT,
if parameters.address_type not in (
CardanoAddressType.BASE,
CardanoAddressType.BASE_KEY_SCRIPT,
CardanoAddressType.POINTER,
CardanoAddressType.ENTERPRISE,
CardanoAddressType.BYRON,
):
# Change outputs with script payment part are forbidden.
# Reward addresses are forbidden as outputs in general, see also validate_output_address
Expand Down
4 changes: 2 additions & 2 deletions core/src/apps/cardano/get_address.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from . import seed
from .address import derive_human_readable_address, validate_address_parameters
from .helpers.credential import Credential, should_show_address_credentials
from .layout import show_cardano_address, show_credentials
from .layout import show_address_credentials, show_cardano_address
from .sign_tx import validate_network_info

if TYPE_CHECKING:
Expand Down Expand Up @@ -47,7 +47,7 @@ async def _display_address(
protocol_magic: int,
) -> None:
if should_show_address_credentials(address_parameters):
await show_credentials(
await show_address_credentials(
ctx,
Credential.payment_credential(address_parameters),
Credential.stake_credential(address_parameters),
Expand Down
42 changes: 30 additions & 12 deletions core/src/apps/cardano/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,22 +271,45 @@ async def confirm_sending_token(
)


async def show_credentials(
async def show_address_credentials(
ctx: wire.Context,
payment_credential: Credential,
stake_credential: Credential,
is_change_output: bool = False,
) -> None:
await _show_credential(ctx, payment_credential, is_change_output)
await _show_credential(ctx, stake_credential, is_change_output)
intro_text = "Address"
await _show_credential(ctx, payment_credential, intro_text, is_output=False)
await _show_credential(ctx, stake_credential, intro_text, is_output=False)


async def show_change_output_credentials(
ctx: wire.Context,
payment_credential: Credential,
stake_credential: Credential,
) -> None:
intro_text = "The following address is a change address. Its"
await _show_credential(ctx, payment_credential, intro_text, is_output=True)
await _show_credential(ctx, stake_credential, intro_text, is_output=True)


async def show_device_owned_output_credentials(
ctx: wire.Context,
payment_credential: Credential,
stake_credential: Credential,
show_both_credentials: bool,
) -> None:
intro_text = "The following address is owned by this device. Its"
await _show_credential(ctx, payment_credential, intro_text, is_output=True)
if show_both_credentials:
await _show_credential(ctx, stake_credential, intro_text, is_output=True)


async def _show_credential(
ctx: wire.Context,
credential: Credential,
is_change_output: bool = False,
intro_text: str,
is_output: bool,
) -> None:
if is_change_output:
if is_output:
title = "Confirm transaction"
else:
title = f"{ADDRESS_TYPE_NAMES[credential.address_type]} address"
Expand All @@ -297,15 +320,10 @@ async def _show_credential(
# and reward address payment credential. In that case we don't want to
# show some of the "props".
if credential.is_set():
if is_change_output:
address_usage = "Change address"
else:
address_usage = "Address"

credential_title = credential.get_title()
props.append(
(
f"{address_usage} {credential.type_name} credential is a {credential_title}:",
f"{intro_text} {credential.type_name} credential is a {credential_title}:",
None,
)
)
Expand Down
Loading

0 comments on commit 7513776

Please sign in to comment.