add more details to btc tx description

This commit is contained in:
Michele Balistreri 2024-08-13 10:06:53 +02:00
parent 1e319b640f
commit 0aa87e39a0
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
5 changed files with 66 additions and 10 deletions

View File

@ -49,6 +49,7 @@ typedef struct {
psbt_txin_t inputs[BTC_MAX_INPUTS]; psbt_txin_t inputs[BTC_MAX_INPUTS];
psbt_txout_t outputs[BTC_MAX_OUTPUTS]; psbt_txout_t outputs[BTC_MAX_OUTPUTS];
psbt_input_data_t input_data[BTC_MAX_INPUTS]; psbt_input_data_t input_data[BTC_MAX_INPUTS];
bool output_is_change[BTC_MAX_OUTPUTS];
size_t input_count; size_t input_count;
size_t output_count; size_t output_count;

View File

@ -533,6 +533,17 @@ static app_err_t core_btc_validate(btc_tx_ctx_t* tx_ctx) {
} }
} }
for (int i = 0; i < tx_ctx->output_count; i++) {
for (int j = 0; j < tx_ctx->input_count; j++) {
if (tx_ctx->input_data[j].can_sign &&
(tx_ctx->input_data[j].script_pubkey_len == tx_ctx->outputs[i].script_len) &&
!memcmp(tx_ctx->input_data[j].script_pubkey, tx_ctx->outputs[i].script, tx_ctx->outputs[i].script_len)) {
tx_ctx->output_is_change[i] = true;
break;
}
}
}
return can_sign_something ? ERR_OK : ERR_MISMATCH; return can_sign_something ? ERR_OK : ERR_MISMATCH;
} }

View File

