feat(cardano): add support for output datum hash and script data hash

vdovhanych/arm-emu-deploy
David Misiak 3 years ago committed by matejcik
parent 2b3a53a6ae
commit 48587d83fe

@ -206,6 +206,7 @@ message CardanoSignTxInit {
required uint32 minting_asset_groups_count = 13;
required CardanoDerivationType derivation_type = 14;
optional bool include_network_id = 15 [default=false]; // network id included as tx body item
optional bytes script_data_hash = 16;
}
/**
@ -226,6 +227,7 @@ message CardanoTxOutput {
optional CardanoAddressParametersType address_parameters = 2; // parameters used to derive the address
required uint64 amount = 3; // amount to spend
required uint32 asset_groups_count = 4;
optional bytes datum_hash = 5;
}
/**

@ -28,6 +28,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -60,6 +61,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -92,6 +94,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -124,6 +127,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -156,6 +160,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -188,6 +193,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -225,6 +231,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -257,6 +264,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -289,6 +297,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -321,6 +330,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -353,6 +363,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -385,6 +396,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -417,6 +429,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -449,6 +462,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -484,6 +498,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -521,6 +536,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -558,6 +574,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -595,6 +612,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -633,6 +651,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -671,6 +690,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -708,6 +728,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -745,6 +766,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -782,6 +804,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -819,6 +842,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -857,6 +881,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -898,6 +923,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -932,6 +958,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -974,6 +1001,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1018,6 +1046,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1026,6 +1055,143 @@
"error_message": "Invalid auxiliary data"
}
},
{
"description": "Output datum hash has incorrect length",
"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",
"datum_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3"
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"error_message": "Invalid output datum hash"
}
},
{
"description": "Output datum hash with non-script address",
"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",
"datum_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7"
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"error_message": "Invalid output"
}
},
{
"description": "Output datum hash with non-script address parameters",
"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": [
{
"addressType": 2,
"path": "m/1852'/1815'/0'/0/0",
"scriptStakingHash": "8d7bebc7a58f1c7b5fb7c9391071ecd3b51b032695522f8c555343a9",
"amount": "7120787",
"datum_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7"
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"error_message": "Invalid output"
}
},
{
"description": "Script data hash has incorrect length",
"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": "3003112"
}
],
"mint": [],
"script_data_hash": "d593fd793c377ac50a3169bb8378ffc257c944da31aa8f355dfa5a4f",
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"error_message": "Invalid script data hash"
}
},
{
"description": "Change output path larger than 100",
"parameters": {
@ -1056,6 +1222,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1094,6 +1261,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1132,6 +1300,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1164,6 +1333,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1201,6 +1371,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1248,6 +1419,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1300,6 +1472,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1332,6 +1505,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [
{
@ -1368,6 +1542,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [
{
@ -1406,6 +1581,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1486,6 +1662,7 @@
]
}
],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [
{
@ -1523,6 +1700,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [
{
@ -1611,6 +1789,7 @@
]
}
],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [
{
@ -1653,6 +1832,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1690,6 +1870,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1727,6 +1908,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1770,6 +1952,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1813,6 +1996,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1855,6 +2039,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1891,6 +2076,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1924,6 +2110,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false

@ -28,6 +28,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -73,6 +74,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -119,6 +121,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -174,6 +177,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -238,6 +242,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -285,6 +290,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -332,6 +338,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -378,6 +385,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -426,6 +434,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -471,6 +480,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -516,6 +526,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -556,6 +567,7 @@
],
"outputs": [],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -606,6 +618,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -657,6 +670,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -713,6 +727,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -765,6 +780,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -813,6 +829,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -864,6 +881,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -918,6 +936,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -976,6 +995,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1047,6 +1067,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1088,6 +1109,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1138,6 +1160,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1190,6 +1213,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1237,6 +1261,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1375,6 +1400,7 @@
}
},
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -1490,6 +1516,7 @@
]
}
],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [
{
@ -1540,6 +1567,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": true
@ -1555,6 +1583,130 @@
}
]
}
},
{
"description": "Ordinary transaction with output datum 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": "addr1w9rhu54nz94k9l5v6d9rzfs47h7dv7xffcwkekuxcx3evnqpvuxu0",
"amount": "1",
"datum_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7"
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"tx_hash": "8ea2765f1e46d84f02d8b25a5f0cf445aaeaadcab913e17e59388a4f898ca812",
"witnesses": [
{
"type": 1,
"pub_key": "5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1",
"signature": "ccc4e3c2adbf63561881212c8dffd42a02850460256da9b393aaed2cbd131fbb2798a92a2adf59c31d22e1e33c3dad011d91e09aa2d5b15ba64fa995bf241900",
"chain_code": null
}
]
}
},
{
"description": "Ordinary transaction with script address but no datum 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": "addr1w9rhu54nz94k9l5v6d9rzfs47h7dv7xffcwkekuxcx3evnqpvuxu0",
"amount": "1"
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"tx_hash": "06d6587ddd79e000b6922c54069b78bb931b0cba06d97ba4171f3ce6590438d2",
"witnesses": [
{
"type": 1,
"pub_key": "5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1",
"signature": "4b7e694b8a31905918561eedc376aaa2f7827f19e228a9e28b5f56ee55ea61725752c50c2f1c67b79de747aeb8e5f1559ce211107a399938b954121d4c085f07",
"chain_code": null
}
]
}
},
{
"description": "Ordinary transaction with script data 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"
}
],
"mint": [],
"script_data_hash": "d593fd793c377ac50a3169bb8378ffc257c944da31aa8f355dfa5a4f6ff89e02",
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"tx_hash": "8606e5b69b5c40bd359d7bad6ed6f77810b8e8acba6cbca298c13f92b11178d4",
"witnesses": [
{
"type": 1,
"pub_key": "5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1",
"signature": "c8676cf593554f347e2d6a5ffc6a1371638156eaaddb3e7f94ae9a7488a6adb01c3660d8aff1da08e01c4899615158e69c5c797841ef7747740ab56d3b452f0c",
"chain_code": null
}
]
}
}
]
}

@ -32,6 +32,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -72,6 +73,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -116,6 +118,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -151,6 +154,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -188,6 +192,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -223,6 +228,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -310,6 +316,7 @@
]
}
],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{

@ -79,6 +79,7 @@
]
}
],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -136,6 +137,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -189,6 +191,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -246,6 +249,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -308,6 +312,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -407,6 +412,7 @@
]
}
],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
@ -444,6 +450,95 @@
}
]
}
},
{
"description": "Multisig transaction with output datum hash",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
"fee": 42,
"ttl": 10,
"certificates": [],
"withdrawals": [],
"auxiliary_data": null,
"inputs": [
{
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"prev_index": 0
}
],
"outputs": [
{
"address": "addr1w9rhu54nz94k9l5v6d9rzfs47h7dv7xffcwkekuxcx3evnqpvuxu0",
"amount": "1",
"datum_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7"
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
"path": "m/1854'/1815'/0'/0/0"
}
],
"include_network_id": false
},
"result": {
"tx_hash": "8ea2765f1e46d84f02d8b25a5f0cf445aaeaadcab913e17e59388a4f898ca812",
"witnesses": [
{
"type": 1,
"pub_key": "b10be5c0d11ad8292bbe69e220ca0cfbe154610b3041a8e72f9d515c226ab3b1",
"signature": "186bd74158d42d1703ac97171f09c50052a6ce6e9dad38520aa38c25c94df6857a6be3c930464ba64884cc8cdd01d05c533d9e9026b2ba50afbe93752bfd0106",
"chain_code": null
}
]
}
},
{
"description": "Multisig transaction with script data hash",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
"fee": 42,
"ttl": 10,
"certificates": [],
"withdrawals": [],
"auxiliary_data": null,
"inputs": [
{
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"prev_index": 0
}
],
"outputs": [
{
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
"amount": "1"
}
],
"mint": [],
"script_data_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [
{
"path": "m/1854'/1815'/0'/0/0"
}
],
"include_network_id": false
},
"result": {
"tx_hash": "ee065ce429d8dbcc2432aa81706877f2eee4fc5031d1e1ae06fe993b9987b1be",
"witnesses": [
{
"type": 1,
"pub_key": "b10be5c0d11ad8292bbe69e220ca0cfbe154610b3041a8e72f9d515c226ab3b1",
"signature": "88ce2f590b662688ee626dd2ee471ec6e55cfac467c12645ef10c582a539dd85a1bac7ff7b95a59354576f604a031a28de8817c51eff88ec7d43cb00e824d90b",
"chain_code": null
}
]
}
}
]
}

@ -32,6 +32,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -77,6 +78,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -122,6 +124,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false

@ -49,6 +49,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -105,6 +106,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -158,6 +160,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -211,6 +214,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -285,6 +289,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -321,6 +326,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -379,6 +385,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -432,6 +439,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -484,6 +492,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -536,6 +545,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -622,6 +632,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -708,6 +719,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "ORDINARY_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -794,6 +806,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "MULTISIG_TRANSACTION",
"additional_witness_requests": [],
"include_network_id": false
@ -880,6 +893,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [
{
@ -970,6 +984,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [
{
@ -1087,6 +1102,7 @@
]
}
],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [
{
@ -1179,6 +1195,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -1186,6 +1203,181 @@
"result": {
"error_message": "Invalid output"
}
},
{
"description": "Sample stake pool registration certificate with output datum hash",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
"fee": 42,
"ttl": 10,
"certificates": [
{
"type": 3,
"pool_parameters": {
"pool_id": "f61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb4973",
"vrf_key_hash": "198890ad6c92e80fbdab554dda02da9fb49d001bbd96181f3e07f7a6ab0d0640",
"pledge": 500000000,
"cost": 340000000,
"margin": {
"numerator": 1,
"denominator": 2
},
"reward_account": "stake1uya87zwnmax0v6nnn8ptqkl6ydx4522kpsc3l3wmf3yswygwx45el",
"owners": [
{
"staking_key_path": "m/1852'/1815'/0'/2/0"
},
{
"staking_key_hash": "3a7f09d3df4cf66a7399c2b05bfa234d5a29560c311fc5db4c490711"
}
],
"relays": [
{
"type": 0,
"ipv4_address": "192.168.0.1",
"ipv6_address": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"port": 1234
},
{
"type": 0,
"ipv6_address": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"port": 1234
},
{
"type": 0,
"ipv4_address": "192.168.0.1",
"port": 1234
},
{
"type": 1,
"host_name": "www.test.test",
"port": 1234
},
{
"type": 2,
"host_name": "www.test2.test"
}
],
"metadata": {
"url": "https://www.test.test",
"hash": "914c57c1f12bbf4a82b12d977d4f274674856a11ed4b9b95bd70f5d41c5064a6"
}
}
}
],
"withdrawals": [],
"auxiliary_data": null,
"inputs": [
{
"path": null,
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"prev_index": 0
}
],
"outputs": [
{
"address": "addr1w9rhu54nz94k9l5v6d9rzfs47h7dv7xffcwkekuxcx3evnqpvuxu0",
"amount": "1",
"datum_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7"
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"error_message": "Invalid output"
}
},
{
"description": "Sample stake pool registration certificate with script data hash",
"parameters": {
"protocol_magic": 764824073,
"network_id": 1,
"fee": 42,
"ttl": 10,
"certificates": [
{
"type": 3,
"pool_parameters": {
"pool_id": "f61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb4973",
"vrf_key_hash": "198890ad6c92e80fbdab554dda02da9fb49d001bbd96181f3e07f7a6ab0d0640",
"pledge": 500000000,
"cost": 340000000,
"margin": {
"numerator": 1,
"denominator": 2
},
"reward_account": "stake1uya87zwnmax0v6nnn8ptqkl6ydx4522kpsc3l3wmf3yswygwx45el",
"owners": [
{
"staking_key_path": "m/1852'/1815'/0'/2/0"
},
{
"staking_key_hash": "3a7f09d3df4cf66a7399c2b05bfa234d5a29560c311fc5db4c490711"
}
],
"relays": [
{
"type": 0,
"ipv4_address": "192.168.0.1",
"ipv6_address": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"port": 1234
},
{
"type": 0,
"ipv6_address": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"port": 1234
},
{
"type": 0,
"ipv4_address": "192.168.0.1",
"port": 1234
},
{
"type": 1,
"host_name": "www.test.test",
"port": 1234
},
{
"type": 2,
"host_name": "www.test2.test"
}
],
"metadata": {
"url": "https://www.test.test",
"hash": "914c57c1f12bbf4a82b12d977d4f274674856a11ed4b9b95bd70f5d41c5064a6"
}
}
}
],
"withdrawals": [],
"auxiliary_data": null,
"inputs": [
{
"path": null,
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"prev_index": 0
}
],
"outputs": [
{
"address": "addr1w9rhu54nz94k9l5v6d9rzfs47h7dv7xffcwkekuxcx3evnqpvuxu0",
"amount": "1"
}
],
"mint": [],
"script_data_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
},
"result": {
"error_message": "Invalid tx signing request"
}
}
]
}

@ -82,6 +82,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -176,6 +177,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -271,6 +273,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -332,6 +335,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -393,6 +397,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false
@ -489,6 +494,7 @@
}
],
"mint": [],
"script_data_hash": null,
"signing_mode": "POOL_REGISTRATION_AS_OWNER",
"additional_witness_requests": [],
"include_network_id": false

@ -39,6 +39,13 @@ ADDRESS_TYPES_SHELLEY = (
CardanoAddressType.REWARD_SCRIPT,
)
ADDRESS_TYPES_PAYMENT_SCRIPT = (
CardanoAddressType.BASE_SCRIPT_KEY,
CardanoAddressType.BASE_SCRIPT_SCRIPT,
CardanoAddressType.POINTER_SCRIPT,
CardanoAddressType.ENTERPRISE_SCRIPT,
)
MIN_ADDRESS_BYTES_LENGTH = 29
MAX_ADDRESS_BYTES_LENGTH = 65
@ -240,7 +247,7 @@ def _validate_address_and_get_type(
raise INVALID_ADDRESS
address_bytes = get_address_bytes_unsafe(address)
address_type = _get_address_type(address_bytes)
address_type = get_address_type(address_bytes)
if address_type == CardanoAddressType.BYRON:
validate_byron_address(address_bytes, protocol_magic)
@ -281,14 +288,14 @@ def get_address_bytes_unsafe(address: str) -> bytes:
return address_bytes
def _get_address_type(address: bytes) -> CardanoAddressType:
def get_address_type(address: bytes) -> CardanoAddressType:
return address[0] >> 4 # type: ignore [int-into-enum]
def _validate_shelley_address(
address_str: str, address_bytes: bytes, network_id: int
) -> None:
address_type = _get_address_type(address_bytes)
address_type = get_address_type(address_bytes)
_validate_address_size(address_bytes)
_validate_address_bech32_hrp(address_str, address_type, network_id)
@ -352,7 +359,7 @@ def derive_human_readable_address(
def encode_human_readable_address(address_bytes: bytes) -> str:
address_type = _get_address_type(address_bytes)
address_type = get_address_type(address_bytes)
if address_type == CardanoAddressType.BYRON:
return base58.encode(address_bytes)
elif address_type in ADDRESS_TYPES_SHELLEY:

@ -18,7 +18,11 @@ INVALID_STAKEPOOL_REGISTRATION_TX_WITNESSES = wire.ProcessError(
INVALID_WITNESS_REQUEST = wire.ProcessError("Invalid witness request")
INVALID_NATIVE_SCRIPT = wire.ProcessError("Invalid native script")
INVALID_TOKEN_BUNDLE_MINT = wire.ProcessError("Invalid mint token bundle")
INVALID_OUTPUT_DATUM_HASH = wire.ProcessError("Invalid output datum hash")
INVALID_SCRIPT_DATA_HASH = wire.ProcessError("Invalid script data hash")
LOVELACE_MAX_SUPPLY = 45_000_000_000 * 1_000_000
ADDRESS_KEY_HASH_SIZE = 28
SCRIPT_HASH_SIZE = 28
OUTPUT_DATUM_HASH_SIZE = 32
SCRIPT_DATA_HASH_SIZE = 32

@ -12,6 +12,8 @@ HRP_JORMUN_PUBLIC_KEY = "ed25519_pk"
HRP_SCRIPT_HASH = "script"
HRP_KEY_HASH = "addr_vkh"
HRP_SHARED_KEY_HASH = "addr_shared_vkh"
HRP_OUTPUT_DATUM_HASH = "datum"
HRP_SCRIPT_DATA_HASH = "script_data"
def encode(hrp: str, data: bytes) -> str:

@ -76,6 +76,14 @@ def format_key_hash(key_hash: bytes, is_shared_key: bool) -> str:
return bech32.encode(hrp, key_hash)
def format_output_datum_hash(output_datum_hash: bytes) -> str:
return bech32.encode(bech32.HRP_OUTPUT_DATUM_HASH, output_datum_hash)
def format_script_data_hash(script_data_hash: bytes) -> str:
return bech32.encode(bech32.HRP_SCRIPT_DATA_HASH, script_data_hash)
def get_public_key_hash(keychain: seed.Keychain, path: list[int]) -> bytes:
public_key = derive_public_key(keychain, path)
return hashlib.blake2b(data=public_key, outlen=ADDRESS_KEY_HASH_SIZE).digest()

@ -31,6 +31,8 @@ from .helpers.utils import (
format_asset_fingerprint,
format_key_hash,
format_optional_int,
format_output_datum_hash,
format_script_data_hash,
format_script_hash,
format_stake_pool_id,
to_account_path,
@ -332,6 +334,34 @@ async def show_warning_tx_output_contains_tokens(ctx: wire.Context) -> None:
)
async def show_warning_tx_output_contains_datum_hash(
ctx: wire.Context, datum_hash: bytes
) -> None:
await confirm_properties(
ctx,
"confirm_datum_hash",
title="Confirm transaction",
props=[
(
"The following transaction output contains datum hash:",
format_output_datum_hash(datum_hash),
),
("\nContinue?", None),
],
br_code=ButtonRequestType.Other,
)
async def show_warning_tx_output_no_datum_hash(ctx: wire.Context) -> None:
await confirm_metadata(
ctx,
"confirm_no_datum_hash",
title="Confirm transaction",
content="The following transaction output contains a script address, but does not contain a datum hash.",
br_code=ButtonRequestType.Other,
)
async def confirm_witness_request(
ctx: wire.Context,
witness_path: list[int],
@ -654,6 +684,16 @@ async def show_warning_tx_network_unverifiable(ctx: wire.Context) -> None:
)
async def confirm_script_data_hash(ctx: wire.Context, script_data_hash: bytes) -> None:
await confirm_properties(
ctx,
"confirm_script_data_hash",
title="Confirm transaction",
props=[("Script data hash:", format_script_data_hash(script_data_hash))],
br_code=ButtonRequestType.Other,
)
async def show_cardano_address(
ctx: wire.Context,
address_parameters: CardanoAddressParametersType,

@ -1,7 +1,7 @@
from typing import TYPE_CHECKING
from trezor.crypto import hashlib
from trezor.enums import CardanoAddressType, CardanoNativeScriptType
from trezor.enums import CardanoNativeScriptType
from apps.cardano.helpers import (
ADDRESS_KEY_HASH_SIZE,
@ -21,15 +21,6 @@ if TYPE_CHECKING:
from apps.common.cbor import CborSequence
SCRIPT_ADDRESS_TYPES = (
CardanoAddressType.BASE_SCRIPT_KEY,
CardanoAddressType.BASE_KEY_SCRIPT,
CardanoAddressType.BASE_SCRIPT_SCRIPT,
CardanoAddressType.POINTER_SCRIPT,
CardanoAddressType.ENTERPRISE_SCRIPT,
CardanoAddressType.REWARD_SCRIPT,
)
def validate_native_script(script: CardanoNativeScript | None) -> None:
if not script:

@ -35,9 +35,11 @@ from apps.common import cbor, safety_checks
from . import seed
from .address import (
ADDRESS_TYPES_PAYMENT_SCRIPT,
derive_address_bytes,
derive_human_readable_address,
get_address_bytes_unsafe,
get_address_type,
validate_output_address,
validate_output_address_parameters,
)
@ -59,6 +61,8 @@ from .certificates import (
)
from .helpers import (
INVALID_OUTPUT,
INVALID_OUTPUT_DATUM_HASH,
INVALID_SCRIPT_DATA_HASH,
INVALID_STAKE_POOL_REGISTRATION_TX_STRUCTURE,
INVALID_STAKEPOOL_REGISTRATION_TX_WITNESSES,
INVALID_TOKEN_BUNDLE_MINT,
@ -67,6 +71,8 @@ from .helpers import (
INVALID_WITHDRAWAL,
INVALID_WITNESS_REQUEST,
LOVELACE_MAX_SUPPLY,
OUTPUT_DATUM_HASH_SIZE,
SCRIPT_DATA_HASH_SIZE,
network_ids,
protocol_magics,
)
@ -87,6 +93,7 @@ from .helpers.paths import (
from .helpers.utils import derive_public_key, validate_stake_credential
from .layout import (
confirm_certificate,
confirm_script_data_hash,
confirm_sending,
confirm_sending_token,
confirm_stake_pool_metadata,
@ -102,7 +109,9 @@ from .layout import (
show_warning_path,
show_warning_tx_contains_mint,
show_warning_tx_network_unverifiable,
show_warning_tx_output_contains_datum_hash,
show_warning_tx_output_contains_tokens,
show_warning_tx_output_no_datum_hash,
)
from .seed import is_byron_path, is_multisig_path, is_shelley_path
@ -124,6 +133,7 @@ TX_BODY_KEY_WITHDRAWALS = const(5)
TX_BODY_KEY_AUXILIARY_DATA = const(7)
TX_BODY_KEY_VALIDITY_INTERVAL_START = const(8)
TX_BODY_KEY_MINT = const(9)
TX_BODY_KEY_SCRIPT_DATA_HASH = const(11)
TX_BODY_KEY_NETWORK_ID = const(15)
POOL_REGISTRATION_CERTIFICATE_ITEMS_COUNT = 10
@ -147,6 +157,7 @@ async def sign_tx(
msg.validity_interval_start is not None,
msg.minting_asset_groups_count > 0,
msg.include_network_id,
msg.script_data_hash is not None,
)
)
@ -203,6 +214,12 @@ async def _validate_tx_signing_request(
else:
raise INVALID_TX_SIGNING_REQUEST
if msg.script_data_hash is not None and msg.signing_mode not in (
CardanoTxSigningMode.ORDINARY_TRANSACTION,
CardanoTxSigningMode.MULTISIG_TRANSACTION,
):
raise INVALID_TX_SIGNING_REQUEST
return is_network_id_verifiable
@ -284,6 +301,9 @@ async def _process_transaction(
with tx_dict.add(TX_BODY_KEY_MINT, minting_dict):
await _process_minting(ctx, minting_dict)
if msg.script_data_hash is not None:
await _process_script_data_hash(ctx, tx_dict, msg.script_data_hash)
if msg.include_network_id:
tx_dict.add(TX_BODY_KEY_NETWORK_ID, msg.network_id)
@ -360,13 +380,15 @@ async def _process_outputs(
keychain, protocol_magic, network_id, output
)
if output.asset_groups_count == 0:
outputs_list.append((output_address, output.amount))
else:
# output structure is: [address, [amount, asset_groups]]
output_list: HashBuilderList = HashBuilderList(2)
with outputs_list.append(output_list):
output_list.append(output_address)
has_datum_hash = output.datum_hash is not None
output_list: HashBuilderList = HashBuilderList(2 + int(has_datum_hash))
with outputs_list.append(output_list):
output_list.append(output_address)
if output.asset_groups_count == 0:
# output structure is: [address, amount, datum_hash?]
output_list.append(output.amount)
else:
# output structure is: [address, [amount, asset_groups], datum_hash?]
output_value_list: HashBuilderList = HashBuilderList(2)
with output_list.append(output_value_list):
output_value_list.append(output.amount)
@ -380,6 +402,8 @@ async def _process_outputs(
output.asset_groups_count,
should_show_output,
)
if has_datum_hash:
output_list.append(output.datum_hash)
total_amount += output.amount
@ -662,6 +686,19 @@ async def _process_minting_tokens(
tokens.add(token.asset_name_bytes, token.mint_amount)
async def _process_script_data_hash(
ctx: wire.Context,
tx_body_builder_dict: HashBuilderDict,
script_data_hash: bytes,
) -> None:
"""Validate, confirm and serialize the script data hash."""
_validate_script_data_hash(script_data_hash)
await confirm_script_data_hash(ctx, script_data_hash)
tx_body_builder_dict.add(TX_BODY_KEY_SCRIPT_DATA_HASH, script_data_hash)
async def _process_witness_requests(
ctx: wire.Context,
keychain: seed.Keychain,
@ -762,6 +799,18 @@ def _validate_output(
else:
raise INVALID_OUTPUT
if output.datum_hash is not None:
if signing_mode not in (
CardanoTxSigningMode.ORDINARY_TRANSACTION,
CardanoTxSigningMode.MULTISIG_TRANSACTION,
):
raise INVALID_OUTPUT
if len(output.datum_hash) != OUTPUT_DATUM_HASH_SIZE:
raise INVALID_OUTPUT_DATUM_HASH
address_type = _get_output_address_type(output)
if address_type not in ADDRESS_TYPES_PAYMENT_SCRIPT:
raise INVALID_OUTPUT
account_path_checker.add_output(output)
@ -769,6 +818,16 @@ def _should_show_output(
output: CardanoTxOutput,
signing_mode: CardanoTxSigningMode,
) -> bool:
if output.datum_hash:
# none of the reasons for hiding below should be reachable when datum hash
# is present, but let's make sure
return True
address_type = _get_output_address_type(output)
if output.datum_hash is None and address_type in ADDRESS_TYPES_PAYMENT_SCRIPT:
# Plutus script address without a datum hash is unspendable, we must show a warning
return True
if signing_mode == CardanoTxSigningMode.POOL_REGISTRATION_AS_OWNER:
# In a pool registration transaction, there are no inputs belonging to the user
# and no spending witnesses. It is thus safe to not show the outputs.
@ -789,9 +848,16 @@ async def _show_output(
protocol_magic: int,
network_id: int,
) -> None:
if output.datum_hash:
await show_warning_tx_output_contains_datum_hash(ctx, output.datum_hash)
if output.asset_groups_count > 0:
await show_warning_tx_output_contains_tokens(ctx)
address_type = _get_output_address_type(output)
if output.datum_hash is None and address_type in ADDRESS_TYPES_PAYMENT_SCRIPT:
await show_warning_tx_output_no_datum_hash(ctx)
is_change_output: bool
if address_parameters := output.address_parameters:
is_change_output = True
@ -892,6 +958,11 @@ def _validate_withdrawal(
account_path_checker.add_withdrawal(withdrawal)
def _validate_script_data_hash(script_data_hash: bytes) -> None:
if len(script_data_hash) != SCRIPT_DATA_HASH_SIZE:
raise INVALID_SCRIPT_DATA_HASH
def _get_output_address(
keychain: seed.Keychain,
protocol_magic: int,
@ -907,6 +978,13 @@ def _get_output_address(
return get_address_bytes_unsafe(output.address)
def _get_output_address_type(output: CardanoTxOutput) -> CardanoAddressType:
if output.address_parameters:
return output.address_parameters.address_type
assert output.address is not None # _validate_output
return get_address_type(get_address_bytes_unsafe(output.address))
def _sign_tx_hash(
keychain: seed.Keychain, tx_body_hash: bytes, path: list[int]
) -> bytes:

@ -1332,6 +1332,7 @@ if TYPE_CHECKING:
minting_asset_groups_count: "int"
derivation_type: "CardanoDerivationType"
include_network_id: "bool"
script_data_hash: "bytes | None"
def __init__(
self,
@ -1351,6 +1352,7 @@ if TYPE_CHECKING:
ttl: "int | None" = None,
validity_interval_start: "int | None" = None,
include_network_id: "bool | None" = None,
script_data_hash: "bytes | None" = None,
) -> None:
pass
@ -1379,6 +1381,7 @@ if TYPE_CHECKING:
address_parameters: "CardanoAddressParametersType | None"
amount: "int"
asset_groups_count: "int"
datum_hash: "bytes | None"
def __init__(
self,
@ -1387,6 +1390,7 @@ if TYPE_CHECKING:
asset_groups_count: "int",
address: "str | None" = None,
address_parameters: "CardanoAddressParametersType | None" = None,
datum_hash: "bytes | None" = None,
) -> None:
pass

@ -172,27 +172,27 @@ def parse_output(output: dict) -> OutputWithAssetGroups:
if not (contains_address or contains_address_type):
raise ValueError(INCOMPLETE_OUTPUT_ERROR_MESSAGE)
address = None
address_parameters = None
token_bundle = []
if contains_address:
address = output["address"]
address = output.get("address")
address_parameters = None
if contains_address_type:
address_parameters = _parse_address_parameters(
output, INCOMPLETE_OUTPUT_ERROR_MESSAGE
)
token_bundle = []
if "token_bundle" in output:
token_bundle = _parse_token_bundle(output["token_bundle"], is_mint=False)
datum_hash = parse_optional_bytes(output.get("datum_hash"))
return (
messages.CardanoTxOutput(
address=address,
address_parameters=address_parameters,
amount=int(output["amount"]),
asset_groups_count=len(token_bundle),
datum_hash=datum_hash,
),
token_bundle,
)
@ -537,6 +537,10 @@ def parse_mint(mint: Iterable[dict]) -> List[AssetGroupWithTokens]:
return _parse_token_bundle(mint, is_mint=True)
def parse_script_data_hash(script_data_hash: Optional[str]) -> Optional[bytes]:
return parse_optional_bytes(script_data_hash)
def parse_additional_witness_request(
additional_witness_request: dict,
) -> Path:
@ -688,6 +692,7 @@ def sign_tx(
network_id: int = NETWORK_IDS["mainnet"],
auxiliary_data: Optional[messages.CardanoTxAuxiliaryData] = None,
mint: Sequence[AssetGroupWithTokens] = (),
script_data_hash: Optional[bytes] = None,
additional_witness_requests: Sequence[Path] = (),
derivation_type: messages.CardanoDerivationType = messages.CardanoDerivationType.ICARUS,
include_network_id: bool = False,
@ -712,6 +717,7 @@ def sign_tx(
network_id=network_id,
has_auxiliary_data=auxiliary_data is not None,
minting_asset_groups_count=len(mint),
script_data_hash=script_data_hash,
witness_requests_count=len(witness_requests),
derivation_type=derivation_type,
include_network_id=include_network_id,

@ -87,6 +87,9 @@ def sign_tx(
]
auxiliary_data = cardano.parse_auxiliary_data(transaction.get("auxiliary_data"))
mint = cardano.parse_mint(transaction.get("mint", ()))
script_data_hash = cardano.parse_script_data_hash(
transaction.get("script_data_hash")
)
additional_witness_requests = [
cardano.parse_additional_witness_request(p)
for p in transaction["additional_witness_requests"]
@ -107,6 +110,7 @@ def sign_tx(
network_id,
auxiliary_data,
mint,
script_data_hash,
additional_witness_requests,
derivation_type=derivation_type,
include_network_id=include_network_id,

@ -2245,6 +2245,7 @@ class CardanoSignTxInit(protobuf.MessageType):
13: protobuf.Field("minting_asset_groups_count", "uint32", repeated=False, required=True),
14: protobuf.Field("derivation_type", "CardanoDerivationType", repeated=False, required=True),
15: protobuf.Field("include_network_id", "bool", repeated=False, required=False),
16: protobuf.Field("script_data_hash", "bytes", repeated=False, required=False),
}
def __init__(
@ -2265,6 +2266,7 @@ class CardanoSignTxInit(protobuf.MessageType):
ttl: Optional["int"] = None,
validity_interval_start: Optional["int"] = None,
include_network_id: Optional["bool"] = False,
script_data_hash: Optional["bytes"] = None,
) -> None:
self.signing_mode = signing_mode
self.protocol_magic = protocol_magic
@ -2281,6 +2283,7 @@ class CardanoSignTxInit(protobuf.MessageType):
self.ttl = ttl
self.validity_interval_start = validity_interval_start
self.include_network_id = include_network_id
self.script_data_hash = script_data_hash
class CardanoTxInput(protobuf.MessageType):
@ -2307,6 +2310,7 @@ class CardanoTxOutput(protobuf.MessageType):
2: protobuf.Field("address_parameters", "CardanoAddressParametersType", repeated=False, required=False),
3: protobuf.Field("amount", "uint64", repeated=False, required=True),
4: protobuf.Field("asset_groups_count", "uint32", repeated=False, required=True),
5: protobuf.Field("datum_hash", "bytes", repeated=False, required=False),
}
def __init__(
@ -2316,11 +2320,13 @@ class CardanoTxOutput(protobuf.MessageType):
asset_groups_count: "int",
address: Optional["str"] = None,
address_parameters: Optional["CardanoAddressParametersType"] = None,
datum_hash: Optional["bytes"] = None,
) -> None:
self.amount = amount
self.asset_groups_count = asset_groups_count
self.address = address
self.address_parameters = address_parameters
self.datum_hash = datum_hash
class CardanoAssetGroup(protobuf.MessageType):

@ -45,6 +45,7 @@ def test_cardano_sign_tx(client: Client, parameters, result):
withdrawals = [cardano.parse_withdrawal(w) for w in parameters["withdrawals"]]
auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"])
mint = cardano.parse_mint(parameters["mint"])
script_data_hash = cardano.parse_script_data_hash(parameters["script_data_hash"])
additional_witness_requests = [
cardano.parse_additional_witness_request(p)
for p in parameters["additional_witness_requests"]
@ -72,6 +73,7 @@ def test_cardano_sign_tx(client: Client, parameters, result):
network_id=parameters["network_id"],
auxiliary_data=auxiliary_data,
mint=mint,
script_data_hash=script_data_hash,
additional_witness_requests=additional_witness_requests,
include_network_id=parameters["include_network_id"],
)
@ -93,6 +95,7 @@ def test_cardano_sign_tx_failed(client: Client, parameters, result):
withdrawals = [cardano.parse_withdrawal(w) for w in parameters["withdrawals"]]
auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"])
mint = cardano.parse_mint(parameters["mint"])
script_data_hash = cardano.parse_script_data_hash(parameters["script_data_hash"])
additional_witness_requests = [
cardano.parse_additional_witness_request(p)
for p in parameters["additional_witness_requests"]
@ -121,6 +124,7 @@ def test_cardano_sign_tx_failed(client: Client, parameters, result):
network_id=parameters["network_id"],
auxiliary_data=auxiliary_data,
mint=mint,
script_data_hash=script_data_hash,
additional_witness_requests=additional_witness_requests,
include_network_id=parameters["include_network_id"],
)

Loading…
Cancel
Save