layout: op_return now requires confirmation by user

This commit is contained in:
Pavol Rusnak 2017-11-15 15:42:56 +01:00
parent de3b78bd0b
commit 54659d49d8
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
3 changed files with 65 additions and 22 deletions

View File

@ -36,6 +36,33 @@
#define BITCOIN_DIVISIBILITY (8)
// split longer string into 4 rows, rowlen chars each
static const char **split_message(const uint8_t *msg, uint32_t len, uint32_t rowlen)
{
static char str[4][32 + 1];
if (rowlen > 32) {
rowlen = 32;
}
memset(str, 0, sizeof(str));
strlcpy(str[0], (char *)msg, rowlen + 1);
if (len > rowlen) {
strlcpy(str[1], (char *)msg + rowlen, rowlen + 1);
}
if (len > rowlen * 2) {
strlcpy(str[2], (char *)msg + rowlen * 2, rowlen + 1);
}
if (len > rowlen * 3) {
strlcpy(str[3], (char *)msg + rowlen * 3, rowlen + 1);
}
if (len > rowlen * 4) {
str[3][rowlen - 1] = '.';
str[3][rowlen - 2] = '.';
str[3][rowlen - 3] = '.';
}
static const char *ret[4] = { str[0], str[1], str[2], str[3] };
return ret;
}
void *layoutLast = layoutHome;
void layoutDialogSwipe(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6)
@ -128,6 +155,37 @@ void layoutConfirmOutput(const CoinInfo *coin, const TxOutputType *out)
);
}
void layoutConfirmOpReturn(const uint8_t *data, uint32_t size)
{
bool ascii_only = true;
for (uint32_t i = 0; i < size; i++) {
if (data[i] < ' ' || data[i] > '~') {
ascii_only = false;
break;
}
}
const char **str;
if (!ascii_only) {
char hex[65];
memset(hex, 0, sizeof(hex));
data2hex(data, (size > 32) ? 32 : size, hex);
str = split_message((const uint8_t *)hex, size * 2, 16);
} else {
str = split_message(data, size, 20);
}
layoutDialogSwipe(&bmp_icon_question,
_("Cancel"),
_("Confirm"),
NULL,
_("Confirm OP_RETURN:"),
str[0],
str[1],
str[2],
str[3],
NULL
);
}
void layoutConfirmTx(const CoinInfo *coin, uint64_t amount_out, uint64_t amount_fee)
{
char str_out[32], str_fee[32];
@ -163,28 +221,6 @@ void layoutFeeOverThreshold(const CoinInfo *coin, uint64_t fee)
);
}
// split longer string into 4 rows, rowlen chars each
static const char **split_message(const uint8_t *msg, uint32_t len, uint32_t rowlen)
{
static char str[4][32 + 1];
if (rowlen > 32) {
rowlen = 32;
}
memset(str, 0, sizeof(str));
strlcpy(str[0], (char *)msg, rowlen + 1);
if (len > rowlen) {
strlcpy(str[1], (char *)msg + rowlen, rowlen + 1);
}
if (len > rowlen * 2) {
strlcpy(str[2], (char *)msg + rowlen * 2, rowlen + 1);
}
if (len > rowlen * 3) {
strlcpy(str[3], (char *)msg + rowlen * 3, rowlen + 1);
}
static const char *ret[4] = { str[0], str[1], str[2], str[3] };
return ret;
}
void layoutSignMessage(const uint8_t *msg, uint32_t len)
{
const char **str = split_message(msg, len, 16);

View File

@ -41,6 +41,7 @@ void layoutProgressSwipe(const char *desc, int permil);
void layoutScreensaver(void);
void layoutHome(void);
void layoutConfirmOutput(const CoinInfo *coin, const TxOutputType *out);
void layoutConfirmOpReturn(const uint8_t *data, uint32_t size);
void layoutConfirmTx(const CoinInfo *coin, uint64_t amount_out, uint64_t amount_fee);
void layoutFeeOverThreshold(const CoinInfo *coin, uint64_t fee);
void layoutSignMessage(const uint8_t *msg, uint32_t len);

View File

@ -171,6 +171,12 @@ int compile_output(const CoinInfo *coin, const HDNode *root, TxOutputType *in, T
if (in->amount != 0) {
return 0; // failed to compile output
}
if (needs_confirm) {
layoutConfirmOpReturn(in->op_return_data.bytes, in->op_return_data.size);
if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) {
return -1; // user aborted
}
}
uint32_t r = 0;
out->script_pubkey.bytes[0] = 0x6A; r++; // OP_RETURN
r += op_push(in->op_return_data.size, out->script_pubkey.bytes + r);