@ -287,11 +287,11 @@ static void dialog_indexed_string(char* dst, const char* label, size_t index) {
// TODO: move this to more general function to recognize data and display correct data accordingly // TODO: move this to more general function to recognize data and display correct data accordingly
static i18n_str_id_t dialog_recognize_data(const txContent_t* tx) { static i18n_str_id_t dialog_recognize_data(const txContent_t* tx) {
if (tx->dataLength == 0) { if (tx->dataLength == 0) {
return TX_DATA_NONE; return TX_NO;
} else if (tx->value.length == 0 && tx->dataLength == ETH_ERC20_TRANSFER_LEN && !memcmp(tx->data, ETH_ERC20_SIGNATURE, ETH_ERC20_SIGNATURE_LEN)) { } else if (tx->value.length == 0 && tx->dataLength == ETH_ERC20_TRANSFER_LEN && !memcmp(tx->data, ETH_ERC20_SIGNATURE, ETH_ERC20_SIGNATURE_LEN)) {
return TX_DATA_ERC20; return TX_DATA_ERC20;
} else { } else {
return TX_DATA_PRESENT; return TX_YES;
} }
} }
@ -375,6 +375,8 @@ void dialog_confirm_btc_summary(const btc_tx_ctx_t* tx) {
uint64_t signed_amount = 0; uint64_t signed_amount = 0;
uint64_t total_output = 0; uint64_t total_output = 0;
bool has_sighash_none = false;
for (int i = 0; i < tx->input_count; i++) { for (int i = 0; i < tx->input_count; i++) {
uint64_t t; uint64_t t;
memcpy(&t, tx->input_data[i].amount, sizeof(uint64_t)); memcpy(&t, tx->input_data[i].amount, sizeof(uint64_t));
@ -382,24 +384,57 @@ void dialog_confirm_btc_summary(const btc_tx_ctx_t* tx) {
if (tx->input_data[i].can_sign) { if (tx->input_data[i].can_sign) {
signed_amount += t; signed_amount += t;
} }
if ((tx->input_data[i].sighash_flag & SIGHASH_MASK) == SIGHASH_NONE) {
has_sighash_none = true;
} }
}
uint64_t change = 0;
int dest_idx = -1;
for (int i = 0; i < tx->output_count; i++) { for (int i = 0; i < tx->output_count; i++) {
uint64_t t; uint64_t t;
memcpy(&t, tx->outputs[i].amount, sizeof(uint64_t)); memcpy(&t, tx->outputs[i].amount, sizeof(uint64_t));
total_output += t; total_output += t;
if (tx->output_is_change[i]) {
change += t;
} else {
if (dest_idx == -1) {
dest_idx = i;
} else {
dest_idx = -2;
}
}
} }
// TODO: fix labels, add basic informations on destination address dialog_btc_amount(&ctx, TX_AMOUNT, total_input);
if (total_input == signed_amount) { if (total_input != signed_amount) {
dialog_btc_amount(&ctx, TX_AMOUNT, total_input);
} else {
dialog_btc_amount(&ctx, TX_AMOUNT, total_input);
dialog_btc_amount(&ctx, TX_SIGNED_AMOUNT, signed_amount); dialog_btc_amount(&ctx, TX_SIGNED_AMOUNT, signed_amount);
} }
if (change) {
dialog_btc_amount(&ctx, TX_CHANGE, change);
}
dialog_btc_amount(&ctx, TX_FEE, total_input - total_output); dialog_btc_amount(&ctx, TX_FEE, total_input - total_output);
if (has_sighash_none) {
ctx.x = TH_DATA_LEFT_MARGIN;
screen_draw_text(&ctx, MESSAGE_MAX_X, MESSAGE_MAX_Y, (const uint8_t*) LSTR(TX_SIGHASH_WARNING), strlen(LSTR(TX_SIGHASH_WARNING)), false, false);
} else {
char buf[BIGNUM_STRING_LEN];
dialog_label(&ctx, LSTR(TX_ADDRESS));
if (dest_idx >= 0) {
script_output_to_address(tx->outputs[dest_idx].script, tx->outputs[dest_idx].script_len, buf);
dialog_data(&ctx, buf);
} else {
dialog_data(&ctx, LSTR(TX_MULTIPLE_RECIPIENT));
}
}
} }
static inline void dialog_btc_sign_scheme_format(char* buf, uint32_t flag) { static inline void dialog_btc_sign_scheme_format(char* buf, uint32_t flag) {
@ -457,7 +492,7 @@ void dialog_confirm_btc_inouts(const btc_tx_ctx_t* tx, size_t page) {
dialog_inline_data(&ctx, buf); dialog_inline_data(&ctx, buf);
dialog_label(&ctx, LSTR(TX_SIGNED)); dialog_label(&ctx, LSTR(TX_SIGNED));
dialog_inline_data(&ctx, tx->input_data[i].can_sign ? LSTR(TX_DATA_PRESENT) : LSTR(TX_DATA_NONE)); dialog_inline_data(&ctx, tx->input_data[i].can_sign ? LSTR(TX_YES) : LSTR(TX_NO));
i++; i++;
displayed++; displayed++;
@ -477,6 +512,9 @@ void dialog_confirm_btc_inouts(const btc_tx_ctx_t* tx, size_t page) {
memcpy(&t, tx->outputs[i].amount, sizeof(uint64_t)); memcpy(&t, tx->outputs[i].amount, sizeof(uint64_t));
dialog_btc_amount(&ctx, TX_AMOUNT, t); dialog_btc_amount(&ctx, TX_AMOUNT, t);
dialog_label(&ctx, LSTR(TX_CHANGE));
dialog_inline_data(&ctx, tx->output_is_change[i] ? LSTR(TX_YES) : LSTR(TX_NO));
i++; i++;
displayed++; displayed++;
} }

View File

@ -46,6 +46,8 @@ const char *const i18n_english_strings[] = {
"To", "To",
"Amount", "Amount",
"Signed amount", "Signed amount",
"Multiple recipients",
"WARNING: recipients could change! Do not sign unless you absolutely know what you are doing.",
"Fee", "Fee",
"Signer", "Signer",
"Data", "Data",
@ -60,6 +62,7 @@ const char *const i18n_english_strings[] = {
"NONE", "NONE",
"SINGLE", "SINGLE",
"ANYONECANPAY", "ANYONECANPAY",
"Change",
// MSG Confirmation // MSG Confirmation
"Sign message", "Sign message",

View File

@ -52,12 +52,14 @@ typedef enum {
TX_ADDRESS, TX_ADDRESS,
TX_AMOUNT, TX_AMOUNT,
TX_SIGNED_AMOUNT, TX_SIGNED_AMOUNT,
TX_MULTIPLE_RECIPIENT,
TX_SIGHASH_WARNING,
TX_FEE, TX_FEE,
TX_SIGNER, TX_SIGNER,
TX_DATA, TX_DATA,
TX_DATA_NONE, TX_NO,
TX_DATA_ERC20, TX_DATA_ERC20,
TX_DATA_PRESENT, TX_YES,
TX_INPUT, TX_INPUT,
TX_OUTPUT, TX_OUTPUT,
TX_SIGNED, TX_SIGNED,
@ -66,6 +68,7 @@ typedef enum {
TX_SIGN_NONE, TX_SIGN_NONE,
TX_SIGN_SINGLE, TX_SIGN_SINGLE,
TX_SIGN_ANYONECANPAY, TX_SIGN_ANYONECANPAY,
TX_CHANGE,
// MSG Confirmation // MSG Confirmation
MSG_CONFIRM_TITLE, MSG_CONFIRM_TITLE,