From 02289e2166aef2816258d115a1d65d80b562f841 Mon Sep 17 00:00:00 2001 From: smdmitry Date: Wed, 25 Dec 2019 17:15:06 +0300 Subject: [PATCH 01/10] metaverse ETP and MST tokens --- Makefile | 12 +- blue_app_metaverse.gif | Bin 0 -> 640 bytes blue_badge_metaverse.gif | Bin 0 -> 640 bytes include/btchip_bcd.h | 2 +- include/btchip_context.h | 7 +- include/btchip_filesystem.h | 3 +- metaverse.png | Bin 0 -> 2935 bytes nanos_app_metaverse.gif | Bin 0 -> 656 bytes nanos_badge_metaverse.gif | Bin 0 -> 656 bytes nanox_app_metaverse.gif | Bin 0 -> 656 bytes src/btchip_apdu_hash_input_finalize_full.c | 29 ++++ src/btchip_bcd.c | 14 +- src/btchip_transaction.c | 21 +++ src/main.c | 147 +++++++++++++++++++-- 14 files changed, 210 insertions(+), 25 deletions(-) mode change 100755 => 100644 Makefile create mode 100644 blue_app_metaverse.gif create mode 100644 blue_badge_metaverse.gif create mode 100644 metaverse.png create mode 100644 nanos_app_metaverse.gif create mode 100644 nanos_badge_metaverse.gif create mode 100644 nanox_app_metaverse.gif diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index d855a87a..e372d27a --- a/Makefile +++ b/Makefile @@ -168,9 +168,15 @@ else ifeq ($(COIN),resistance) DEFINES += COIN_P2PKH_VERSION=7063 COIN_P2SH_VERSION=7068 COIN_FAMILY=1 COIN_COINID=\"Res\" COIN_COINID_HEADER=\"RES\" COIN_COLOR_HDR=0x3790CA COIN_COLOR_DB=0x9BC8E5 COIN_COINID_NAME=\"Res\" COIN_COINID_SHORT=\"RES\" COIN_KIND=COIN_KIND_RESISTANCE APPNAME ="Resistance" APP_LOAD_PARAMS += --path $(APP_PATH) +else ifeq ($(COIN),metaverse) +# Metaverse +DEFINES += COIN_P2PKH_VERSION=50 COIN_P2SH_VERSION=5 COIN_FAMILY=5 COIN_COINID=\"Metaverse\" COIN_COINID_HEADER=\"METAVERSE\" COIN_COLOR_HDR=0xD0DAFB COIN_COLOR_DB=0xE8EDFD COIN_COINID_NAME=\"Metaverse\" COIN_COINID_SHORT=\"ETP\" COIN_KIND=COIN_KIND_METAVERSE +DEFINES_LIB=# while debugging +APPNAME ="Metaverse" +APP_LOAD_PARAMS += --path $(APP_PATH) else ifeq ($(filter clean,$(MAKECMDGOALS)),) -$(error Unsupported COIN - use bitcoin_testnet, bitcoin, bitcoin_cash, bitcoin_gold, litecoin, dogecoin, dash, zcash, horizen, komodo, stratis, peercoin, pivx, viacoin, vertcoin, stealth, digibyte, qtum, bitcoin_private, zcoin, gamecredits, zclassic, xsn, nix, lbry, resistance) +$(error Unsupported COIN - use bitcoin_testnet, bitcoin, bitcoin_cash, bitcoin_gold, litecoin, dogecoin, dash, zcash, horizen, komodo, stratis, peercoin, pivx, viacoin, vertcoin, stealth, digibyte, qtum, bitcoin_private, zcoin, gamecredits, zclassic, xsn, nix, lbry, resistance, metaverse) endif endif @@ -318,6 +324,6 @@ listvariants: else listvariants: - @echo VARIANTS COIN bitcoin_testnet bitcoin bitcoin_cash bitcoin_gold litecoin dogecoin dash zcash horizen komodo stratis peercoin pivx viacoin vertcoin stealth digibyte qtum bitcoin_private zcoin gamecredits zclassic xsn nix lbry resistance + @echo VARIANTS COIN bitcoin_testnet bitcoin bitcoin_cash bitcoin_gold litecoin dogecoin dash zcash horizen komodo stratis peercoin pivx viacoin vertcoin stealth digibyte qtum bitcoin_private zcoin gamecredits zclassic xsn nix lbry resistance metaverse -endif +endif \ No newline at end of file diff --git a/blue_app_metaverse.gif b/blue_app_metaverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..f79567be165009e7d82f62403bbb669fd88f2845 GIT binary patch literal 640 zcmV-`0)PESNk%w1VKM+R0J8u9w8zz&v&P-!>xZSgdYiOHb(lG8kjmKNRDYk--Q@7| z_HL4{VTq^t`T76<|14pNA^8LV00000EC2ui05SkF000F4u*peV3WUAQyY~zcBvolP z!ccr{%NB!hmdfDXcsD4slo+`n&OkZ=gdD>P=>eD$%m={XH~^!Y;zV&35~$RGr=ZCh zcoUn8jOYZw)y~)P%MB)i+uU*7>>XkpaB4U*4TK*Ba1I0ish%O5Rpg0#eQ&e?W4@#YlI3fd)Omm!aWk~@C2ez^v3Sce290`-f9?T93 zLYj-t9S8si3)71Z%GOM!aMBwE*=-vJ005Zg2dh}GVH*L*Q~(C`U;zb>VY;)>**O4U z+k*q$5+>x51YtCTO!9T}x360VhhPLUF$d>C0gMj+Jc8t)Xj6-P4IBu7$blM_4K71I zh}p7RpAR6tf#^7sCru9az?|A34$e)OK9eHj@F&*JMF*a~?78%3%WSz?6a^Et!_Tig zqvT{sbt>4UQ4Ba#K&)m}rBgQy2$0nbJfv^)#)U=)U<(4m3c585SLOm!K`1i98>ehn zmwgoXVzHG9LrnsHVTPzF!LQ0gKPaZ60YNX*9uN$b2j#=J(K^8~2tXEQ+Xt1Y+{FQ- zHVY9SX{eh)CISxl_ zBGiqrZyyXD3bG)8#)JE?Sdzd{mOuDIpfSNMaaf1|AS)(Z2Tl%7oZ!@gE)dZ}12sVC a!VVMSp@N0w#E{_=7#x^G2qR1w0RTH+GY$j* literal 0 HcmV?d00001 diff --git a/blue_badge_metaverse.gif b/blue_badge_metaverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..f79567be165009e7d82f62403bbb669fd88f2845 GIT binary patch literal 640 zcmV-`0)PESNk%w1VKM+R0J8u9w8zz&v&P-!>xZSgdYiOHb(lG8kjmKNRDYk--Q@7| z_HL4{VTq^t`T76<|14pNA^8LV00000EC2ui05SkF000F4u*peV3WUAQyY~zcBvolP z!ccr{%NB!hmdfDXcsD4slo+`n&OkZ=gdD>P=>eD$%m={XH~^!Y;zV&35~$RGr=ZCh zcoUn8jOYZw)y~)P%MB)i+uU*7>>XkpaB4U*4TK*Ba1I0ish%O5Rpg0#eQ&e?W4@#YlI3fd)Omm!aWk~@C2ez^v3Sce290`-f9?T93 zLYj-t9S8si3)71Z%GOM!aMBwE*=-vJ005Zg2dh}GVH*L*Q~(C`U;zb>VY;)>**O4U z+k*q$5+>x51YtCTO!9T}x360VhhPLUF$d>C0gMj+Jc8t)Xj6-P4IBu7$blM_4K71I zh}p7RpAR6tf#^7sCru9az?|A34$e)OK9eHj@F&*JMF*a~?78%3%WSz?6a^Et!_Tig zqvT{sbt>4UQ4Ba#K&)m}rBgQy2$0nbJfv^)#)U=)U<(4m3c585SLOm!K`1i98>ehn zmwgoXVzHG9LrnsHVTPzF!LQ0gKPaZ60YNX*9uN$b2j#=J(K^8~2tXEQ+Xt1Y+{FQ- zHVY9SX{eh)CISxl_ zBGiqrZyyXD3bG)8#)JE?Sdzd{mOuDIpfSNMaaf1|AS)(Z2Tl%7oZ!@gE)dZ}12sVC a!VVMSp@N0w#E{_=7#x^G2qR1w0RTH+GY$j* literal 0 HcmV?d00001 diff --git a/include/btchip_bcd.h b/include/btchip_bcd.h index bb17304d..225d09ca 100644 --- a/include/btchip_bcd.h +++ b/include/btchip_bcd.h @@ -20,6 +20,6 @@ #define BTCHIP_BCD_H unsigned char -btchip_convert_hex_amount_to_displayable(unsigned char *amount); +btchip_convert_hex_amount_to_displayable(unsigned char *amount, unsigned char decimals); #endif diff --git a/include/btchip_context.h b/include/btchip_context.h index 71fa81c8..2ca43fa9 100644 --- a/include/btchip_context.h +++ b/include/btchip_context.h @@ -250,6 +250,8 @@ struct btchip_context_s { unsigned char nExpiryHeight[4]; unsigned char nLockTime[4]; unsigned char sigHashType[4]; + + unsigned char decimals[4]; // For Metaverse tokens, need to provide precision for all outputs from external source (maximum can handle 4 outputs with tokens) }; typedef struct btchip_context_s btchip_context_t; @@ -292,7 +294,8 @@ typedef enum btchip_coin_kind_e { COIN_KIND_XSN, COIN_KIND_NIX, COIN_KIND_LBRY, - COIN_KIND_RESISTANCE + COIN_KIND_RESISTANCE, + COIN_KIND_METAVERSE } btchip_coin_kind_t; typedef struct btchip_altcoin_config_s { @@ -316,4 +319,6 @@ typedef struct btchip_altcoin_config_s { void btchip_context_init(void); +#define DECIMALS (!(G_coin_config->flags & FLAG_PEERCOIN_UNITS) ? 8 : 6) + #endif diff --git a/include/btchip_filesystem.h b/include/btchip_filesystem.h index 555953c8..77eae7be 100644 --- a/include/btchip_filesystem.h +++ b/include/btchip_filesystem.h @@ -35,7 +35,8 @@ enum btchip_family_e { BTCHIP_FAMILY_BITCOIN = 0x01, BTCHIP_FAMILY_PEERCOIN = 0x02, BTCHIP_FAMILY_QTUM = 0x03, - BTCHIP_FAMILY_STEALTH = 0x04 + BTCHIP_FAMILY_STEALTH = 0x04, + BTCHIP_FAMILY_METAVERSE = 0x05 }; struct btchip_config_s { diff --git a/metaverse.png b/metaverse.png new file mode 100644 index 0000000000000000000000000000000000000000..da7bbd0c9ba320e58191cb783a0407027bf42acf GIT binary patch literal 2935 zcmV--3yAcIP)^@RCodHoo#Fs#~H^TlM)C8Oa%cIN^tX{I1*Qz7OF}{s%u0V z@#U^*Dut>D`}oiXi9kQ}sMJWfQY)3~2Mn|{UpNjWEmcdvmLj4AK}?DjML5CEMTsq> zloy4(h)P^YNobT%{l_!s_0HVx?Ci_!`SvGSmUni2cl*D2=6RlZcBbj}?b{R;scgQT zh+2q9{BGed{r$+^gfo|j=psL3(DHkvRLEU-yfPp{6(p6-XNahi3lNu^Zc3Sp!+uJI z+(;NN61X6#Y`&X_AVgYfoL-^z0xah|w&aF#Ulzy`@5~==YQQ z5`+uUOGKNc#>S+~h3Si2kW@C`%X>v5_6Rr7W4cR)+@Q;O5}pO&o)Wrdo79+KXD{zD z+8&xGLHK~(m-GrxjKaw&6>=AKF47hxmCeIE?U5Q1bimlsspE}l36jd@i^;(48!b_0 zNJngNGnI(pADH<;J_c9Cv4`+T`?%ClW4gZm0JSb(Oy|b0(7Cb8@w@fTzyoWqHqd`X zI>O;GhVMWpNaoF%MTd57qz9KTX8-jGA{xK)5%ugoLN{*Siql(lVg+=yK=a82ty(lMvwF{d|`%`dROMag9GlX~m% z6M6+gu6b}dGk5(%rKrtbGmq)Itp`;-WCyo%v7_1mK5(`q9djeyv62e8$LWc52jw<) z(Mx~)1skIxW-}kFD@Z+r3la+WM&d>+ThvVNT`SYT&|6h+vWf!(L)3cDV*0_V2P&<@ z<5%dJlf#O$o!OdMJEeW@U9%|Dkuv&UKIyggk|}O4A3F|(@v0EwcUv|{$MZ){d%g(} zW!{|GbmQh{GJ#*ogi?+5Zt!?r;af8%(cs1S$vaapG^ ztHhuldJhp?y;f#F2};_9$#R@DNtg-()2-%>O*- zOmpXqR5l-(xtb1i*@9eTivwhVD!Hf)0zOO{iEjx8Y2>A*^B6G>N2Fu&?|@^dwmTND zTHkFlsKbsv_uC%oSouw6OY!rq`<60+AV{^iquzP*-K*3D_q3^r#ZS+kd_B-lWYj~@ zGxlzKRLYhLkVr(LZo2jqmJtpqD~v&1nnrX3c68~&`Hp9yrzDsO;@Rb0rs3|vq$QXM zk`N<|1aZsW5>F^5c*jT(r|d2G%EPm@=2XAoS zwjZ(A^KxBOG_CB}J!q18#|PQB?NM573yhFX-@gBtR^ku?|JF>$6mJb;KJ(JBmp z=YRdvbyKdx>mKMoTQ!w0VkSh`R`7a%_}i(f*F}x7AOcZmOFT%@`Cten(HopRHQZoK zvsz6buG_h>OR8S9f|Ne4vwk5UAgWB9UJpHf_mR^zuNC$!h!R` zU)1x+nknT!Zs3b?a(JA&ANj7Q*TZ$_owbUgM5Nv#wS)lN<+Z7MJ!MI8?vk&~rTf2e zwsku9is0ROsaX1jd43@M`n~ z;@IU6rDH0*Okz2YrZz;HBWb*Wg3}e`+a4Z!nt4-V06%^Hf>C9rmLP66Qh*)=@fxv26yr${8DlMzg%p4;^E{lJ zAfqM7xp93jp$?b2h!t9bzyx7_!j0rP5C3R;S(pV>c@hG&Ay<^(4{bq24oKBg;NBrg z*l2-a7QlK>R9Ap>k`R}tU*=HLm>MQf_+MICgD zYAM(7QnNESW3bz97YT*3L+LUsR2yK2I#XzB4r|C)# zTQ+=8tMH6?#o@sduSv%%G&Rwlqi2j35!-Y06*eK{1!Niej-H`6-+kZn>k+^4sH9wW z_X0L%KwOkExlQT1fnsZj@v_T#O5pmbz9rR2W%E^95(J6c8!tv@nCt>0@ZwfFrS20d zTo*mW$kF#Q7^)VXOpq89f;jGJQ4P3%I)%&3duqUH6ay-2E*hJyC-)z7eE^hAY$a=C z=`bQ9b>oc@5$rv-tH=T+MCGDn2tvS2)$;K$uZU9Fb^P&x{LJ;E~ zBEWc3??n#Qy-5IqUIf1ptqaLCU?z(%bA3iSrGY?lR8_W6*$u(qpkVrzPB#eT!fsnwe77`%~{?y7iMr6?Sgvei0C+vcUR`Rh@yQYv}~ z+)KnYrf#NK1BJNDS|^p1hf9TAWkVO$jA36?t6U2pfZwg}#QG@$xU6^vunt`DDf@k? zvb}wL^TSB-8+@s}Bri|D)`-LQO^YQ#cuZ1vyR@l1p_tbimsL9&NrKRXD8+gU6z!P; zcucyBsMQGNKI_t;F5p`rjnvyRGTxfqw6 z?rT*+XhIbD$30R*f+_f>WK^a~OAwkIPYz2B30?_igL^Ity4WwJh6G)-#LyOmi_*u< zS2FeIjZwa#z1Ae4r!pXJzB+4_gsemM@}6-~_pMiTd)?q0iS0;s=TX8uDU%W_V?k&# zR)H{^rN+jj%mcnY(@*b95CIov2luZVvBzBELKLMIj|3u!6}|;HqR_O|IK8;U=P`=9 z1GWx<3t}ae&1bk1&>q$5*&$Nqg$V2?ND-`rDu|s_Hs8+I2o}G^dckoK3*UO-5s3jA hzek*+>%btQ{{ty^>c|O$!I%I5002ovPDHLkV1mqmj8^~v literal 0 HcmV?d00001 diff --git a/nanos_app_metaverse.gif b/nanos_app_metaverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..838245a89bbfda2e02edef2b68333885859ff739 GIT binary patch literal 656 zcmZ?wbhEHb6krfw_`m=Kia%Kx85kHDbU=KN3c-mj#P znPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN*i1Q(;w+TacStlBiITo0C^;Rbi`? zn3A8AY6WD2g!Ppaz)DK8ZIv8B5(*$Yo%4%Q6-@QabdwED3>3^Q^$g7nOiT@R6pRcE z&GijT^$pB)4GgUeEUb(S6`(-Lj!VI&C?(A*$i)q68IWhIlu=SrV5P5LUS6(OZmgGI zl&)`RX=$l%V5DzkqzhD`TU?n}l31aeSF8*&0%C?sYH@N=We6^lgE!9KDdAH?w#AWZr-?l?dp}wmo8p7f9~v=)2B|JIDYKtk;8`$9@xKc@1EVe zcJA1|ZR?iJn>KD(zi#cC)vH#nSiWrOlEsS_E|@=W?wr}PX3m&CZR(WClO|5+@9XX9 z?&|DlZ)c-mj#P znPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN*i1Q(;w+TacStlBiITo0C^;Rbi`? zn3A8AY6WD2g!Ppaz)DK8ZIv8B5(*$Yo%4%Q6-@QabdwED3>3^Q^$g7nOiT@R6pRcE z&GijT^$pB)4GgUeEUb(S6`(-Lj!VI&C?(A*$i)q68IWhIlu=SrV5P5LUS6(OZmgGI zl&)`RX=$l%V5DzkqzhD`TU?n}l31aeSF8*&0%C?sYH@N=We6^lgE!9KDdAH?w#AWZr-?l?dp}wmo8p7f9~v=)2B|JIDYKtk;8`$9@xKc@1EVe zcJA1|ZR?iJn>KD(zi#cC)vH#nSiWrOlEsS_E|@=W?wr}PX3m&CZR(WClO|5+@9XX9 z?&|DlZ)c-mj#P znPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN*i1Q(;w+TacStlBiITo0C^;Rbi`? zn3A8AY6WD2g!Ppaz)DK8ZIv8B5(*$Yo%4%Q6-@QabdwED3>3^Q^$g7nOiT@R6pRcE z&GijT^$pB)4GgUeEUb(S6`(-Lj!VI&C?(A*$i)q68IWhIlu=SrV5P5LUS6(OZmgGI zl&)`RX=$l%V5DzkqzhD`TU?n}l31aeSF8*&0%C?sYH@N=We6^lgE!9KDdAH?w#AWZr-?l?dp}wmo8p7f9~v=)2B|JIDYKtk;8`$9@xKc@1EVe zcJA1|ZR?iJn>KD(zi#cC)vH#nSiWrOlEsS_E|@=W?wr}PX3m&CZR(WClO|5+@9XX9 z?&|DlZ) 4) { // For Metaverse can handle max 4 outputs with tokens + goto discardTransaction; + } + os_memmove(btchip_context_D.decimals, G_io_apdu_buffer + ISO_OFFSET_CDATA, apduLength); + goto return_OK; + } + unsigned char keyLength; if (!btchip_context_D.transactionContext.firstSigned) { // Already validated, should be prevented on the client side diff --git a/src/btchip_bcd.c b/src/btchip_bcd.c index a243ffaa..65e51b75 100644 --- a/src/btchip_bcd.c +++ b/src/btchip_bcd.c @@ -20,16 +20,10 @@ #define SCRATCH_SIZE 21 unsigned char -btchip_convert_hex_amount_to_displayable(unsigned char *amount) { - unsigned char LOOP1; - unsigned char LOOP2; - if (!(G_coin_config->flags & FLAG_PEERCOIN_UNITS)) { - LOOP1 = 13; - LOOP2 = 8; - } else { - LOOP1 = 15; - LOOP2 = 6; - } +btchip_convert_hex_amount_to_displayable(unsigned char *amount, unsigned char decimals) { + unsigned char LOOP1 = SCRATCH_SIZE - decimals; + unsigned char LOOP2 = decimals; + unsigned short scratch[SCRATCH_SIZE]; unsigned char offset = 0; unsigned char nonZero = 0; diff --git a/src/btchip_transaction.c b/src/btchip_transaction.c index 1afbcc0f..62917e0d 100644 --- a/src/btchip_transaction.c +++ b/src/btchip_transaction.c @@ -728,6 +728,27 @@ void transaction_parse(unsigned char parseMode) { btchip_context_D.transactionContext.scriptRemaining = transaction_get_varint(); + if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + unsigned char etpBuff[4]; + unsigned long int scriptRemaining = btchip_context_D.transactionContext.scriptRemaining; + + scriptRemaining += 4; // Version + os_memmove(etpBuff, btchip_context_D.transactionBufferPointer + scriptRemaining, 4); + scriptRemaining += 4; // Type + + if (etpBuff[0] == 2) { + os_memmove(etpBuff, btchip_context_D.transactionBufferPointer + scriptRemaining, 4); + scriptRemaining += 4; // Status + + if (etpBuff[0] == 2) { + scriptRemaining += *(btchip_context_D.transactionBufferPointer + scriptRemaining) + 1 + 8; + // Length varint + Ticker length + Amount length + } + } + + btchip_context_D.transactionContext.scriptRemaining = scriptRemaining; + } + PRINTF("Script to read " DEBUG_LONG "\n",btchip_context_D.transactionContext.scriptRemaining); // Move on btchip_context_D.transactionContext.transactionState = diff --git a/src/main.c b/src/main.c index 0a81ac2b..22611ac3 100644 --- a/src/main.c +++ b/src/main.c @@ -156,8 +156,9 @@ union { // of char fullAddress[65]; // the address - char fullAmount[20]; // full amount + char fullAmount[40]; // full amount (Metaverse can have long token names, so increased from 20 to 40) char feesAmount[20]; // fees + char decimals[3]; } tmp; struct { @@ -983,9 +984,30 @@ const bagl_element_t ui_verify_output_nanos[] = { UI_NANOS_SCROLLING_TEXT(3, 23, 26, 82, vars.tmp.fullAddress, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px) }; +const bagl_element_t ui_verify_output_decimals_nanos[] = { + + UI_NANOS_BACKGROUND(), + UI_NANOS_ICON_LEFT(0, BAGL_GLYPH_ICON_CROSS), + UI_NANOS_ICON_RIGHT(0, BAGL_GLYPH_ICON_CHECK), + UI_NANOS_TEXT(1, 0, 12, 128, "Confirm", BAGL_FONT_OPEN_SANS_EXTRABOLD_11px), + UI_NANOS_TEXT(1, 0, 26, 128, vars.tmp.feesAmount, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px), + + UI_NANOS_TEXT(2, 0, 12, 128, "Amount", BAGL_FONT_OPEN_SANS_REGULAR_11px), + UI_NANOS_SCROLLING_TEXT(2, 23, 26, 82, vars.tmp.fullAmount, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px), + + UI_NANOS_TEXT(3, 0, 12, 128, "Decimals", BAGL_FONT_OPEN_SANS_REGULAR_11px), + UI_NANOS_TEXT(3, 0, 26, 128, vars.tmp.decimals, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px), + + UI_NANOS_TEXT(4, 0, 12, 128, "Address", BAGL_FONT_OPEN_SANS_REGULAR_11px), + UI_NANOS_SCROLLING_TEXT(4, 23, 26, 82, vars.tmp.fullAddress, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px) +}; + unsigned int ui_verify_output_nanos_button(unsigned int button_mask, unsigned int button_mask_counter); +unsigned int ui_verify_output_decimals_nanos_button(unsigned int button_mask, + unsigned int button_mask_counter); + const bagl_element_t ui_finalize_nanos[] = { UI_NANOS_BACKGROUND(), UI_NANOS_ICON_LEFT(0, BAGL_GLYPH_ICON_CROSS), @@ -1229,6 +1251,20 @@ unsigned int ui_verify_output_nanos_button(unsigned int button_mask, return 0; } +unsigned int ui_verify_output_decimals_nanos_button(unsigned int button_mask, + unsigned int button_mask_counter) { + switch (button_mask) { + case BUTTON_EVT_RELEASED | BUTTON_LEFT: + io_seproxyhal_touch_verify_cancel(NULL); + break; + + case BUTTON_EVT_RELEASED | BUTTON_RIGHT: + io_seproxyhal_touch_verify_ok(NULL); + break; + } + return 0; +} + unsigned int ui_finalize_nanos_button(unsigned int button_mask, unsigned int button_mask_counter) { switch (button_mask) { @@ -1667,6 +1703,13 @@ UX_STEP_NOCB( .title = "Address", .text = vars.tmp.fullAddress, }); +UX_STEP_NOCB( + ux_confirm_single_flow_4_step, + bnnn_paging, + { + .title = "Decimals", + .text = vars.tmp.decimals, + }); UX_STEP_VALID( ux_confirm_single_flow_5_step, pb, @@ -1692,6 +1735,16 @@ UX_FLOW(ux_confirm_single_flow, &ux_confirm_single_flow_6_step ); +// confirm_single: confirm output #x(feesAmount) / Amount: fullAmount / Decimals: decimals / Address: fullAddress +UX_FLOW(ux_confirm_single_decimals_flow, + &ux_confirm_single_flow_1_step, + &ux_confirm_single_flow_2_step, + &ux_confirm_single_flow_3_step, + &ux_confirm_single_flow_4_step, + &ux_confirm_single_flow_5_step, + &ux_confirm_single_flow_6_step +); + ////////////////////////////////////////////////////////////////////// UX_STEP_NOCB( @@ -2031,7 +2084,7 @@ uint8_t prepare_fees() { btchip_context_D.tmp = (unsigned char *)(vars.tmp.feesAmount + btchip_context_D.shortCoinIdLength + 1); - textSize = btchip_convert_hex_amount_to_displayable(fees); + textSize = btchip_convert_hex_amount_to_displayable(fees, DECIMALS); vars.tmp.feesAmount[textSize + btchip_context_D.shortCoinIdLength + 1] = '\0'; } @@ -2057,6 +2110,7 @@ uint8_t prepare_single_output() { unsigned short textSize; unsigned char nativeSegwit; + vars.tmp.decimals[0] = '\0'; vars.tmp.fullAddress[0] = '\0'; btchip_swap_bytes(amount, btchip_context_D.currentOutput + offset, 8); offset += 8; @@ -2144,7 +2198,7 @@ uint8_t prepare_single_output() { } headerLength = strlen(vars.tmp.fullAmount); btchip_context_D.tmp = vars.tmp.fullAmount + headerLength; - textSize = btchip_convert_hex_amount_to_displayable(btchip_context_D.currentOutput + offset + 3 + 4 + 4 + 4); + textSize = btchip_convert_hex_amount_to_displayable(btchip_context_D.currentOutput + offset + 3 + 4 + 4 + 4, DECIMALS); vars.tmp.fullAmount[textSize + headerLength] = '\0'; } else { @@ -2154,11 +2208,77 @@ uint8_t prepare_single_output() { btchip_context_D.tmp = (unsigned char *)(vars.tmp.fullAmount + btchip_context_D.shortCoinIdLength + 1); - textSize = btchip_convert_hex_amount_to_displayable(amount); + textSize = btchip_convert_hex_amount_to_displayable(amount, DECIMALS); vars.tmp.fullAmount[textSize + btchip_context_D.shortCoinIdLength + 1] = '\0'; } + if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + vars.tmp.decimals[0] = '\0'; + + unsigned char decimals = DECIMALS; + unsigned char etpBuff[4]; + unsigned char etpVarintLen; + unsigned char *parsePointer = btchip_context_D.currentOutput + offset + 26; + uint8_t headerLength = btchip_context_D.shortCoinIdLength; + + os_memmove(etpBuff, parsePointer, 4); + parsePointer += 4; + + // Version = 1 | 207 (ATTACHMENT.VERSION.DEFAULT | ATTACHMENT.VERSION.DID) + if (etpBuff[0] != 1 || etpBuff[1] != 0 || etpBuff[2] != 0 || etpBuff[3] != 0) { + return 0; + } + + os_memmove(etpBuff, parsePointer, 4); + parsePointer += 4; + + // Type = 0 | 2 (ATTACHMENT.TYPE.ETP_TRANSFER | ATTACHMENT.TYPE.MST) + if (etpBuff[0] == 0 && etpBuff[1] == 0 && etpBuff[2] == 0 && etpBuff[3] == 0) { + } else if (etpBuff[0] == 2 && etpBuff[1] == 0 && etpBuff[2] == 0 && etpBuff[3] == 0) { + os_memmove(etpBuff, parsePointer, 4); + parsePointer += 4; + + // Status = 1 | 2 (MST.STATUS.REGISTER | MST.STATUS.TRANSFER) + if (etpBuff[0] == 2 && etpBuff[1] == 0 && etpBuff[2] == 0 && etpBuff[3] == 0) { + // Ticker text length + etpVarintLen = *parsePointer; + parsePointer += 1; + + // Prepare ticker text + headerLength = etpVarintLen > 10 ? 10 : etpVarintLen; + os_memmove(vars.tmp.fullAmount + 0, parsePointer, headerLength); + vars.tmp.fullAmount[headerLength] = '\0'; + + // Get token transfer amount + parsePointer += etpVarintLen; + btchip_swap_bytes(amount, parsePointer, 8); + parsePointer += 8; + + // Hardcode some tokens with predefined decimals (no need to display decimals confirmation to user) + if (strcmp(vars.tmp.fullAmount, "DNA") == 0) { + decimals = 4; + } else if (strcmp(vars.tmp.fullAmount, "MVS.ZGC") == 0) { + decimals = 8; + } else if (strcmp(vars.tmp.fullAmount, "MVS.ZDC") == 0) { + decimals = 6; + } else { + decimals = btchip_context_D.decimals[btchip_context_D.totalOutputs - btchip_context_D.remainingOutputs]; + snprintf(vars.tmp.decimals, sizeof(vars.tmp.decimals), "%d", decimals); + } + } else { + return 0; + } + } else { + return 0; + } + + vars.tmp.fullAmount[headerLength] = ' '; + btchip_context_D.tmp = (unsigned char *)(vars.tmp.fullAmount + headerLength + 1); + textSize = btchip_convert_hex_amount_to_displayable(amount, decimals); + vars.tmp.fullAmount[textSize + headerLength + 1] = '\0'; + } + return 1; } @@ -2386,7 +2506,7 @@ uint8_t prepare_full_output(uint8_t checkOnly) { (unsigned char *)(vars.tmp.fullAmount + btchip_context_D.shortCoinIdLength + 1); - textSize = btchip_convert_hex_amount_to_displayable(amount); + textSize = btchip_convert_hex_amount_to_displayable(amount, DECIMALS); vars.tmp .fullAmount[textSize + btchip_context_D.shortCoinIdLength + 1] = @@ -2407,7 +2527,7 @@ uint8_t prepare_full_output(uint8_t checkOnly) { (unsigned char *)(vars.tmp.feesAmount + btchip_context_D.shortCoinIdLength + 1); - textSize = btchip_convert_hex_amount_to_displayable(fees); + textSize = btchip_convert_hex_amount_to_displayable(fees, DECIMALS); vars.tmp .feesAmount[textSize + btchip_context_D.shortCoinIdLength + 1] = @@ -2477,11 +2597,20 @@ unsigned int btchip_bagl_confirm_single_output() { #if defined(TARGET_BLUE) ui_transaction_output_blue_init(); #elif defined(HAVE_UX_FLOW) - ux_flow_init(0, ux_confirm_single_flow, NULL); + if (vars.tmp.decimals[0] != '\0') { + ux_flow_init(0, ux_confirm_single_decimals_flow, NULL); + } else { + ux_flow_init(0, ux_confirm_single_flow, NULL); + } #elif defined(TARGET_NANOS) ux_step = 0; - ux_step_count = 3; - UX_DISPLAY(ui_verify_output_nanos, ui_verify_output_prepro); + if (vars.tmp.decimals[0] != '\0') { + ux_step_count = 4; + UX_DISPLAY(ui_verify_output_decimals_nanos, ui_verify_output_prepro); + } else { + ux_step_count = 3; + UX_DISPLAY(ui_verify_output_nanos, ui_verify_output_prepro); + } #endif // TARGET_ return 1; } From 92c1f0b841f04023b7b9537a374ca8572d153d6e Mon Sep 17 00:00:00 2001 From: smdmitry Date: Wed, 25 Dec 2019 19:41:01 +0300 Subject: [PATCH 02/10] amounts sanity check --- include/btchip_context.h | 1 + src/btchip_apdu_hash_input_finalize_full.c | 2 ++ src/btchip_context.c | 2 ++ src/btchip_transaction.c | 6 ++++++ src/main.c | 23 ++++++++++++++++++++++ 5 files changed, 34 insertions(+) diff --git a/include/btchip_context.h b/include/btchip_context.h index 2ca43fa9..22956ab2 100644 --- a/include/btchip_context.h +++ b/include/btchip_context.h @@ -241,6 +241,7 @@ struct btchip_context_s { unsigned int discardSize; unsigned char outputParsingState; unsigned char totalOutputAmount[8]; + unsigned char totalTokenInputAmount[8]; unsigned char changeOutputFound; /* Overwinter */ diff --git a/src/btchip_apdu_hash_input_finalize_full.c b/src/btchip_apdu_hash_input_finalize_full.c index 99a67088..a08e70bf 100644 --- a/src/btchip_apdu_hash_input_finalize_full.c +++ b/src/btchip_apdu_hash_input_finalize_full.c @@ -38,6 +38,8 @@ static void btchip_apdu_hash_input_finalize_full_reset(void) { btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS; os_memset(btchip_context_D.totalOutputAmount, 0, sizeof(btchip_context_D.totalOutputAmount)); + os_memset(btchip_context_D.totalTokenInputAmount, 0, + sizeof(btchip_context_D.totalTokenInputAmount)); btchip_context_D.changeOutputFound = 0; btchip_set_check_internal_structure_integrity(1); } diff --git a/src/btchip_context.c b/src/btchip_context.c index a085ef59..f5d90fc8 100644 --- a/src/btchip_context.c +++ b/src/btchip_context.c @@ -31,6 +31,8 @@ void btchip_context_init() { btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS; os_memset(btchip_context_D.totalOutputAmount, 0, sizeof(btchip_context_D.totalOutputAmount)); + os_memset(btchip_context_D.totalTokenInputAmount, 0, + sizeof(btchip_context_D.totalTokenInputAmount)); btchip_context_D.changeOutputFound = 0; if (N_btchip.config_valid != 0x01) { diff --git a/src/btchip_transaction.c b/src/btchip_transaction.c index 62917e0d..560ac328 100644 --- a/src/btchip_transaction.c +++ b/src/btchip_transaction.c @@ -743,6 +743,12 @@ void transaction_parse(unsigned char parseMode) { if (etpBuff[0] == 2) { scriptRemaining += *(btchip_context_D.transactionBufferPointer + scriptRemaining) + 1 + 8; // Length varint + Ticker length + Amount length + + if ((parseMode == PARSE_MODE_TRUSTED_INPUT) && (btchip_context_D.transactionContext.transactionCurrentInputOutput == btchip_context_D.transactionTargetInput)) { + unsigned char tamount[8]; + btchip_swap_bytes(tamount, btchip_context_D.transactionBufferPointer + scriptRemaining - 8, 8); + transaction_amount_add_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, tamount); + } } } diff --git a/src/main.c b/src/main.c index 22611ac3..45fc8af6 100644 --- a/src/main.c +++ b/src/main.c @@ -2066,6 +2066,22 @@ uint8_t prepare_fees() { unsigned short textSize; unsigned char borrow; + if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + if ( + btchip_context_D.totalTokenInputAmount[0] != 0 || + btchip_context_D.totalTokenInputAmount[1] != 0 || + btchip_context_D.totalTokenInputAmount[2] != 0 || + btchip_context_D.totalTokenInputAmount[3] != 0 || + btchip_context_D.totalTokenInputAmount[4] != 0 || + btchip_context_D.totalTokenInputAmount[5] != 0 || + btchip_context_D.totalTokenInputAmount[6] != 0 || + btchip_context_D.totalTokenInputAmount[7] != 0 + ) { + PRINTF("Error : Token amount not consistent"); + goto error; + } + } + borrow = transaction_amount_sub_be( fees, btchip_context_D.transactionContext.transactionAmount, btchip_context_D.totalOutputAmount); @@ -2236,6 +2252,11 @@ uint8_t prepare_single_output() { // Type = 0 | 2 (ATTACHMENT.TYPE.ETP_TRANSFER | ATTACHMENT.TYPE.MST) if (etpBuff[0] == 0 && etpBuff[1] == 0 && etpBuff[2] == 0 && etpBuff[3] == 0) { } else if (etpBuff[0] == 2 && etpBuff[1] == 0 && etpBuff[2] == 0 && etpBuff[3] == 0) { + // Throw error is ETP amount is non zero + if (amount[0] != 0 || amount[1] != 0 || amount[2] != 0 || amount[3] != 0 || amount[4] != 0 || amount[5] != 0 || amount[6] != 0 || amount[7] != 0) { + return 0; + } + os_memmove(etpBuff, parsePointer, 4); parsePointer += 4; @@ -2255,6 +2276,8 @@ uint8_t prepare_single_output() { btchip_swap_bytes(amount, parsePointer, 8); parsePointer += 8; + transaction_amount_sub_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, amount); + // Hardcode some tokens with predefined decimals (no need to display decimals confirmation to user) if (strcmp(vars.tmp.fullAmount, "DNA") == 0) { decimals = 4; From 8dd435d858456753d4d6ad16166c5f3f5beae7f3 Mon Sep 17 00:00:00 2001 From: smdmitry Date: Thu, 26 Dec 2019 01:47:41 +0300 Subject: [PATCH 03/10] reduce memory consumption --- src/btchip_apdu_hash_input_finalize_full.c | 22 +++--- src/btchip_transaction.c | 28 +++---- src/main.c | 88 +++++++++++++++------- 3 files changed, 86 insertions(+), 52 deletions(-) diff --git a/src/btchip_apdu_hash_input_finalize_full.c b/src/btchip_apdu_hash_input_finalize_full.c index a08e70bf..5f18ef6b 100644 --- a/src/btchip_apdu_hash_input_finalize_full.c +++ b/src/btchip_apdu_hash_input_finalize_full.c @@ -175,24 +175,24 @@ static bool handle_output_state() { discardSize = 1; if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { - unsigned char etpBuff[4]; - unsigned long int scriptRemaining = scriptSize + 9; + // btchip_context_D.nVersionGroupId = unsigned char etpBuff[4]; + btchip_context_D.trustedInputIndex = scriptSize + 9; // unsigned long int scriptRemaining - scriptRemaining += 4; // Version - os_memmove(etpBuff, btchip_context_D.currentOutput + scriptRemaining, 4); - scriptRemaining += 4; // Type + btchip_context_D.trustedInputIndex += 4; // Version + os_memmove(btchip_context_D.nVersionGroupId, btchip_context_D.currentOutput + btchip_context_D.trustedInputIndex, 4); + btchip_context_D.trustedInputIndex += 4; // Type - if (etpBuff[0] == 2) { - os_memmove(etpBuff, btchip_context_D.currentOutput + scriptRemaining, 4); - scriptRemaining += 4; // Status + if (btchip_context_D.nVersionGroupId[0] == 2) { + os_memmove(btchip_context_D.nVersionGroupId, btchip_context_D.currentOutput + btchip_context_D.trustedInputIndex, 4); + btchip_context_D.trustedInputIndex += 4; // Status - if (etpBuff[0] == 2) { - scriptRemaining += *(btchip_context_D.currentOutput + scriptRemaining) + 1 + 8; + if (btchip_context_D.nVersionGroupId[0] == 2) { + btchip_context_D.trustedInputIndex += *(btchip_context_D.currentOutput + btchip_context_D.trustedInputIndex) + 1 + 8; // Length varint + Ticker length + Amount length } } - scriptSize = scriptRemaining - 9; + scriptSize = btchip_context_D.trustedInputIndex - 9; } } else if (btchip_context_D.currentOutput[8] == 0xFD) { if (btchip_context_D.currentOutputOffset < 9 + 2) { diff --git a/src/btchip_transaction.c b/src/btchip_transaction.c index 560ac328..85d8e9d6 100644 --- a/src/btchip_transaction.c +++ b/src/btchip_transaction.c @@ -729,30 +729,30 @@ void transaction_parse(unsigned char parseMode) { transaction_get_varint(); if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { - unsigned char etpBuff[4]; - unsigned long int scriptRemaining = btchip_context_D.transactionContext.scriptRemaining; + // btchip_context_D.nVersionGroupId = unsigned char etpBuff[4]; + btchip_context_D.trustedInputIndex = btchip_context_D.transactionContext.scriptRemaining; // unsigned long int scriptRemaining - scriptRemaining += 4; // Version - os_memmove(etpBuff, btchip_context_D.transactionBufferPointer + scriptRemaining, 4); - scriptRemaining += 4; // Type + btchip_context_D.trustedInputIndex += 4; // Version + os_memmove(btchip_context_D.nVersionGroupId, btchip_context_D.transactionBufferPointer + btchip_context_D.trustedInputIndex, 4); + btchip_context_D.trustedInputIndex += 4; // Type - if (etpBuff[0] == 2) { - os_memmove(etpBuff, btchip_context_D.transactionBufferPointer + scriptRemaining, 4); - scriptRemaining += 4; // Status + if (btchip_context_D.nVersionGroupId[0] == 2) { + os_memmove(btchip_context_D.nVersionGroupId, btchip_context_D.transactionBufferPointer + btchip_context_D.trustedInputIndex, 4); + btchip_context_D.trustedInputIndex += 4; // Status - if (etpBuff[0] == 2) { - scriptRemaining += *(btchip_context_D.transactionBufferPointer + scriptRemaining) + 1 + 8; + if (btchip_context_D.nVersionGroupId[0] == 2) { + btchip_context_D.trustedInputIndex += *(btchip_context_D.transactionBufferPointer + btchip_context_D.trustedInputIndex) + 1 + 8; // Length varint + Ticker length + Amount length if ((parseMode == PARSE_MODE_TRUSTED_INPUT) && (btchip_context_D.transactionContext.transactionCurrentInputOutput == btchip_context_D.transactionTargetInput)) { - unsigned char tamount[8]; - btchip_swap_bytes(tamount, btchip_context_D.transactionBufferPointer + scriptRemaining - 8, 8); - transaction_amount_add_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, tamount); + // btchip_context_D.inputValue = unsigned char tamount[8]; + btchip_swap_bytes(btchip_context_D.inputValue, btchip_context_D.transactionBufferPointer + btchip_context_D.trustedInputIndex - 8, 8); + transaction_amount_add_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, btchip_context_D.inputValue); } } } - btchip_context_D.transactionContext.scriptRemaining = scriptRemaining; + btchip_context_D.transactionContext.scriptRemaining = btchip_context_D.trustedInputIndex; } PRINTF("Script to read " DEBUG_LONG "\n",btchip_context_D.transactionContext.scriptRemaining); diff --git a/src/main.c b/src/main.c index 45fc8af6..8fb9d838 100644 --- a/src/main.c +++ b/src/main.c @@ -156,7 +156,7 @@ union { // of char fullAddress[65]; // the address - char fullAmount[40]; // full amount (Metaverse can have long token names, so increased from 20 to 40) + char fullAmount[20]; // full amount (Metaverse may have long token names, so maybe increase from 20 to 40?) char feesAmount[20]; // fees char decimals[3]; } tmp; @@ -2230,49 +2230,82 @@ uint8_t prepare_single_output() { } if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + // btchip_context_D.nVersionGroupId = unsigned char etpBuff[4]; vars.tmp.decimals[0] = '\0'; - unsigned char decimals = DECIMALS; - unsigned char etpBuff[4]; - unsigned char etpVarintLen; unsigned char *parsePointer = btchip_context_D.currentOutput + offset + 26; - uint8_t headerLength = btchip_context_D.shortCoinIdLength; + btchip_context_D.nExpiryHeight[0] = DECIMALS; + btchip_context_D.nExpiryHeight[1] = 0; + btchip_context_D.nExpiryHeight[2] = btchip_context_D.shortCoinIdLength; - os_memmove(etpBuff, parsePointer, 4); + // btchip_context_D.nExpiryHeight[0] = unsigned char decimals = DECIMALS; + // btchip_context_D.nExpiryHeight[1] = unsigned char etpVarintLen; + // btchip_context_D.nExpiryHeight[2] = unsigned char headerLength = btchip_context_D.shortCoinIdLength; + + + os_memmove(btchip_context_D.nVersionGroupId, parsePointer, 4); parsePointer += 4; // Version = 1 | 207 (ATTACHMENT.VERSION.DEFAULT | ATTACHMENT.VERSION.DID) - if (etpBuff[0] != 1 || etpBuff[1] != 0 || etpBuff[2] != 0 || etpBuff[3] != 0) { + if ( + btchip_context_D.nVersionGroupId[0] != 1 || + btchip_context_D.nVersionGroupId[1] != 0 || + btchip_context_D.nVersionGroupId[2] != 0 || + btchip_context_D.nVersionGroupId[3] != 0 + ) { return 0; } - os_memmove(etpBuff, parsePointer, 4); + os_memmove(btchip_context_D.nVersionGroupId, parsePointer, 4); parsePointer += 4; // Type = 0 | 2 (ATTACHMENT.TYPE.ETP_TRANSFER | ATTACHMENT.TYPE.MST) - if (etpBuff[0] == 0 && etpBuff[1] == 0 && etpBuff[2] == 0 && etpBuff[3] == 0) { - } else if (etpBuff[0] == 2 && etpBuff[1] == 0 && etpBuff[2] == 0 && etpBuff[3] == 0) { + if ( + btchip_context_D.nVersionGroupId[0] == 0 && + btchip_context_D.nVersionGroupId[1] == 0 && + btchip_context_D.nVersionGroupId[2] == 0 && + btchip_context_D.nVersionGroupId[3] == 0) { + } else if ( + btchip_context_D.nVersionGroupId[0] == 2 && + btchip_context_D.nVersionGroupId[1] == 0 && + btchip_context_D.nVersionGroupId[2] == 0 && + btchip_context_D.nVersionGroupId[3] == 0 + ) { // Throw error is ETP amount is non zero - if (amount[0] != 0 || amount[1] != 0 || amount[2] != 0 || amount[3] != 0 || amount[4] != 0 || amount[5] != 0 || amount[6] != 0 || amount[7] != 0) { + if ( + amount[0] != 0 || + amount[1] != 0 || + amount[2] != 0 || + amount[3] != 0 || + amount[4] != 0 || + amount[5] != 0 || + amount[6] != 0 || + amount[7] != 0 + ) { return 0; } - os_memmove(etpBuff, parsePointer, 4); + os_memmove(btchip_context_D.nVersionGroupId, parsePointer, 4); parsePointer += 4; // Status = 1 | 2 (MST.STATUS.REGISTER | MST.STATUS.TRANSFER) - if (etpBuff[0] == 2 && etpBuff[1] == 0 && etpBuff[2] == 0 && etpBuff[3] == 0) { + if ( + btchip_context_D.nVersionGroupId[0] == 2 && + btchip_context_D.nVersionGroupId[1] == 0 && + btchip_context_D.nVersionGroupId[2] == 0 && + btchip_context_D.nVersionGroupId[3] == 0 + ) { // Ticker text length - etpVarintLen = *parsePointer; + btchip_context_D.nExpiryHeight[1] = *parsePointer; parsePointer += 1; // Prepare ticker text - headerLength = etpVarintLen > 10 ? 10 : etpVarintLen; - os_memmove(vars.tmp.fullAmount + 0, parsePointer, headerLength); - vars.tmp.fullAmount[headerLength] = '\0'; + btchip_context_D.nExpiryHeight[2] = btchip_context_D.nExpiryHeight[1] > 10 ? 10 : btchip_context_D.nExpiryHeight[1]; + os_memmove(vars.tmp.fullAmount, parsePointer, btchip_context_D.nExpiryHeight[2]); + vars.tmp.fullAmount[btchip_context_D.nExpiryHeight[2]] = '\0'; // Get token transfer amount - parsePointer += etpVarintLen; + parsePointer += btchip_context_D.nExpiryHeight[1]; btchip_swap_bytes(amount, parsePointer, 8); parsePointer += 8; @@ -2280,14 +2313,14 @@ uint8_t prepare_single_output() { // Hardcode some tokens with predefined decimals (no need to display decimals confirmation to user) if (strcmp(vars.tmp.fullAmount, "DNA") == 0) { - decimals = 4; + btchip_context_D.nExpiryHeight[0] = 4; } else if (strcmp(vars.tmp.fullAmount, "MVS.ZGC") == 0) { - decimals = 8; + btchip_context_D.nExpiryHeight[0] = 8; } else if (strcmp(vars.tmp.fullAmount, "MVS.ZDC") == 0) { - decimals = 6; + btchip_context_D.nExpiryHeight[0] = 6; } else { - decimals = btchip_context_D.decimals[btchip_context_D.totalOutputs - btchip_context_D.remainingOutputs]; - snprintf(vars.tmp.decimals, sizeof(vars.tmp.decimals), "%d", decimals); + btchip_context_D.nExpiryHeight[0] = btchip_context_D.decimals[btchip_context_D.totalOutputs - btchip_context_D.remainingOutputs]; + snprintf(vars.tmp.decimals, sizeof(vars.tmp.decimals), "%d", btchip_context_D.nExpiryHeight[0]); } } else { return 0; @@ -2296,10 +2329,11 @@ uint8_t prepare_single_output() { return 0; } - vars.tmp.fullAmount[headerLength] = ' '; - btchip_context_D.tmp = (unsigned char *)(vars.tmp.fullAmount + headerLength + 1); - textSize = btchip_convert_hex_amount_to_displayable(amount, decimals); - vars.tmp.fullAmount[textSize + headerLength + 1] = '\0'; + vars.tmp.fullAmount[btchip_context_D.nExpiryHeight[2]] = ' '; + btchip_context_D.tmp = (unsigned char *)(vars.tmp.fullAmount + btchip_context_D.nExpiryHeight[2] + 1); + textSize = btchip_convert_hex_amount_to_displayable(amount, btchip_context_D.nExpiryHeight[0]); + vars.tmp.fullAmount[textSize + btchip_context_D.nExpiryHeight[2] + 1] = '\0'; + vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 1] = '\0'; } return 1; From 9ee15def957ca5f7c6f52c3ed559c6d135232471 Mon Sep 17 00:00:00 2001 From: smdmitry Date: Thu, 26 Dec 2019 16:29:09 +0300 Subject: [PATCH 04/10] change path and defines --- include/btchip_context.h | 8 +++ src/btchip_apdu_hash_input_finalize_full.c | 44 +++++++----- src/btchip_helpers.c | 12 ++++ src/btchip_transaction.c | 35 ++++++---- src/main.c | 80 ++++++++++------------ 5 files changed, 105 insertions(+), 74 deletions(-) diff --git a/include/btchip_context.h b/include/btchip_context.h index 22956ab2..834b00e2 100644 --- a/include/btchip_context.h +++ b/include/btchip_context.h @@ -322,4 +322,12 @@ void btchip_context_init(void); #define DECIMALS (!(G_coin_config->flags & FLAG_PEERCOIN_UNITS) ? 8 : 6) +// Metaverse reuse context variables to save memory +#define ETP_COUNTER btchip_context_D.trustedInputIndex // unsigned long int +#define ETP_BUFF btchip_context_D.nVersionGroupId // unsigned char[4] +#define ETP_AMOUNT btchip_context_D.inputValue // unsigned char[8] +#define ETP_DECIMALS btchip_context_D.nExpiryHeight[0] // unsigned char +#define ETP_LENGTH btchip_context_D.nExpiryHeight[1] // unsigned char +#define ETP_TMP btchip_context_D.nExpiryHeight[2] // unsigned char + #endif diff --git a/src/btchip_apdu_hash_input_finalize_full.c b/src/btchip_apdu_hash_input_finalize_full.c index 5f18ef6b..7d60786a 100644 --- a/src/btchip_apdu_hash_input_finalize_full.c +++ b/src/btchip_apdu_hash_input_finalize_full.c @@ -109,12 +109,22 @@ static bool check_output_displayable() { } } if (changeFound) { - if (btchip_context_D.changeOutputFound) { - PRINTF("Error : Multiple change output found"); - THROW(EXCEPTION); + // Allow 2 change outputs for metaverse (ETP + token) + if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + if (btchip_context_D.changeOutputFound >= 2) { + PRINTF("Error : Multiple change output found"); + THROW(EXCEPTION); + } + btchip_context_D.changeOutputFound++; + displayable = false; + } else { + if (btchip_context_D.changeOutputFound) { + PRINTF("Error : Multiple change output found"); + THROW(EXCEPTION); + } + btchip_context_D.changeOutputFound = true; + displayable = false; } - btchip_context_D.changeOutputFound = true; - displayable = false; } } @@ -175,24 +185,26 @@ static bool handle_output_state() { discardSize = 1; if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { - // btchip_context_D.nVersionGroupId = unsigned char etpBuff[4]; - btchip_context_D.trustedInputIndex = scriptSize + 9; // unsigned long int scriptRemaining + ETP_COUNTER = scriptSize + 9; - btchip_context_D.trustedInputIndex += 4; // Version - os_memmove(btchip_context_D.nVersionGroupId, btchip_context_D.currentOutput + btchip_context_D.trustedInputIndex, 4); - btchip_context_D.trustedInputIndex += 4; // Type + ETP_COUNTER += 4; // Version + os_memmove(ETP_BUFF, btchip_context_D.currentOutput + ETP_COUNTER, 4); + ETP_COUNTER += 4; // Type - if (btchip_context_D.nVersionGroupId[0] == 2) { - os_memmove(btchip_context_D.nVersionGroupId, btchip_context_D.currentOutput + btchip_context_D.trustedInputIndex, 4); - btchip_context_D.trustedInputIndex += 4; // Status + if (ETP_BUFF[0] == 2) { + os_memmove(ETP_BUFF, btchip_context_D.currentOutput + ETP_COUNTER, 4); + ETP_COUNTER += 4; // Status - if (btchip_context_D.nVersionGroupId[0] == 2) { - btchip_context_D.trustedInputIndex += *(btchip_context_D.currentOutput + btchip_context_D.trustedInputIndex) + 1 + 8; + if (ETP_BUFF[0] == 2) { + ETP_COUNTER += *(btchip_context_D.currentOutput + ETP_COUNTER) + 1 + 8; // Length varint + Ticker length + Amount length + + btchip_swap_bytes(ETP_AMOUNT, btchip_context_D.currentOutput + ETP_COUNTER - 8, 8); + transaction_amount_sub_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, ETP_AMOUNT); } } - scriptSize = btchip_context_D.trustedInputIndex - 9; + scriptSize = ETP_COUNTER - 9; } } else if (btchip_context_D.currentOutput[8] == 0xFD) { if (btchip_context_D.currentOutputOffset < 9 + 2) { diff --git a/src/btchip_helpers.c b/src/btchip_helpers.c index 4369e884..4cec568c 100644 --- a/src/btchip_helpers.c +++ b/src/btchip_helpers.c @@ -354,6 +354,18 @@ unsigned char bip44_derivation_guard(unsigned char *bip32Path, bool is_change_pa return 1; } + // Allow change path to be 0 or 1 (no security threats here) + if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + // If the account or address index is very high or if the change isn't 0 or 1, return a warning + if((bip32PathInt[BIP44_ACCOUNT_OFFSET]^0x80000000) > MAX_BIP44_ACCOUNT_RECOMMENDED || + (bip32PathInt[BIP44_CHANGE_OFFSET] != 0 && bip32PathInt[BIP44_CHANGE_OFFSET] != 1) || + bip32PathInt[BIP44_ADDRESS_INDEX_OFFSET] > MAX_BIP44_ADDRESS_INDEX_RECOMMENDED) { + return 1; + } + + return 0; + } + // If the account or address index is very high or if the change isn't 1, return a warning if((bip32PathInt[BIP44_ACCOUNT_OFFSET]^0x80000000) > MAX_BIP44_ACCOUNT_RECOMMENDED || bip32PathInt[BIP44_CHANGE_OFFSET] != is_change_path?1:0 || diff --git a/src/btchip_transaction.c b/src/btchip_transaction.c index 85d8e9d6..ce188bb6 100644 --- a/src/btchip_transaction.c +++ b/src/btchip_transaction.c @@ -729,30 +729,35 @@ void transaction_parse(unsigned char parseMode) { transaction_get_varint(); if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { - // btchip_context_D.nVersionGroupId = unsigned char etpBuff[4]; - btchip_context_D.trustedInputIndex = btchip_context_D.transactionContext.scriptRemaining; // unsigned long int scriptRemaining + ETP_COUNTER = btchip_context_D.transactionContext.scriptRemaining; - btchip_context_D.trustedInputIndex += 4; // Version - os_memmove(btchip_context_D.nVersionGroupId, btchip_context_D.transactionBufferPointer + btchip_context_D.trustedInputIndex, 4); - btchip_context_D.trustedInputIndex += 4; // Type + ETP_COUNTER += 4; // Version + os_memmove(ETP_BUFF, btchip_context_D.transactionBufferPointer + ETP_COUNTER, 4); + ETP_COUNTER += 4; // Type - if (btchip_context_D.nVersionGroupId[0] == 2) { - os_memmove(btchip_context_D.nVersionGroupId, btchip_context_D.transactionBufferPointer + btchip_context_D.trustedInputIndex, 4); - btchip_context_D.trustedInputIndex += 4; // Status + if (ETP_BUFF[0] == 2) { + os_memmove(ETP_BUFF, btchip_context_D.transactionBufferPointer + ETP_COUNTER, 4); + ETP_COUNTER += 4; // Status - if (btchip_context_D.nVersionGroupId[0] == 2) { - btchip_context_D.trustedInputIndex += *(btchip_context_D.transactionBufferPointer + btchip_context_D.trustedInputIndex) + 1 + 8; + if (ETP_BUFF[0] == 2) { + ETP_COUNTER += *(btchip_context_D.transactionBufferPointer + ETP_COUNTER) + 1 + 8; // Length varint + Ticker length + Amount length - if ((parseMode == PARSE_MODE_TRUSTED_INPUT) && (btchip_context_D.transactionContext.transactionCurrentInputOutput == btchip_context_D.transactionTargetInput)) { - // btchip_context_D.inputValue = unsigned char tamount[8]; - btchip_swap_bytes(btchip_context_D.inputValue, btchip_context_D.transactionBufferPointer + btchip_context_D.trustedInputIndex - 8, 8); - transaction_amount_add_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, btchip_context_D.inputValue); + if ( + parseMode == PARSE_MODE_TRUSTED_INPUT && + btchip_context_D.transactionContext.transactionCurrentInputOutput == btchip_context_D.transactionTargetInput + ) { + btchip_swap_bytes(ETP_AMOUNT, btchip_context_D.transactionBufferPointer + ETP_COUNTER - 8, 8); + transaction_amount_add_be( + btchip_context_D.totalTokenInputAmount, + btchip_context_D.totalTokenInputAmount, + ETP_AMOUNT + ); } } } - btchip_context_D.transactionContext.scriptRemaining = btchip_context_D.trustedInputIndex; + btchip_context_D.transactionContext.scriptRemaining = ETP_COUNTER; } PRINTF("Script to read " DEBUG_LONG "\n",btchip_context_D.transactionContext.scriptRemaining); diff --git a/src/main.c b/src/main.c index 8fb9d838..0c7cc858 100644 --- a/src/main.c +++ b/src/main.c @@ -2230,46 +2230,40 @@ uint8_t prepare_single_output() { } if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { - // btchip_context_D.nVersionGroupId = unsigned char etpBuff[4]; vars.tmp.decimals[0] = '\0'; unsigned char *parsePointer = btchip_context_D.currentOutput + offset + 26; - btchip_context_D.nExpiryHeight[0] = DECIMALS; - btchip_context_D.nExpiryHeight[1] = 0; - btchip_context_D.nExpiryHeight[2] = btchip_context_D.shortCoinIdLength; + ETP_DECIMALS = DECIMALS; + ETP_TMP = 0; + ETP_LENGTH = btchip_context_D.shortCoinIdLength; - // btchip_context_D.nExpiryHeight[0] = unsigned char decimals = DECIMALS; - // btchip_context_D.nExpiryHeight[1] = unsigned char etpVarintLen; - // btchip_context_D.nExpiryHeight[2] = unsigned char headerLength = btchip_context_D.shortCoinIdLength; - - - os_memmove(btchip_context_D.nVersionGroupId, parsePointer, 4); + os_memmove(ETP_BUFF, parsePointer, 4); parsePointer += 4; // Version = 1 | 207 (ATTACHMENT.VERSION.DEFAULT | ATTACHMENT.VERSION.DID) if ( - btchip_context_D.nVersionGroupId[0] != 1 || - btchip_context_D.nVersionGroupId[1] != 0 || - btchip_context_D.nVersionGroupId[2] != 0 || - btchip_context_D.nVersionGroupId[3] != 0 + ETP_BUFF[0] != 1 || + ETP_BUFF[1] != 0 || + ETP_BUFF[2] != 0 || + ETP_BUFF[3] != 0 ) { return 0; } - os_memmove(btchip_context_D.nVersionGroupId, parsePointer, 4); + os_memmove(ETP_BUFF, parsePointer, 4); parsePointer += 4; // Type = 0 | 2 (ATTACHMENT.TYPE.ETP_TRANSFER | ATTACHMENT.TYPE.MST) if ( - btchip_context_D.nVersionGroupId[0] == 0 && - btchip_context_D.nVersionGroupId[1] == 0 && - btchip_context_D.nVersionGroupId[2] == 0 && - btchip_context_D.nVersionGroupId[3] == 0) { + ETP_BUFF[0] == 0 && + ETP_BUFF[1] == 0 && + ETP_BUFF[2] == 0 && + ETP_BUFF[3] == 0) { } else if ( - btchip_context_D.nVersionGroupId[0] == 2 && - btchip_context_D.nVersionGroupId[1] == 0 && - btchip_context_D.nVersionGroupId[2] == 0 && - btchip_context_D.nVersionGroupId[3] == 0 + ETP_BUFF[0] == 2 && + ETP_BUFF[1] == 0 && + ETP_BUFF[2] == 0 && + ETP_BUFF[3] == 0 ) { // Throw error is ETP amount is non zero if ( @@ -2285,42 +2279,42 @@ uint8_t prepare_single_output() { return 0; } - os_memmove(btchip_context_D.nVersionGroupId, parsePointer, 4); + os_memmove(ETP_BUFF, parsePointer, 4); parsePointer += 4; // Status = 1 | 2 (MST.STATUS.REGISTER | MST.STATUS.TRANSFER) if ( - btchip_context_D.nVersionGroupId[0] == 2 && - btchip_context_D.nVersionGroupId[1] == 0 && - btchip_context_D.nVersionGroupId[2] == 0 && - btchip_context_D.nVersionGroupId[3] == 0 + ETP_BUFF[0] == 2 && + ETP_BUFF[1] == 0 && + ETP_BUFF[2] == 0 && + ETP_BUFF[3] == 0 ) { // Ticker text length - btchip_context_D.nExpiryHeight[1] = *parsePointer; + ETP_TMP = *parsePointer; parsePointer += 1; // Prepare ticker text - btchip_context_D.nExpiryHeight[2] = btchip_context_D.nExpiryHeight[1] > 10 ? 10 : btchip_context_D.nExpiryHeight[1]; - os_memmove(vars.tmp.fullAmount, parsePointer, btchip_context_D.nExpiryHeight[2]); - vars.tmp.fullAmount[btchip_context_D.nExpiryHeight[2]] = '\0'; + ETP_LENGTH = ETP_TMP > 10 ? 10 : ETP_TMP; + os_memmove(vars.tmp.fullAmount, parsePointer, ETP_LENGTH); + vars.tmp.fullAmount[ETP_LENGTH] = '\0'; // Get token transfer amount - parsePointer += btchip_context_D.nExpiryHeight[1]; + parsePointer += ETP_TMP; btchip_swap_bytes(amount, parsePointer, 8); parsePointer += 8; - transaction_amount_sub_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, amount); + //transaction_amount_sub_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, amount); // Hardcode some tokens with predefined decimals (no need to display decimals confirmation to user) if (strcmp(vars.tmp.fullAmount, "DNA") == 0) { - btchip_context_D.nExpiryHeight[0] = 4; + ETP_DECIMALS = 4; } else if (strcmp(vars.tmp.fullAmount, "MVS.ZGC") == 0) { - btchip_context_D.nExpiryHeight[0] = 8; + ETP_DECIMALS = 8; } else if (strcmp(vars.tmp.fullAmount, "MVS.ZDC") == 0) { - btchip_context_D.nExpiryHeight[0] = 6; + ETP_DECIMALS = 6; } else { - btchip_context_D.nExpiryHeight[0] = btchip_context_D.decimals[btchip_context_D.totalOutputs - btchip_context_D.remainingOutputs]; - snprintf(vars.tmp.decimals, sizeof(vars.tmp.decimals), "%d", btchip_context_D.nExpiryHeight[0]); + ETP_DECIMALS = btchip_context_D.decimals[btchip_context_D.totalOutputs - btchip_context_D.remainingOutputs]; + snprintf(vars.tmp.decimals, sizeof(vars.tmp.decimals), "%d", ETP_DECIMALS); } } else { return 0; @@ -2329,10 +2323,10 @@ uint8_t prepare_single_output() { return 0; } - vars.tmp.fullAmount[btchip_context_D.nExpiryHeight[2]] = ' '; - btchip_context_D.tmp = (unsigned char *)(vars.tmp.fullAmount + btchip_context_D.nExpiryHeight[2] + 1); - textSize = btchip_convert_hex_amount_to_displayable(amount, btchip_context_D.nExpiryHeight[0]); - vars.tmp.fullAmount[textSize + btchip_context_D.nExpiryHeight[2] + 1] = '\0'; + vars.tmp.fullAmount[ETP_LENGTH] = ' '; + btchip_context_D.tmp = (unsigned char *)(vars.tmp.fullAmount + ETP_LENGTH + 1); + textSize = btchip_convert_hex_amount_to_displayable(amount, ETP_DECIMALS); + vars.tmp.fullAmount[textSize + ETP_LENGTH + 1] = '\0'; vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 1] = '\0'; } From fbed533a8aac5909f5684e2384f1e0bb9f7ded16 Mon Sep 17 00:00:00 2001 From: smdmitry Date: Fri, 27 Dec 2019 11:09:46 +0300 Subject: [PATCH 05/10] coinFamily => kind --- src/btchip_apdu_hash_input_finalize_full.c | 6 +++--- src/btchip_helpers.c | 2 +- src/btchip_transaction.c | 2 +- src/main.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/btchip_apdu_hash_input_finalize_full.c b/src/btchip_apdu_hash_input_finalize_full.c index 7d60786a..2a4cf1b3 100644 --- a/src/btchip_apdu_hash_input_finalize_full.c +++ b/src/btchip_apdu_hash_input_finalize_full.c @@ -110,7 +110,7 @@ static bool check_output_displayable() { } if (changeFound) { // Allow 2 change outputs for metaverse (ETP + token) - if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + if (G_coin_config->kind == COIN_KIND_METAVERSE) { if (btchip_context_D.changeOutputFound >= 2) { PRINTF("Error : Multiple change output found"); THROW(EXCEPTION); @@ -184,7 +184,7 @@ static bool handle_output_state() { scriptSize = btchip_context_D.currentOutput[8]; discardSize = 1; - if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + if (G_coin_config->kind == COIN_KIND_METAVERSE) { ETP_COUNTER = scriptSize + 9; ETP_COUNTER += 4; // Version @@ -298,7 +298,7 @@ unsigned short btchip_apdu_hash_input_finalize_full_internal( } if (p1 == FINALIZE_P1_CHANGEINFO) { - if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE && G_io_apdu_buffer[ISO_OFFSET_P2] == 0x0E) { + if (G_coin_config->kind == COIN_KIND_METAVERSE && G_io_apdu_buffer[ISO_OFFSET_P2] == 0x0E) { if (apduLength > 4) { // For Metaverse can handle max 4 outputs with tokens goto discardTransaction; } diff --git a/src/btchip_helpers.c b/src/btchip_helpers.c index 4cec568c..259d7adb 100644 --- a/src/btchip_helpers.c +++ b/src/btchip_helpers.c @@ -355,7 +355,7 @@ unsigned char bip44_derivation_guard(unsigned char *bip32Path, bool is_change_pa } // Allow change path to be 0 or 1 (no security threats here) - if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + if (G_coin_config->kind == COIN_KIND_METAVERSE) { // If the account or address index is very high or if the change isn't 0 or 1, return a warning if((bip32PathInt[BIP44_ACCOUNT_OFFSET]^0x80000000) > MAX_BIP44_ACCOUNT_RECOMMENDED || (bip32PathInt[BIP44_CHANGE_OFFSET] != 0 && bip32PathInt[BIP44_CHANGE_OFFSET] != 1) || diff --git a/src/btchip_transaction.c b/src/btchip_transaction.c index ce188bb6..32ab3b7b 100644 --- a/src/btchip_transaction.c +++ b/src/btchip_transaction.c @@ -728,7 +728,7 @@ void transaction_parse(unsigned char parseMode) { btchip_context_D.transactionContext.scriptRemaining = transaction_get_varint(); - if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + if (G_coin_config->kind == COIN_KIND_METAVERSE) { ETP_COUNTER = btchip_context_D.transactionContext.scriptRemaining; ETP_COUNTER += 4; // Version diff --git a/src/main.c b/src/main.c index 0c7cc858..24f601c7 100644 --- a/src/main.c +++ b/src/main.c @@ -2066,7 +2066,7 @@ uint8_t prepare_fees() { unsigned short textSize; unsigned char borrow; - if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + if (G_coin_config->kind == COIN_KIND_METAVERSE) { if ( btchip_context_D.totalTokenInputAmount[0] != 0 || btchip_context_D.totalTokenInputAmount[1] != 0 || @@ -2229,7 +2229,7 @@ uint8_t prepare_single_output() { '\0'; } - if (btchip_context_D.coinFamily == BTCHIP_FAMILY_METAVERSE) { + if (G_coin_config->kind == COIN_KIND_METAVERSE) { vars.tmp.decimals[0] = '\0'; unsigned char *parsePointer = btchip_context_D.currentOutput + offset + 26; From d6b6ad7b5bd1aed0924fd60567857a5e1d3f45ab Mon Sep 17 00:00:00 2001 From: smdmitry Date: Tue, 7 Jan 2020 01:02:34 +0300 Subject: [PATCH 06/10] prepare all tx types for inputs --- Makefile | 1 + include/btchip_context.h | 7 + src/btchip_apdu_hash_input_finalize_full.c | 237 ++++++++- src/btchip_helpers.c | 2 + src/btchip_transaction.c | 203 +++++++- src/main.c | 559 ++++++++++++++++++--- 6 files changed, 911 insertions(+), 98 deletions(-) diff --git a/Makefile b/Makefile index e372d27a..3c9f78b2 100644 --- a/Makefile +++ b/Makefile @@ -172,6 +172,7 @@ else ifeq ($(COIN),metaverse) # Metaverse DEFINES += COIN_P2PKH_VERSION=50 COIN_P2SH_VERSION=5 COIN_FAMILY=5 COIN_COINID=\"Metaverse\" COIN_COINID_HEADER=\"METAVERSE\" COIN_COLOR_HDR=0xD0DAFB COIN_COLOR_DB=0xE8EDFD COIN_COINID_NAME=\"Metaverse\" COIN_COINID_SHORT=\"ETP\" COIN_KIND=COIN_KIND_METAVERSE DEFINES_LIB=# while debugging +DEFINES += APP_METAVERSE APPNAME ="Metaverse" APP_LOAD_PARAMS += --path $(APP_PATH) else diff --git a/include/btchip_context.h b/include/btchip_context.h index 834b00e2..44dbc6f5 100644 --- a/include/btchip_context.h +++ b/include/btchip_context.h @@ -252,7 +252,9 @@ struct btchip_context_s { unsigned char nLockTime[4]; unsigned char sigHashType[4]; + #ifdef APP_METAVERSE unsigned char decimals[4]; // For Metaverse tokens, need to provide precision for all outputs from external source (maximum can handle 4 outputs with tokens) + #endif }; typedef struct btchip_context_s btchip_context_t; @@ -322,6 +324,7 @@ void btchip_context_init(void); #define DECIMALS (!(G_coin_config->flags & FLAG_PEERCOIN_UNITS) ? 8 : 6) +#ifdef APP_METAVERSE // Metaverse reuse context variables to save memory #define ETP_COUNTER btchip_context_D.trustedInputIndex // unsigned long int #define ETP_BUFF btchip_context_D.nVersionGroupId // unsigned char[4] @@ -329,5 +332,9 @@ void btchip_context_init(void); #define ETP_DECIMALS btchip_context_D.nExpiryHeight[0] // unsigned char #define ETP_LENGTH btchip_context_D.nExpiryHeight[1] // unsigned char #define ETP_TMP btchip_context_D.nExpiryHeight[2] // unsigned char +#define ETP_OUT_TYPE btchip_context_D.nExpiryHeight[3] // unsigned char +#define ETP_VERSION btchip_context_D.overwinterSignReady // unsigned char +#define ETP_POINTER (parsePointer + ETP_COUNTER) +#endif #endif diff --git a/src/btchip_apdu_hash_input_finalize_full.c b/src/btchip_apdu_hash_input_finalize_full.c index 2a4cf1b3..f88cec2b 100644 --- a/src/btchip_apdu_hash_input_finalize_full.c +++ b/src/btchip_apdu_hash_input_finalize_full.c @@ -108,7 +108,17 @@ static bool check_output_displayable() { } } } + + #ifdef APP_METAVERSE + if (G_coin_config->kind == COIN_KIND_METAVERSE) { + if (ETP_OUT_TYPE == 3 || ETP_OUT_TYPE == 21 || ETP_OUT_TYPE == 41 || ETP_OUT_TYPE == 42 || ETP_OUT_TYPE == 61 || ETP_OUT_TYPE == 62) { + changeFound = false; + } + } + #endif + if (changeFound) { + #ifdef APP_METAVERSE // Allow 2 change outputs for metaverse (ETP + token) if (G_coin_config->kind == COIN_KIND_METAVERSE) { if (btchip_context_D.changeOutputFound >= 2) { @@ -117,14 +127,17 @@ static bool check_output_displayable() { } btchip_context_D.changeOutputFound++; displayable = false; - } else { - if (btchip_context_D.changeOutputFound) { - PRINTF("Error : Multiple change output found"); - THROW(EXCEPTION); - } - btchip_context_D.changeOutputFound = true; - displayable = false; + + return displayable; } + #endif + + if (btchip_context_D.changeOutputFound) { + PRINTF("Error : Multiple change output found"); + THROW(EXCEPTION); + } + btchip_context_D.changeOutputFound = true; + displayable = false; } } @@ -184,28 +197,196 @@ static bool handle_output_state() { scriptSize = btchip_context_D.currentOutput[8]; discardSize = 1; - if (G_coin_config->kind == COIN_KIND_METAVERSE) { + #ifdef APP_METAVERSE + if (G_coin_config->kind == COIN_KIND_METAVERSE) { // Parsing output tx + ETP_OUT_TYPE = 255; + ETP_VERSION = 0; + + unsigned char *parsePointer = btchip_context_D.currentOutput; ETP_COUNTER = scriptSize + 9; - ETP_COUNTER += 4; // Version - os_memmove(ETP_BUFF, btchip_context_D.currentOutput + ETP_COUNTER, 4); - ETP_COUNTER += 4; // Type + os_memmove(ETP_BUFF, ETP_POINTER, 4); // Version + ETP_COUNTER += 4; + + if ( + ETP_BUFF[0] == 1 && + ETP_BUFF[1] == 0 && + ETP_BUFF[2] == 0 && + ETP_BUFF[3] == 0 + ) { + ETP_VERSION = 1; + } else if ( + ETP_BUFF[0] == 207 && + ETP_BUFF[1] == 0 && + ETP_BUFF[2] == 0 && + ETP_BUFF[3] == 0 + ) { + ETP_VERSION = 207; + } + + if (ETP_VERSION != 1 && ETP_VERSION != 207) { + PRINTF("PARSE ERROR ETP_VERSION %d\n", ETP_VERSION); + THROW(EXCEPTION); + } + + os_memmove(ETP_BUFF, ETP_POINTER, 4); // Type + ETP_COUNTER += 4; + + if (ETP_VERSION == 207) { + // to_did + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // from_did + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + } + + if ( + ETP_BUFF[1] != 0 || + ETP_BUFF[2] != 0 || + ETP_BUFF[3] != 0 + ) { + PRINTF("PARSE ERROR Unknown ETP Type\n"); + THROW(EXCEPTION); + } + + if (ETP_BUFF[0] == 0) { // ATTACHMENT.TYPE.ETP_TRANSFER + ETP_OUT_TYPE = 0; + } else if (ETP_BUFF[0] == 2) { // ATTACHMENT.TYPE.MST + os_memmove(ETP_BUFF, ETP_POINTER, 4); // Status + ETP_COUNTER += 4; + + if ( + ETP_BUFF[1] != 0 || + ETP_BUFF[2] != 0 || + ETP_BUFF[3] != 0 + ) { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + THROW(EXCEPTION); + } + + if (ETP_BUFF[0] == 1) { // MST.STATUS.REGISTER + ETP_COUNTER += *ETP_POINTER + 1 + 16 + 1 + 1 + 2; + // Length varint + Ticker length + maximum supply + precision + secondary issue threshold + '0000' - if (ETP_BUFF[0] == 2) { - os_memmove(ETP_BUFF, btchip_context_D.currentOutput + ETP_COUNTER, 4); - ETP_COUNTER += 4; // Status + ETP_COUNTER += *ETP_POINTER + 1; // issuer + ETP_COUNTER += *ETP_POINTER + 1; // recipient address + ETP_COUNTER += *ETP_POINTER + 1; // description - if (ETP_BUFF[0] == 2) { - ETP_COUNTER += *(btchip_context_D.currentOutput + ETP_COUNTER) + 1 + 8; + ETP_OUT_TYPE = 21; + } else if (ETP_BUFF[0] == 2) { // MST.STATUS.TRANSFER + ETP_COUNTER += *ETP_POINTER + 1 + 8; // Length varint + Ticker length + Amount length - btchip_swap_bytes(ETP_AMOUNT, btchip_context_D.currentOutput + ETP_COUNTER - 8, 8); + btchip_swap_bytes(ETP_AMOUNT, ETP_POINTER - 8, 8); transaction_amount_sub_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, ETP_AMOUNT); + + ETP_OUT_TYPE = 22; + } else { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + THROW(EXCEPTION); + } + } else if (ETP_BUFF[0] == 3) { // ATTACHMENT.TYPE.MESSAGE + // Message + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + ETP_OUT_TYPE = 3; + } else if (ETP_BUFF[0] == 4) { // ATTACHMENT.TYPE.AVATAR + os_memmove(ETP_BUFF, ETP_POINTER, 4); // Status + ETP_COUNTER += 4; + + if ( + ETP_BUFF[1] != 0 || + ETP_BUFF[2] != 0 || + ETP_BUFF[3] != 0 + ) { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + THROW(EXCEPTION); + } + + // Status = 1 | 2 (AVATAR.STATUS.REGISTER | AVATAR.STATUS.TRANSFER) + if (ETP_BUFF[0] == 1 || ETP_BUFF[0] == 2) { + // Symbol text length + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // Symbol address length + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + ETP_OUT_TYPE = 41; + } else { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + THROW(EXCEPTION); + + //ETP_OUT_TYPE = 42; + } + } else if (ETP_BUFF[0] == 5) { // ATTACHMENT.TYPE.CERT + // Symbol + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // Owner + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // Address + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + os_memmove(ETP_BUFF, ETP_POINTER, 4); + ETP_COUNTER += 4; // Cert + + ETP_COUNTER += 1; // Status + + if (true) { // Check currentOutput has more data + // content + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; } - } + ETP_OUT_TYPE = 5; + } else if (ETP_BUFF[0] == 6) { // ATTACHMENT.TYPE.MIT + ETP_BUFF[0] = *ETP_POINTER; + ETP_COUNTER += 1; // Status + + if (ETP_BUFF[0] == 1) { // Constants.MIT.STATUS.REGISTER + // Symbol + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // Address + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // content + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + ETP_OUT_TYPE = 61; + } else if (ETP_BUFF[0] == 2) { // Constants.MIT.STATUS.TRANSFER + // Symbol + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // address + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + os_memset(ETP_AMOUNT, 0, sizeof(ETP_AMOUNT)); + ETP_AMOUNT[0] = 1; + transaction_amount_sub_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, ETP_AMOUNT); + + ETP_OUT_TYPE = 62; + } else { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + THROW(EXCEPTION); + } + } scriptSize = ETP_COUNTER - 9; } + #endif } else if (btchip_context_D.currentOutput[8] == 0xFD) { if (btchip_context_D.currentOutputOffset < 9 + 2) { break; @@ -287,6 +468,12 @@ unsigned short btchip_apdu_hash_input_finalize_full_internal( } } + #ifdef APP_METAVERSE + if (G_coin_config->kind == COIN_KIND_METAVERSE) { + btchip_context_D.tmpCtx.output.multipleOutput = 1; + } + #endif + // Check state BEGIN_TRY { TRY { @@ -298,13 +485,17 @@ unsigned short btchip_apdu_hash_input_finalize_full_internal( } if (p1 == FINALIZE_P1_CHANGEINFO) { - if (G_coin_config->kind == COIN_KIND_METAVERSE && G_io_apdu_buffer[ISO_OFFSET_P2] == 0x0E) { - if (apduLength > 4) { // For Metaverse can handle max 4 outputs with tokens - goto discardTransaction; + #ifdef APP_METAVERSE + if (G_coin_config->kind == COIN_KIND_METAVERSE) { + if (G_io_apdu_buffer[ISO_OFFSET_P2] == 0x0E) { + if (apduLength > 4) { // For Metaverse can handle max 4 outputs with tokens + goto discardTransaction; + } + os_memmove(btchip_context_D.decimals, G_io_apdu_buffer + ISO_OFFSET_CDATA, apduLength); + goto return_OK; } - os_memmove(btchip_context_D.decimals, G_io_apdu_buffer + ISO_OFFSET_CDATA, apduLength); - goto return_OK; } + #endif unsigned char keyLength; if (!btchip_context_D.transactionContext.firstSigned) { diff --git a/src/btchip_helpers.c b/src/btchip_helpers.c index 259d7adb..71dd15e2 100644 --- a/src/btchip_helpers.c +++ b/src/btchip_helpers.c @@ -354,6 +354,7 @@ unsigned char bip44_derivation_guard(unsigned char *bip32Path, bool is_change_pa return 1; } + #ifdef APP_METAVERSE // Allow change path to be 0 or 1 (no security threats here) if (G_coin_config->kind == COIN_KIND_METAVERSE) { // If the account or address index is very high or if the change isn't 0 or 1, return a warning @@ -365,6 +366,7 @@ unsigned char bip44_derivation_guard(unsigned char *bip32Path, bool is_change_pa return 0; } + #endif // If the account or address index is very high or if the change isn't 1, return a warning if((bip32PathInt[BIP44_ACCOUNT_OFFSET]^0x80000000) > MAX_BIP44_ACCOUNT_RECOMMENDED || diff --git a/src/btchip_transaction.c b/src/btchip_transaction.c index 32ab3b7b..ef8d6653 100644 --- a/src/btchip_transaction.c +++ b/src/btchip_transaction.c @@ -728,37 +728,224 @@ void transaction_parse(unsigned char parseMode) { btchip_context_D.transactionContext.scriptRemaining = transaction_get_varint(); - if (G_coin_config->kind == COIN_KIND_METAVERSE) { + #ifdef APP_METAVERSE + if (G_coin_config->kind == COIN_KIND_METAVERSE) { // Parsing input tx + ETP_VERSION = 0; ETP_COUNTER = btchip_context_D.transactionContext.scriptRemaining; + unsigned char *parsePointer = btchip_context_D.transactionBufferPointer; - ETP_COUNTER += 4; // Version - os_memmove(ETP_BUFF, btchip_context_D.transactionBufferPointer + ETP_COUNTER, 4); + os_memmove(ETP_BUFF, ETP_POINTER, 4); // Version + ETP_COUNTER += 4; + + if ( + ETP_BUFF[0] == 1 && + ETP_BUFF[1] == 0 && + ETP_BUFF[2] == 0 && + ETP_BUFF[3] == 0 + ) { + ETP_VERSION = 1; + } else if ( + ETP_BUFF[0] == 207 && + ETP_BUFF[1] == 0 && + ETP_BUFF[2] == 0 && + ETP_BUFF[3] == 0 + ) { + ETP_VERSION = 207; + } + + if (ETP_VERSION != 1 && ETP_VERSION != 207) { + PRINTF("PARSE ERROR ETP_VERSION %d\n", ETP_VERSION); + goto fail; + } + + os_memmove(ETP_BUFF, ETP_POINTER, 4); ETP_COUNTER += 4; // Type - if (ETP_BUFF[0] == 2) { - os_memmove(ETP_BUFF, btchip_context_D.transactionBufferPointer + ETP_COUNTER, 4); + if (ETP_VERSION == 207) { + // to_did + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // from_did + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + } + + if ( + ETP_BUFF[1] != 0 || + ETP_BUFF[2] != 0 || + ETP_BUFF[3] != 0 + ) { + PRINTF("PARSE ERROR Unknown ETP Type\n"); + goto fail; + } + + if (ETP_BUFF[0] == 0) { // ATTACHMENT.TYPE.ETP_TRANSFER + + } else if (ETP_BUFF[0] == 2) { // ATTACHMENT.TYPE.MST + os_memmove(ETP_BUFF, ETP_POINTER, 4); ETP_COUNTER += 4; // Status - if (ETP_BUFF[0] == 2) { - ETP_COUNTER += *(btchip_context_D.transactionBufferPointer + ETP_COUNTER) + 1 + 8; + if ( + ETP_BUFF[1] != 0 || + ETP_BUFF[2] != 0 || + ETP_BUFF[3] != 0 + ) { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + goto fail; + } + + if (ETP_BUFF[0] == 1) { // MST.STATUS.REGISTER + ETP_COUNTER += *ETP_POINTER + 1 + 8; // Length varint + Ticker length + Amount length if ( parseMode == PARSE_MODE_TRUSTED_INPUT && btchip_context_D.transactionContext.transactionCurrentInputOutput == btchip_context_D.transactionTargetInput ) { - btchip_swap_bytes(ETP_AMOUNT, btchip_context_D.transactionBufferPointer + ETP_COUNTER - 8, 8); + btchip_swap_bytes(ETP_AMOUNT, ETP_POINTER - 8, 8); transaction_amount_add_be( btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, ETP_AMOUNT ); } + + ETP_COUNTER += 1 + 1 + 2; + // precision + secondary issue threshold + '0000' + + ETP_COUNTER += *ETP_POINTER + 1; // issuer + ETP_COUNTER += *ETP_POINTER + 1; // recipient address + ETP_COUNTER += *ETP_POINTER + 1; // description + } else if (ETP_BUFF[0] == 2) { // MST.STATUS.TRANSFER + ETP_COUNTER += *ETP_POINTER + 1 + 8; + // Length varint + Ticker length + Amount length + + if ( + parseMode == PARSE_MODE_TRUSTED_INPUT && + btchip_context_D.transactionContext.transactionCurrentInputOutput == btchip_context_D.transactionTargetInput + ) { + btchip_swap_bytes(ETP_AMOUNT, ETP_POINTER - 8, 8); + transaction_amount_add_be( + btchip_context_D.totalTokenInputAmount, + btchip_context_D.totalTokenInputAmount, + ETP_AMOUNT + ); + } + } else { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + goto fail; + } + } else if (ETP_BUFF[0] == 3) { // ATTACHMENT.TYPE.MESSAGE + // Message + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + } else if (ETP_BUFF[0] == 4) { // ATTACHMENT.TYPE.AVATAR + os_memmove(ETP_BUFF, ETP_POINTER, 4); + ETP_COUNTER += 4; // Status + + if ( + ETP_BUFF[1] != 0 || + ETP_BUFF[2] != 0 || + ETP_BUFF[3] != 0 + ) { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + goto fail; + } + + // Status = 1 | 2 (AVATAR.STATUS.REGISTER | AVATAR.STATUS.TRANSFER) + if (ETP_BUFF[0] == 1 || ETP_BUFF[0] == 2) { + // Symbol text length + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // Symbol address length + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + if ( + parseMode == PARSE_MODE_TRUSTED_INPUT && + btchip_context_D.transactionContext.transactionCurrentInputOutput == btchip_context_D.transactionTargetInput + ) { + PRINTF("PARSE ERROR Can not use AVATAR.STATUS.REGISTER | AVATAR.STATUS.TRANSFER as input\n"); + goto fail; + } + } else { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + goto fail; + } + } else if (ETP_BUFF[0] == 5) { // ATTACHMENT.TYPE.CERT + // Symbol + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // Owner + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // Address + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + os_memmove(ETP_BUFF, ETP_POINTER, 4); + ETP_COUNTER += 4; // Cert + + ETP_COUNTER += 1; // Status + + if (true) { // Check currentOutput has more data + // content + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + } + + if ( + parseMode == PARSE_MODE_TRUSTED_INPUT && + btchip_context_D.transactionContext.transactionCurrentInputOutput == btchip_context_D.transactionTargetInput + ) { + PRINTF("PARSE ERROR Can not use ATTACHMENT.TYPE.CERT as input\n"); + goto fail; + } + } else if (ETP_BUFF[0] == 6) { // ATTACHMENT.TYPE.MIT + ETP_BUFF[0] = *ETP_POINTER; + ETP_COUNTER += 1; // Status + + if (ETP_BUFF[0] == 1 || ETP_BUFF[0] == 2) { // MIT.STATUS.REGISTER | MIT.STATUS.TRANSFER + // Symbol + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + // Address + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + if (ETP_BUFF[0] == 1) { // MIT.STATUS.REGISTER + // Content + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + } + + if ( + parseMode == PARSE_MODE_TRUSTED_INPUT && + btchip_context_D.transactionContext.transactionCurrentInputOutput == btchip_context_D.transactionTargetInput + ) { + os_memset(ETP_AMOUNT, 0, sizeof(ETP_AMOUNT)); + ETP_AMOUNT[0] = 1; + + transaction_amount_add_be( + btchip_context_D.totalTokenInputAmount, + btchip_context_D.totalTokenInputAmount, + ETP_AMOUNT + ); + } + } else { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + goto fail; } } btchip_context_D.transactionContext.scriptRemaining = ETP_COUNTER; } + #endif PRINTF("Script to read " DEBUG_LONG "\n",btchip_context_D.transactionContext.scriptRemaining); // Move on diff --git a/src/main.c b/src/main.c index 24f601c7..c0894011 100644 --- a/src/main.c +++ b/src/main.c @@ -158,7 +158,13 @@ union { char fullAddress[65]; // the address char fullAmount[20]; // full amount (Metaverse may have long token names, so maybe increase from 20 to 40?) char feesAmount[20]; // fees - char decimals[3]; + + #ifdef APP_METAVERSE + char metaverse_decimals[3]; + char metaverse_message[1]; + //char metaverse_message[255]; + char metaverse_did[20]; + #endif } tmp; struct { @@ -984,6 +990,10 @@ const bagl_element_t ui_verify_output_nanos[] = { UI_NANOS_SCROLLING_TEXT(3, 23, 26, 82, vars.tmp.fullAddress, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px) }; +unsigned int ui_verify_output_nanos_button(unsigned int button_mask, + unsigned int button_mask_counter); + +#ifdef APP_METAVERSE const bagl_element_t ui_verify_output_decimals_nanos[] = { UI_NANOS_BACKGROUND(), @@ -996,17 +1006,17 @@ const bagl_element_t ui_verify_output_decimals_nanos[] = { UI_NANOS_SCROLLING_TEXT(2, 23, 26, 82, vars.tmp.fullAmount, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px), UI_NANOS_TEXT(3, 0, 12, 128, "Decimals", BAGL_FONT_OPEN_SANS_REGULAR_11px), - UI_NANOS_TEXT(3, 0, 26, 128, vars.tmp.decimals, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px), + UI_NANOS_TEXT(3, 0, 26, 128, vars.tmp.metaverse_decimals, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px), UI_NANOS_TEXT(4, 0, 12, 128, "Address", BAGL_FONT_OPEN_SANS_REGULAR_11px), UI_NANOS_SCROLLING_TEXT(4, 23, 26, 82, vars.tmp.fullAddress, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px) }; -unsigned int ui_verify_output_nanos_button(unsigned int button_mask, - unsigned int button_mask_counter); - unsigned int ui_verify_output_decimals_nanos_button(unsigned int button_mask, unsigned int button_mask_counter); +#endif + + const bagl_element_t ui_finalize_nanos[] = { UI_NANOS_BACKGROUND(), @@ -1251,6 +1261,7 @@ unsigned int ui_verify_output_nanos_button(unsigned int button_mask, return 0; } +#ifdef APP_METAVERSE unsigned int ui_verify_output_decimals_nanos_button(unsigned int button_mask, unsigned int button_mask_counter) { switch (button_mask) { @@ -1264,6 +1275,7 @@ unsigned int ui_verify_output_decimals_nanos_button(unsigned int button_mask, } return 0; } +#endif unsigned int ui_finalize_nanos_button(unsigned int button_mask, unsigned int button_mask_counter) { @@ -1703,13 +1715,6 @@ UX_STEP_NOCB( .title = "Address", .text = vars.tmp.fullAddress, }); -UX_STEP_NOCB( - ux_confirm_single_flow_4_step, - bnnn_paging, - { - .title = "Decimals", - .text = vars.tmp.decimals, - }); UX_STEP_VALID( ux_confirm_single_flow_5_step, pb, @@ -1735,8 +1740,18 @@ UX_FLOW(ux_confirm_single_flow, &ux_confirm_single_flow_6_step ); +#ifdef APP_METAVERSE +// Metaverse MST // confirm_single: confirm output #x(feesAmount) / Amount: fullAmount / Decimals: decimals / Address: fullAddress -UX_FLOW(ux_confirm_single_decimals_flow, +UX_STEP_NOCB( + ux_confirm_single_flow_4_step, + bnnn_paging, + { + .title = "Decimals", + .text = vars.tmp.metaverse_decimals, + }); + +UX_FLOW(ux_confirm_metaverse_decimals_flow, &ux_confirm_single_flow_1_step, &ux_confirm_single_flow_2_step, &ux_confirm_single_flow_3_step, @@ -1745,6 +1760,105 @@ UX_FLOW(ux_confirm_single_decimals_flow, &ux_confirm_single_flow_6_step ); +UX_STEP_NOCB( + ux_confirm_metaverse_mit_transfer_flow_2_step, + bnnn_paging, + { + .title = "To avatar", + .text = vars.tmp.metaverse_did, + }); +UX_FLOW(ux_confirm_metaverse_mst_create_flow, + &ux_confirm_single_flow_1_step, + &ux_confirm_metaverse_mit_transfer_flow_2_step, + &ux_confirm_single_flow_3_step, + &ux_confirm_single_flow_5_step, + &ux_confirm_single_flow_6_step +); + +// Avatar +UX_STEP_NOCB( + ux_confirm_metaverse_avatar_create_flow_2_step, + bnnn_paging, + { + .title = "New Avatar", + .text = vars.tmp.fullAmount, + }); +UX_FLOW(ux_confirm_metaverse_avatar_create_flow, + &ux_confirm_single_flow_1_step, + &ux_confirm_metaverse_avatar_create_flow_2_step, + &ux_confirm_single_flow_3_step, + &ux_confirm_single_flow_5_step, + &ux_confirm_single_flow_6_step +); + +// MIT +UX_FLOW(ux_confirm_metaverse_mit_transfer_flow, + &ux_confirm_single_flow_1_step, + &ux_confirm_single_flow_2_step, + &ux_confirm_metaverse_mit_transfer_flow_2_step, + &ux_confirm_single_flow_3_step, + &ux_confirm_single_flow_5_step, + &ux_confirm_single_flow_6_step +); +UX_STEP_NOCB( + ux_confirm_metaverse_mit_create_flow_2_step, + bnnn_paging, + { + .title = "Avatar", + .text = vars.tmp.metaverse_did, + }); +UX_STEP_NOCB( + ux_confirm_metaverse_mit_create_flow_4_step, + bnnn_paging, + { + .title = "Message", + .text = vars.tmp.metaverse_message, + }); +UX_FLOW(ux_confirm_metaverse_mit_create_flow, + &ux_confirm_single_flow_1_step, + &ux_confirm_single_flow_2_step, + &ux_confirm_metaverse_mit_create_flow_2_step, + &ux_confirm_single_flow_3_step, + &ux_confirm_metaverse_mit_create_flow_4_step, + &ux_confirm_single_flow_5_step, + &ux_confirm_single_flow_6_step +); + +// Message +UX_STEP_NOCB( + ux_confirm_metaverse_message_flow_2_step, + bnnn_paging, + { + .title = "Message", + .text = vars.tmp.metaverse_message, + }); +UX_FLOW(ux_confirm_metaverse_message_flow, + &ux_confirm_single_flow_1_step, + &ux_confirm_metaverse_message_flow_2_step, + &ux_confirm_single_flow_3_step, + &ux_confirm_single_flow_5_step, + &ux_confirm_single_flow_6_step +); + +// Cert +UX_STEP_NOCB( + ux_confirm_metaverse_cert_flow_2_step, + bnnn_paging, + { + .title = "Certificate", + .text = vars.tmp.metaverse_message, + }); +UX_FLOW(ux_confirm_metaverse_cert_flow, + &ux_confirm_single_flow_1_step, + &ux_confirm_metaverse_cert_flow_2_step, + &ux_confirm_metaverse_mit_create_flow_2_step, + &ux_confirm_single_flow_3_step, + &ux_confirm_single_flow_5_step, + &ux_confirm_single_flow_6_step +); + +#endif + ////////////////////////////////////////////////////////////////////// UX_STEP_NOCB( @@ -2066,6 +2180,7 @@ uint8_t prepare_fees() { unsigned short textSize; unsigned char borrow; + #ifdef APP_METAVERSE if (G_coin_config->kind == COIN_KIND_METAVERSE) { if ( btchip_context_D.totalTokenInputAmount[0] != 0 || @@ -2081,6 +2196,7 @@ uint8_t prepare_fees() { goto error; } } + #endif borrow = transaction_amount_sub_be( fees, btchip_context_D.transactionContext.transactionAmount, @@ -2126,7 +2242,11 @@ uint8_t prepare_single_output() { unsigned short textSize; unsigned char nativeSegwit; - vars.tmp.decimals[0] = '\0'; + #ifdef APP_METAVERSE + if (G_coin_config->kind == COIN_KIND_METAVERSE) { + vars.tmp.metaverse_decimals[0] = '\0'; + } + #endif vars.tmp.fullAddress[0] = '\0'; btchip_swap_bytes(amount, btchip_context_D.currentOutput + offset, 8); offset += 8; @@ -2229,42 +2349,84 @@ uint8_t prepare_single_output() { '\0'; } - if (G_coin_config->kind == COIN_KIND_METAVERSE) { - vars.tmp.decimals[0] = '\0'; + #ifdef APP_METAVERSE - unsigned char *parsePointer = btchip_context_D.currentOutput + offset + 26; - ETP_DECIMALS = DECIMALS; + // 0 - ETP, 21 - MST REG, 22 - MST TX, 3 - MESSAGE, 41 - AVA REG, 42 - AVA TX, 5 - CERT, 61 - MIT REG, 62 - MIT TX + if (G_coin_config->kind == COIN_KIND_METAVERSE) { // Parsing displayable outputs + ETP_OUT_TYPE = 255; + ETP_VERSION = 0; ETP_TMP = 0; + ETP_DECIMALS = DECIMALS; + vars.tmp.metaverse_decimals[0] = '\0'; + + unsigned char *parsePointer = btchip_context_D.currentOutput; + ETP_COUNTER = offset + 26; + ETP_LENGTH = btchip_context_D.shortCoinIdLength; - os_memmove(ETP_BUFF, parsePointer, 4); - parsePointer += 4; + os_memmove(ETP_BUFF, ETP_POINTER, 4); + ETP_COUNTER += 4; // Version = 1 | 207 (ATTACHMENT.VERSION.DEFAULT | ATTACHMENT.VERSION.DID) if ( - ETP_BUFF[0] != 1 || + ETP_BUFF[0] == 1 && + ETP_BUFF[1] == 0 && + ETP_BUFF[2] == 0 && + ETP_BUFF[3] == 0 + ) { + ETP_VERSION = 1; + } else if ( + ETP_BUFF[0] == 207 && + ETP_BUFF[1] == 0 && + ETP_BUFF[2] == 0 && + ETP_BUFF[3] == 0 + ) { + ETP_VERSION = 207; + } + + PRINTF("ETP_VERSION %d\n", ETP_VERSION); + + if (ETP_VERSION != 1 && ETP_VERSION != 207) { + PRINTF("PARSE ERROR ETP_VERSION %d\n", ETP_VERSION); + return 0; + } + + os_memmove(ETP_BUFF, ETP_POINTER, 4); + ETP_COUNTER += 4; + + if (ETP_VERSION == 207) { + // to_did length + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + + os_memmove(vars.tmp.metaverse_did, ETP_POINTER, ETP_TMP); + vars.tmp.metaverse_did[ETP_TMP] = '\0'; + ETP_COUNTER += ETP_TMP; + + // from_did length + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1 + ETP_TMP; + + PRINTF("vars.tmp.metaverse_did = %.*H\n", sizeof(vars.tmp.metaverse_did), vars.tmp.metaverse_did); + } + + PRINTF("ETP_BUFF Type = %.*H\n", sizeof(ETP_BUFF), ETP_BUFF); + + if ( ETP_BUFF[1] != 0 || ETP_BUFF[2] != 0 || ETP_BUFF[3] != 0 ) { + PRINTF("PARSE ERROR Unknown ETP Type\n"); return 0; } - os_memmove(ETP_BUFF, parsePointer, 4); - parsePointer += 4; + if (ETP_BUFF[0] == 0) { // ATTACHMENT.TYPE.ETP_TRANSFER + PRINTF("ATTACHMENT.TYPE.ETP_TRANSFER\n"); + ETP_OUT_TYPE = 0; + } else if (ETP_BUFF[0] == 2) { // ATTACHMENT.TYPE.MST + PRINTF("ATTACHMENT.TYPE.MST\n"); - // Type = 0 | 2 (ATTACHMENT.TYPE.ETP_TRANSFER | ATTACHMENT.TYPE.MST) - if ( - ETP_BUFF[0] == 0 && - ETP_BUFF[1] == 0 && - ETP_BUFF[2] == 0 && - ETP_BUFF[3] == 0) { - } else if ( - ETP_BUFF[0] == 2 && - ETP_BUFF[1] == 0 && - ETP_BUFF[2] == 0 && - ETP_BUFF[3] == 0 - ) { // Throw error is ETP amount is non zero if ( amount[0] != 0 || @@ -2276,32 +2438,99 @@ uint8_t prepare_single_output() { amount[6] != 0 || amount[7] != 0 ) { + PRINTF("PARSE ERROR AMOUNT != 0\n"); return 0; } - os_memmove(ETP_BUFF, parsePointer, 4); - parsePointer += 4; + os_memmove(ETP_BUFF, ETP_POINTER, 4); + ETP_COUNTER += 4; - // Status = 1 | 2 (MST.STATUS.REGISTER | MST.STATUS.TRANSFER) if ( - ETP_BUFF[0] == 2 && - ETP_BUFF[1] == 0 && - ETP_BUFF[2] == 0 && - ETP_BUFF[3] == 0 + ETP_BUFF[1] != 0 || + ETP_BUFF[2] != 0 || + ETP_BUFF[3] != 0 ) { - // Ticker text length - ETP_TMP = *parsePointer; - parsePointer += 1; + PRINTF("PARSE ERROR Unknown ETP Status\n"); + return 0; + } + + if (ETP_BUFF[0] == 1) { // MST.STATUS.REGISTER + // Symbol + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TMP); + vars.tmp.fullAmount[ETP_TMP] = '\0'; + ETP_COUNTER += ETP_TMP; + + // Maximum supply + btchip_swap_bytes(amount, ETP_POINTER, 8); + ETP_COUNTER += 8; + + // Precision + ETP_DECIMALS = *ETP_POINTER; + ETP_COUNTER += 1; + if (ETP_DECIMALS < 0 || ETP_DECIMALS > 8) { + PRINTF("PARSE ERROR Precision not in [0, 8]\n"); + return 0; + } + + // Secondary issue threshold + // writeUInt8 + + // 0000 bytes + os_memmove(ETP_BUFF, ETP_POINTER, 2); + ETP_COUNTER += 2; + if ( + ETP_BUFF[0] != 0 || + ETP_BUFF[1] != 0 + ) { + PRINTF("PARSE ERROR Non zero bytes\n"); + return 0; + } - // Prepare ticker text + // Issuer + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + if ( + strlen(vars.tmp.metaverse_did) != ETP_TMP || + os_memcmp(vars.tmp.metaverse_did, ETP_POINTER, ETP_TMP) != 0 + ) { + PRINTF("PARSE ERROR OUTPUT AVATAR != ATTACHMENT AVATAR\n"); + return 0; + } + ETP_COUNTER += ETP_TMP; + + // Recipient address + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + if ( + strlen(vars.tmp.fullAddress) != ETP_TMP || + os_memcmp(vars.tmp.fullAddress, ETP_POINTER, ETP_TMP) != 0 + ) { + PRINTF("PARSE ERROR OUTPUT ADDRESS != ATTACHMENT ADDRESS\n"); + return 0; + } + ETP_COUNTER += ETP_TMP; + + // Description + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + //os_memmove(vars.tmp.metaverse_message, ETP_POINTER, ETP_LENGTH); + //vars.tmp.metaverse_message[ETP_LENGTH] = '\0'; + + ETP_OUT_TYPE = 21; + } else if (ETP_BUFF[0] == 2) { // MST.STATUS.TRANSFER + // Symbol + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; ETP_LENGTH = ETP_TMP > 10 ? 10 : ETP_TMP; - os_memmove(vars.tmp.fullAmount, parsePointer, ETP_LENGTH); + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_LENGTH); vars.tmp.fullAmount[ETP_LENGTH] = '\0'; // Get token transfer amount - parsePointer += ETP_TMP; - btchip_swap_bytes(amount, parsePointer, 8); - parsePointer += 8; + ETP_COUNTER += ETP_TMP; + btchip_swap_bytes(amount, ETP_POINTER, 8); + ETP_COUNTER += 8; //transaction_amount_sub_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, amount); @@ -2312,23 +2541,204 @@ uint8_t prepare_single_output() { ETP_DECIMALS = 8; } else if (strcmp(vars.tmp.fullAmount, "MVS.ZDC") == 0) { ETP_DECIMALS = 6; + } else if (strcmp(vars.tmp.fullAmount, "SDG") == 0) { + ETP_DECIMALS = 8; } else { ETP_DECIMALS = btchip_context_D.decimals[btchip_context_D.totalOutputs - btchip_context_D.remainingOutputs]; - snprintf(vars.tmp.decimals, sizeof(vars.tmp.decimals), "%d", ETP_DECIMALS); + snprintf(vars.tmp.metaverse_decimals, sizeof(vars.tmp.metaverse_decimals), "%d", ETP_DECIMALS); } + + ETP_OUT_TYPE = 22; } else { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + return 0; + } + } else if (ETP_BUFF[0] == 3) { // ATTACHMENT.TYPE.MESSAGE + // Message + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + //os_memmove(vars.tmp.metaverse_message, ETP_POINTER, ETP_LENGTH); + //vars.tmp.metaverse_message[ETP_LENGTH] = '\0'; + + ETP_OUT_TYPE = 3; + } else if (ETP_BUFF[0] == 4) { // ATTACHMENT.TYPE.AVATAR + PRINTF("ATTACHMENT.TYPE.AVATAR\n"); + // Throw error is ETP amount is non zero + if ( + amount[0] != 0 || + amount[1] != 0 || + amount[2] != 0 || + amount[3] != 0 || + amount[4] != 0 || + amount[5] != 0 || + amount[6] != 0 || + amount[7] != 0 + ) { + PRINTF("PARSE ERROR AMOUNT != 0\n"); + return 0; + } + + os_memmove(ETP_BUFF, ETP_POINTER, 4); // Status + ETP_COUNTER += 4; + + if ( + ETP_BUFF[1] != 0 || + ETP_BUFF[2] != 0 || + ETP_BUFF[3] != 0 + ) { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + return 0; + } + + if (ETP_BUFF[0] == 1) { // AVATAR.STATUS.REGISTER + // Symbol text length + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TMP); + vars.tmp.fullAmount[ETP_TMP] = '\0'; + ETP_COUNTER += ETP_TMP; + + // Symbol address length + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + + if ( + strlen(vars.tmp.fullAddress) != ETP_TMP || + os_memcmp(vars.tmp.fullAddress, ETP_POINTER, ETP_TMP) != 0 + ) { + PRINTF("PARSE ERROR OUTPUT ADDRESS != ATTACHMENT ADDRESS\n"); + PRINTF("ADDRESS LENGTHS %d %d\n", strlen(vars.tmp.fullAddress), ETP_TMP); + PRINTF("OUTPUT ADDRESS %.*H\n", sizeof(vars.tmp.fullAddress), vars.tmp.fullAddress); + PRINTF("ATTACHMENT ADDRESS %.*H\n", ETP_TMP, ETP_POINTER); + return 0; + } + ETP_COUNTER += ETP_TMP; + + ETP_OUT_TYPE = 41; + } else if (ETP_BUFF[0] == 2) { // AVATAR.STATUS.TRANSFER + PRINTF("PARSE ERROR Unsupported ETP Status\n"); + return 0; + + //ETP_OUT_TYPE = 42; + } else { + PRINTF("PARSE ERROR Unknown ETP Status\n"); + return 0; + } + } else if (ETP_BUFF[0] == 5) { // ATTACHMENT.TYPE.CERT + // Symbol + ETP_TMP = *(btchip_context_D.currentOutput + ETP_COUNTER); + ETP_COUNTER += 1 + ETP_TMP; + + // Owner + ETP_TMP = *(btchip_context_D.currentOutput + ETP_COUNTER); + ETP_COUNTER += 1 + ETP_TMP; + + // Address + ETP_TMP = *(btchip_context_D.currentOutput + ETP_COUNTER); + ETP_COUNTER += 1 + ETP_TMP; + + os_memmove(ETP_BUFF, btchip_context_D.currentOutput + ETP_COUNTER, 4); + ETP_COUNTER += 4; // Cert + + ETP_COUNTER += 1; // Status + + if (true) { // Check currentOutput has more data + // content + ETP_TMP = *(btchip_context_D.currentOutput + ETP_COUNTER); + //os_memmove(ETP_BUFF, btchip_context_D.currentOutput + ETP_COUNTER, 4); + ETP_COUNTER += 1 + ETP_TMP; + } + + ETP_OUT_TYPE = 5; + } else if (ETP_BUFF[0] == 6) { // ATTACHMENT.TYPE.MIT + PRINTF("ATTACHMENT.TYPE.MIT\n"); + // Throw error is ETP amount is non zero + if ( + amount[0] != 0 || + amount[1] != 0 || + amount[2] != 0 || + amount[3] != 0 || + amount[4] != 0 || + amount[5] != 0 || + amount[6] != 0 || + amount[7] != 0 + ) { + PRINTF("PARSE ERROR AMOUNT != 0\n"); + return 0; + } + + ETP_BUFF[0] = *ETP_POINTER; + ETP_COUNTER += 1; + + if (ETP_BUFF[0] == 1) { // MIT.STATUS.REGISTER + // Symbol + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TMP); + vars.tmp.fullAmount[ETP_TMP] = '\0'; + ETP_COUNTER += ETP_TMP; + + // Address length + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + if ( + strlen(vars.tmp.fullAddress) != ETP_TMP || + os_memcmp(vars.tmp.fullAddress, ETP_POINTER, ETP_TMP) != 0 + ) { + PRINTF("PARSE ERROR OUTPUT ADDRESS != ATTACHMENT ADDRESS\n"); + return 0; + } + ETP_COUNTER += ETP_TMP; + + // Content + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + //os_memmove(vars.tmp.metaverse_message, ETP_POINTER, ETP_TMP); + //vars.tmp.metaverse_message[ETP_TMP] = '\0'; + ETP_COUNTER += ETP_TMP; + + ETP_OUT_TYPE = 61; + } else if (ETP_BUFF[0] == 2) { // MIT.STATUS.TRANSFER + // Symbol + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TMP); + vars.tmp.fullAmount[ETP_TMP] = '\0'; + ETP_COUNTER += ETP_TMP; + + // Address + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + if (os_memcmp(vars.tmp.fullAddress, ETP_POINTER, ETP_TMP) != 0) { + PRINTF("PARSE ERROR OUTPUT ADDRESS != ATTACHMENT ADDRESS\n"); + return 0; + } + //os_memmove(vars.tmp.fullAddress, ETP_POINTER, ETP_TMP); + //vars.tmp.fullAddress[ETP_TMP] = '\0'; + ETP_COUNTER += ETP_TMP; + + ETP_OUT_TYPE = 62; + } else { + PRINTF("PARSE ERROR UNKNOWN STATUS\n"); return 0; } } else { + PRINTF("PARSE ERROR UNKNOWN TYPE\n"); return 0; } - vars.tmp.fullAmount[ETP_LENGTH] = ' '; - btchip_context_D.tmp = (unsigned char *)(vars.tmp.fullAmount + ETP_LENGTH + 1); - textSize = btchip_convert_hex_amount_to_displayable(amount, ETP_DECIMALS); - vars.tmp.fullAmount[textSize + ETP_LENGTH + 1] = '\0'; - vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 1] = '\0'; + PRINTF("ETP_OUT_TYPE %d\n", ETP_OUT_TYPE); + + if (ETP_OUT_TYPE == 0 || ETP_OUT_TYPE == 22) { + vars.tmp.fullAmount[ETP_LENGTH] = ' '; + btchip_context_D.tmp = (unsigned char *)(vars.tmp.fullAmount + ETP_LENGTH + 1); + textSize = btchip_convert_hex_amount_to_displayable(amount, ETP_DECIMALS); + vars.tmp.fullAmount[textSize + ETP_LENGTH + 1] = '\0'; + vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 1] = '\0'; + } } + #endif return 1; } @@ -2648,20 +3058,35 @@ unsigned int btchip_bagl_confirm_single_output() { #if defined(TARGET_BLUE) ui_transaction_output_blue_init(); #elif defined(HAVE_UX_FLOW) - if (vars.tmp.decimals[0] != '\0') { - ux_flow_init(0, ux_confirm_single_decimals_flow, NULL); - } else { - ux_flow_init(0, ux_confirm_single_flow, NULL); + #ifdef APP_METAVERSE + if (G_coin_config->kind == COIN_KIND_METAVERSE) { + // 0 - ETP, 21 - MST REG, 22 - MST TX, 3 - MESSAGE, 41 - AVA REG, 42 - AVA TX, 5 - CERT, 61 - MIT REG, 62 - MIT TX + if (ETP_OUT_TYPE == 21) { + ux_flow_init(0, ux_confirm_metaverse_mst_create_flow, NULL); + } else if (ETP_OUT_TYPE == 3) { + ux_flow_init(0, ux_confirm_metaverse_message_flow, NULL); + } else if (ETP_OUT_TYPE == 41 || ETP_OUT_TYPE == 42) { + ux_flow_init(0, ux_confirm_metaverse_avatar_create_flow, NULL); + } else if (ETP_OUT_TYPE == 5) { + ux_flow_init(0, ux_confirm_metaverse_cert_flow, NULL); + } else if (ETP_OUT_TYPE == 61) { + ux_flow_init(0, ux_confirm_metaverse_mit_create_flow, NULL); + } else if (ETP_OUT_TYPE == 62) { + ux_flow_init(0, ux_confirm_metaverse_mit_transfer_flow, NULL); + } else if (vars.tmp.metaverse_decimals[0] != '\0') { + ux_flow_init(0, ux_confirm_metaverse_decimals_flow, NULL); + } else { // 0, 22 + ux_flow_init(0, ux_confirm_single_flow, NULL); + } + + return 1; } + #endif + ux_flow_init(0, ux_confirm_single_flow, NULL); #elif defined(TARGET_NANOS) ux_step = 0; - if (vars.tmp.decimals[0] != '\0') { - ux_step_count = 4; - UX_DISPLAY(ui_verify_output_decimals_nanos, ui_verify_output_prepro); - } else { - ux_step_count = 3; - UX_DISPLAY(ui_verify_output_nanos, ui_verify_output_prepro); - } + ux_step_count = 3; + UX_DISPLAY(ui_verify_output_nanos, ui_verify_output_prepro); #endif // TARGET_ return 1; } From 2a502152428f2fb06cf399717a2e1fa7c6ce5676 Mon Sep 17 00:00:00 2001 From: smdmitry Date: Tue, 7 Jan 2020 02:10:37 +0300 Subject: [PATCH 07/10] creation outputs --- include/btchip_context.h | 2 + src/main.c | 176 ++++++++++++++++++++++++++------------- 2 files changed, 119 insertions(+), 59 deletions(-) diff --git a/include/btchip_context.h b/include/btchip_context.h index 44dbc6f5..2dcd86de 100644 --- a/include/btchip_context.h +++ b/include/btchip_context.h @@ -334,7 +334,9 @@ void btchip_context_init(void); #define ETP_TMP btchip_context_D.nExpiryHeight[2] // unsigned char #define ETP_OUT_TYPE btchip_context_D.nExpiryHeight[3] // unsigned char #define ETP_VERSION btchip_context_D.overwinterSignReady // unsigned char +#define ETP_TLEN btchip_context_D.overwinterSignReady // unsigned char #define ETP_POINTER (parsePointer + ETP_COUNTER) +#define ETP_MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #endif diff --git a/src/main.c b/src/main.c index c0894011..1fb9611b 100644 --- a/src/main.c +++ b/src/main.c @@ -161,7 +161,6 @@ union { #ifdef APP_METAVERSE char metaverse_decimals[3]; - char metaverse_message[1]; //char metaverse_message[255]; char metaverse_did[20]; #endif @@ -1761,23 +1760,31 @@ UX_FLOW(ux_confirm_metaverse_decimals_flow, ); UX_STEP_NOCB( - ux_confirm_metaverse_mit_transfer_flow_2_step, + ux_confirm_metaverse_toavatar_step, bnnn_paging, { - .title = "To avatar", + .title = "To Avatar", .text = vars.tmp.metaverse_did, }); +UX_STEP_NOCB( + ux_confirm_metaverse_symbol_step, + bnnn_paging, + { + .title = "New MST", + .text = vars.tmp.fullAmount, + }); UX_FLOW(ux_confirm_metaverse_mst_create_flow, &ux_confirm_single_flow_1_step, - &ux_confirm_metaverse_mit_transfer_flow_2_step, + &ux_confirm_metaverse_symbol_step, &ux_confirm_single_flow_3_step, + &ux_confirm_metaverse_toavatar_step, &ux_confirm_single_flow_5_step, &ux_confirm_single_flow_6_step ); // Avatar UX_STEP_NOCB( - ux_confirm_metaverse_avatar_create_flow_2_step, + ux_confirm_metaverse_newavatar_step, bnnn_paging, { .title = "New Avatar", @@ -1785,7 +1792,7 @@ UX_STEP_NOCB( }); UX_FLOW(ux_confirm_metaverse_avatar_create_flow, &ux_confirm_single_flow_1_step, - &ux_confirm_metaverse_avatar_create_flow_2_step, + &ux_confirm_metaverse_newavatar_step, &ux_confirm_single_flow_3_step, &ux_confirm_single_flow_5_step, &ux_confirm_single_flow_6_step @@ -1795,46 +1802,38 @@ UX_FLOW(ux_confirm_metaverse_avatar_create_flow, UX_FLOW(ux_confirm_metaverse_mit_transfer_flow, &ux_confirm_single_flow_1_step, &ux_confirm_single_flow_2_step, - &ux_confirm_metaverse_mit_transfer_flow_2_step, + &ux_confirm_metaverse_toavatar_step, &ux_confirm_single_flow_3_step, &ux_confirm_single_flow_5_step, &ux_confirm_single_flow_6_step ); UX_STEP_NOCB( - ux_confirm_metaverse_mit_create_flow_2_step, - bnnn_paging, - { - .title = "Avatar", - .text = vars.tmp.metaverse_did, - }); -UX_STEP_NOCB( - ux_confirm_metaverse_mit_create_flow_4_step, + ux_confirm_metaverse_mit_create_step, bnnn_paging, { - .title = "Message", - .text = vars.tmp.metaverse_message, + .title = "New MIT", + .text = vars.tmp.fullAmount, }); UX_FLOW(ux_confirm_metaverse_mit_create_flow, &ux_confirm_single_flow_1_step, - &ux_confirm_single_flow_2_step, - &ux_confirm_metaverse_mit_create_flow_2_step, + &ux_confirm_metaverse_mit_create_step, + &ux_confirm_metaverse_toavatar_step, &ux_confirm_single_flow_3_step, - &ux_confirm_metaverse_mit_create_flow_4_step, &ux_confirm_single_flow_5_step, &ux_confirm_single_flow_6_step ); // Message UX_STEP_NOCB( - ux_confirm_metaverse_message_flow_2_step, + ux_confirm_metaverse_message_step, bnnn_paging, { .title = "Message", - .text = vars.tmp.metaverse_message, + .text = vars.tmp.fullAmount, }); UX_FLOW(ux_confirm_metaverse_message_flow, &ux_confirm_single_flow_1_step, - &ux_confirm_metaverse_message_flow_2_step, + &ux_confirm_metaverse_message_step, &ux_confirm_single_flow_3_step, &ux_confirm_single_flow_5_step, &ux_confirm_single_flow_6_step @@ -1842,16 +1841,16 @@ UX_FLOW(ux_confirm_metaverse_message_flow, // Cert UX_STEP_NOCB( - ux_confirm_metaverse_cert_flow_2_step, + ux_confirm_metaverse_cert_step, bnnn_paging, { .title = "Certificate", - .text = vars.tmp.metaverse_message, + .text = vars.tmp.fullAmount, }); UX_FLOW(ux_confirm_metaverse_cert_flow, &ux_confirm_single_flow_1_step, - &ux_confirm_metaverse_cert_flow_2_step, - &ux_confirm_metaverse_mit_create_flow_2_step, + &ux_confirm_metaverse_cert_step, + &ux_confirm_metaverse_toavatar_step, &ux_confirm_single_flow_3_step, &ux_confirm_single_flow_5_step, &ux_confirm_single_flow_6_step @@ -2399,8 +2398,9 @@ uint8_t prepare_single_output() { ETP_TMP = *ETP_POINTER; ETP_COUNTER += 1; - os_memmove(vars.tmp.metaverse_did, ETP_POINTER, ETP_TMP); - vars.tmp.metaverse_did[ETP_TMP] = '\0'; + ETP_TLEN = ETP_MIN(ETP_TMP, sizeof(vars.tmp.metaverse_did) - 1); + os_memmove(vars.tmp.metaverse_did, ETP_POINTER, ETP_TLEN); + vars.tmp.metaverse_did[ETP_TLEN] = '\0'; ETP_COUNTER += ETP_TMP; // from_did length @@ -2458,8 +2458,9 @@ uint8_t prepare_single_output() { // Symbol ETP_TMP = *ETP_POINTER; ETP_COUNTER += 1; - os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TMP); - vars.tmp.fullAmount[ETP_TMP] = '\0'; + ETP_TLEN = ETP_MIN(ETP_TMP, sizeof(vars.tmp.fullAmount) - 1); + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TLEN); + vars.tmp.fullAmount[ETP_TLEN] = '\0'; ETP_COUNTER += ETP_TMP; // Maximum supply @@ -2475,7 +2476,7 @@ uint8_t prepare_single_output() { } // Secondary issue threshold - // writeUInt8 + ETP_COUNTER += 1; // 0000 bytes os_memmove(ETP_BUFF, ETP_POINTER, 2); @@ -2515,8 +2516,10 @@ uint8_t prepare_single_output() { // Description ETP_TMP = *ETP_POINTER; ETP_COUNTER += 1; - //os_memmove(vars.tmp.metaverse_message, ETP_POINTER, ETP_LENGTH); - //vars.tmp.metaverse_message[ETP_LENGTH] = '\0'; + //ETP_TLEN = ETP_MIN(ETP_TMP, sizeof(vars.tmp.metaverse_message) - 1); + //os_memmove(vars.tmp.metaverse_message, ETP_POINTER, ETP_TLEN); + //vars.tmp.metaverse_message[ETP_TLEN] = '\0'; + ETP_COUNTER += ETP_TMP; ETP_OUT_TYPE = 21; } else if (ETP_BUFF[0] == 2) { // MST.STATUS.TRANSFER @@ -2554,11 +2557,32 @@ uint8_t prepare_single_output() { return 0; } } else if (ETP_BUFF[0] == 3) { // ATTACHMENT.TYPE.MESSAGE + // Throw error is ETP amount is non zero + if ( + amount[0] != 0 || + amount[1] != 0 || + amount[2] != 0 || + amount[3] != 0 || + amount[4] != 0 || + amount[5] != 0 || + amount[6] != 0 || + amount[7] != 0 + ) { + PRINTF("PARSE ERROR AMOUNT != 0\n"); + return 0; + } + // Message ETP_TMP = *ETP_POINTER; ETP_COUNTER += 1; - //os_memmove(vars.tmp.metaverse_message, ETP_POINTER, ETP_LENGTH); - //vars.tmp.metaverse_message[ETP_LENGTH] = '\0'; + + ETP_TLEN = ETP_MIN(ETP_TMP, sizeof(vars.tmp.fullAmount) - 1); + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TLEN); + vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 2] = '.'; + vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 3] = '.'; + vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 4] = '.'; + vars.tmp.fullAmount[ETP_TLEN] = '\0'; + ETP_COUNTER += ETP_TMP; ETP_OUT_TYPE = 3; } else if (ETP_BUFF[0] == 4) { // ATTACHMENT.TYPE.AVATAR @@ -2594,9 +2618,9 @@ uint8_t prepare_single_output() { // Symbol text length ETP_TMP = *ETP_POINTER; ETP_COUNTER += 1; - - os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TMP); - vars.tmp.fullAmount[ETP_TMP] = '\0'; + ETP_TLEN = ETP_MIN(ETP_TMP, sizeof(vars.tmp.fullAmount) - 1); + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TLEN); + vars.tmp.fullAmount[ETP_TLEN] = '\0'; ETP_COUNTER += ETP_TMP; // Symbol address length @@ -2626,27 +2650,64 @@ uint8_t prepare_single_output() { return 0; } } else if (ETP_BUFF[0] == 5) { // ATTACHMENT.TYPE.CERT + // Throw error is ETP amount is non zero + if ( + amount[0] != 0 || + amount[1] != 0 || + amount[2] != 0 || + amount[3] != 0 || + amount[4] != 0 || + amount[5] != 0 || + amount[6] != 0 || + amount[7] != 0 + ) { + PRINTF("PARSE ERROR AMOUNT != 0\n"); + return 0; + } + // Symbol - ETP_TMP = *(btchip_context_D.currentOutput + ETP_COUNTER); - ETP_COUNTER += 1 + ETP_TMP; + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + ETP_TLEN = ETP_MIN(ETP_TMP, sizeof(vars.tmp.fullAmount) - 1); + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TLEN); + vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 2] = '.'; + vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 3] = '.'; + vars.tmp.fullAmount[sizeof(vars.tmp.fullAmount) - 4] = '.'; + vars.tmp.fullAmount[ETP_TLEN] = '\0'; + ETP_COUNTER += ETP_TMP; // Owner - ETP_TMP = *(btchip_context_D.currentOutput + ETP_COUNTER); - ETP_COUNTER += 1 + ETP_TMP; + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + if ( + strlen(vars.tmp.metaverse_did) != ETP_TMP || + os_memcmp(vars.tmp.metaverse_did, ETP_POINTER, ETP_TMP) != 0 + ) { + PRINTF("PARSE ERROR OUTPUT AVATAR != ATTACHMENT CERT OWNER\n"); + return 0; + } + ETP_COUNTER += ETP_TMP; // Address - ETP_TMP = *(btchip_context_D.currentOutput + ETP_COUNTER); - ETP_COUNTER += 1 + ETP_TMP; + ETP_TMP = *ETP_POINTER; + ETP_COUNTER += 1; + if ( + strlen(vars.tmp.fullAddress) != ETP_TMP || + os_memcmp(vars.tmp.fullAddress, ETP_POINTER, ETP_TMP) != 0 + ) { + PRINTF("PARSE ERROR OUTPUT ADDRESS != ATTACHMENT CERT ADDRESS\n"); + return 0; + } + ETP_COUNTER += ETP_TMP; - os_memmove(ETP_BUFF, btchip_context_D.currentOutput + ETP_COUNTER, 4); + os_memmove(ETP_BUFF, ETP_POINTER, 4); ETP_COUNTER += 4; // Cert ETP_COUNTER += 1; // Status if (true) { // Check currentOutput has more data // content - ETP_TMP = *(btchip_context_D.currentOutput + ETP_COUNTER); - //os_memmove(ETP_BUFF, btchip_context_D.currentOutput + ETP_COUNTER, 4); + ETP_TMP = *ETP_POINTER; ETP_COUNTER += 1 + ETP_TMP; } @@ -2675,11 +2736,12 @@ uint8_t prepare_single_output() { // Symbol ETP_TMP = *ETP_POINTER; ETP_COUNTER += 1; - os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TMP); - vars.tmp.fullAmount[ETP_TMP] = '\0'; + ETP_TLEN = ETP_MIN(ETP_TMP, sizeof(vars.tmp.fullAmount) - 1); + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TLEN); + vars.tmp.fullAmount[ETP_TLEN] = '\0'; ETP_COUNTER += ETP_TMP; - // Address length + // Address ETP_TMP = *ETP_POINTER; ETP_COUNTER += 1; if ( @@ -2693,18 +2755,16 @@ uint8_t prepare_single_output() { // Content ETP_TMP = *ETP_POINTER; - ETP_COUNTER += 1; - //os_memmove(vars.tmp.metaverse_message, ETP_POINTER, ETP_TMP); - //vars.tmp.metaverse_message[ETP_TMP] = '\0'; - ETP_COUNTER += ETP_TMP; + ETP_COUNTER += 1 + ETP_TMP; ETP_OUT_TYPE = 61; } else if (ETP_BUFF[0] == 2) { // MIT.STATUS.TRANSFER // Symbol ETP_TMP = *ETP_POINTER; ETP_COUNTER += 1; - os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TMP); - vars.tmp.fullAmount[ETP_TMP] = '\0'; + ETP_TLEN = ETP_MIN(ETP_TMP, sizeof(vars.tmp.fullAmount) - 1); + os_memmove(vars.tmp.fullAmount, ETP_POINTER, ETP_TLEN); + vars.tmp.fullAmount[ETP_TLEN] = '\0'; ETP_COUNTER += ETP_TMP; // Address @@ -2714,8 +2774,6 @@ uint8_t prepare_single_output() { PRINTF("PARSE ERROR OUTPUT ADDRESS != ATTACHMENT ADDRESS\n"); return 0; } - //os_memmove(vars.tmp.fullAddress, ETP_POINTER, ETP_TMP); - //vars.tmp.fullAddress[ETP_TMP] = '\0'; ETP_COUNTER += ETP_TMP; ETP_OUT_TYPE = 62; From d9b4fa66333d40ea6133231c9cc0d5f983b55ae0 Mon Sep 17 00:00:00 2001 From: smdmitry Date: Tue, 7 Jan 2020 02:20:13 +0300 Subject: [PATCH 08/10] ifdef APP_METAVERSE --- include/btchip_context.h | 4 ++-- src/btchip_apdu_hash_input_finalize_full.c | 8 ++++++-- src/btchip_context.c | 8 ++++++-- src/main.c | 5 ++--- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/btchip_context.h b/include/btchip_context.h index 2dcd86de..3b9e9b25 100644 --- a/include/btchip_context.h +++ b/include/btchip_context.h @@ -241,8 +241,7 @@ struct btchip_context_s { unsigned int discardSize; unsigned char outputParsingState; unsigned char totalOutputAmount[8]; - unsigned char totalTokenInputAmount[8]; - unsigned char changeOutputFound; + unsigned char changeOutputFound; /* Overwinter */ unsigned char usingOverwinter; @@ -253,6 +252,7 @@ struct btchip_context_s { unsigned char sigHashType[4]; #ifdef APP_METAVERSE + unsigned char totalTokenInputAmount[8]; unsigned char decimals[4]; // For Metaverse tokens, need to provide precision for all outputs from external source (maximum can handle 4 outputs with tokens) #endif }; diff --git a/src/btchip_apdu_hash_input_finalize_full.c b/src/btchip_apdu_hash_input_finalize_full.c index f88cec2b..276683a4 100644 --- a/src/btchip_apdu_hash_input_finalize_full.c +++ b/src/btchip_apdu_hash_input_finalize_full.c @@ -38,8 +38,12 @@ static void btchip_apdu_hash_input_finalize_full_reset(void) { btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS; os_memset(btchip_context_D.totalOutputAmount, 0, sizeof(btchip_context_D.totalOutputAmount)); - os_memset(btchip_context_D.totalTokenInputAmount, 0, - sizeof(btchip_context_D.totalTokenInputAmount)); + #ifdef APP_METAVERSE + if (G_coin_config->kind == COIN_KIND_METAVERSE) { + os_memset(btchip_context_D.totalTokenInputAmount, 0, + sizeof(btchip_context_D.totalTokenInputAmount)); + } + #endif btchip_context_D.changeOutputFound = 0; btchip_set_check_internal_structure_integrity(1); } diff --git a/src/btchip_context.c b/src/btchip_context.c index f5d90fc8..b2f679ac 100644 --- a/src/btchip_context.c +++ b/src/btchip_context.c @@ -31,8 +31,12 @@ void btchip_context_init() { btchip_context_D.outputParsingState = BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS; os_memset(btchip_context_D.totalOutputAmount, 0, sizeof(btchip_context_D.totalOutputAmount)); - os_memset(btchip_context_D.totalTokenInputAmount, 0, - sizeof(btchip_context_D.totalTokenInputAmount)); + #ifdef APP_METAVERSE + if (G_coin_config->kind == COIN_KIND_METAVERSE) { + os_memset(btchip_context_D.totalTokenInputAmount, 0, + sizeof(btchip_context_D.totalTokenInputAmount)); + } + #endif btchip_context_D.changeOutputFound = 0; if (N_btchip.config_valid != 0x01) { diff --git a/src/main.c b/src/main.c index 1fb9611b..c0760533 100644 --- a/src/main.c +++ b/src/main.c @@ -156,10 +156,11 @@ union { // of char fullAddress[65]; // the address - char fullAmount[20]; // full amount (Metaverse may have long token names, so maybe increase from 20 to 40?) + char fullAmount[20]; // full amount char feesAmount[20]; // fees #ifdef APP_METAVERSE + // char fullAmount[20]; // full amount (Metaverse may have long token names, so maybe increase from 20 to 40?) char metaverse_decimals[3]; //char metaverse_message[255]; char metaverse_did[20]; @@ -2535,8 +2536,6 @@ uint8_t prepare_single_output() { btchip_swap_bytes(amount, ETP_POINTER, 8); ETP_COUNTER += 8; - //transaction_amount_sub_be(btchip_context_D.totalTokenInputAmount, btchip_context_D.totalTokenInputAmount, amount); - // Hardcode some tokens with predefined decimals (no need to display decimals confirmation to user) if (strcmp(vars.tmp.fullAmount, "DNA") == 0) { ETP_DECIMALS = 4; From 4ed50690a08b48dd45c7d0efd8cc057579c307eb Mon Sep 17 00:00:00 2001 From: smdmitry Date: Tue, 7 Jan 2020 02:21:59 +0300 Subject: [PATCH 09/10] fix --- include/btchip_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/btchip_context.h b/include/btchip_context.h index 3b9e9b25..bf3146da 100644 --- a/include/btchip_context.h +++ b/include/btchip_context.h @@ -241,7 +241,7 @@ struct btchip_context_s { unsigned int discardSize; unsigned char outputParsingState; unsigned char totalOutputAmount[8]; - unsigned char changeOutputFound; + unsigned char changeOutputFound; /* Overwinter */ unsigned char usingOverwinter; From 904de43d2ef0cd009eebd9c0e31dc4a60cfd99cc Mon Sep 17 00:00:00 2001 From: smdmitry Date: Wed, 8 Jan 2020 21:11:42 +0300 Subject: [PATCH 10/10] comments --- include/btchip_context.h | 4 ++-- src/btchip_apdu_hash_input_finalize_full.c | 5 +++-- src/main.c | 12 +++++------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/btchip_context.h b/include/btchip_context.h index bf3146da..5a4a4857 100644 --- a/include/btchip_context.h +++ b/include/btchip_context.h @@ -241,7 +241,7 @@ struct btchip_context_s { unsigned int discardSize; unsigned char outputParsingState; unsigned char totalOutputAmount[8]; - unsigned char changeOutputFound; + unsigned char changeOutputFound; /* Overwinter */ unsigned char usingOverwinter; @@ -252,7 +252,7 @@ struct btchip_context_s { unsigned char sigHashType[4]; #ifdef APP_METAVERSE - unsigned char totalTokenInputAmount[8]; + unsigned char totalTokenInputAmount[8]; // same as totalOutputAmount, but for Tokens unsigned char decimals[4]; // For Metaverse tokens, need to provide precision for all outputs from external source (maximum can handle 4 outputs with tokens) #endif }; diff --git a/src/btchip_apdu_hash_input_finalize_full.c b/src/btchip_apdu_hash_input_finalize_full.c index 276683a4..969e7d16 100644 --- a/src/btchip_apdu_hash_input_finalize_full.c +++ b/src/btchip_apdu_hash_input_finalize_full.c @@ -116,7 +116,7 @@ static bool check_output_displayable() { #ifdef APP_METAVERSE if (G_coin_config->kind == COIN_KIND_METAVERSE) { if (ETP_OUT_TYPE == 3 || ETP_OUT_TYPE == 21 || ETP_OUT_TYPE == 41 || ETP_OUT_TYPE == 42 || ETP_OUT_TYPE == 61 || ETP_OUT_TYPE == 62) { - changeFound = false; + changeFound = false; // Always display some transaction output types (even when it is for the same address as input) } } #endif @@ -474,7 +474,7 @@ unsigned short btchip_apdu_hash_input_finalize_full_internal( #ifdef APP_METAVERSE if (G_coin_config->kind == COIN_KIND_METAVERSE) { - btchip_context_D.tmpCtx.output.multipleOutput = 1; + btchip_context_D.tmpCtx.output.multipleOutput = 1; // Disable BTCHIP_OUTPUT_HANDLE_LEGACY; } #endif @@ -492,6 +492,7 @@ unsigned short btchip_apdu_hash_input_finalize_full_internal( #ifdef APP_METAVERSE if (G_coin_config->kind == COIN_KIND_METAVERSE) { if (G_io_apdu_buffer[ISO_OFFSET_P2] == 0x0E) { + // This command is used to specify decimal precision for tokens outputs if (apduLength > 4) { // For Metaverse can handle max 4 outputs with tokens goto discardTransaction; } diff --git a/src/main.c b/src/main.c index c0760533..e8a6c526 100644 --- a/src/main.c +++ b/src/main.c @@ -160,10 +160,10 @@ union { char feesAmount[20]; // fees #ifdef APP_METAVERSE - // char fullAmount[20]; // full amount (Metaverse may have long token names, so maybe increase from 20 to 40?) - char metaverse_decimals[3]; - //char metaverse_message[255]; - char metaverse_did[20]; + // char fullAmount[40]; - Metaverse may have long token names, so maybe increase fullAmount from 20 to 40? + // char metaverse_message[255]; - app freezes when having this var + char metaverse_decimals[3]; // For displaying decimals (0-10) + char metaverse_did[20]; // For displaying destination avatar #endif } tmp; @@ -995,7 +995,6 @@ unsigned int ui_verify_output_nanos_button(unsigned int button_mask, #ifdef APP_METAVERSE const bagl_element_t ui_verify_output_decimals_nanos[] = { - UI_NANOS_BACKGROUND(), UI_NANOS_ICON_LEFT(0, BAGL_GLYPH_ICON_CROSS), UI_NANOS_ICON_RIGHT(0, BAGL_GLYPH_ICON_CHECK), @@ -1741,7 +1740,6 @@ UX_FLOW(ux_confirm_single_flow, ); #ifdef APP_METAVERSE -// Metaverse MST // confirm_single: confirm output #x(feesAmount) / Amount: fullAmount / Decimals: decimals / Address: fullAddress UX_STEP_NOCB( ux_confirm_single_flow_4_step, @@ -2192,6 +2190,7 @@ uint8_t prepare_fees() { btchip_context_D.totalTokenInputAmount[6] != 0 || btchip_context_D.totalTokenInputAmount[7] != 0 ) { + // Transaction input tokens amount must be equal to output tokens amount (MIT counts as 1) PRINTF("Error : Token amount not consistent"); goto error; } @@ -2350,7 +2349,6 @@ uint8_t prepare_single_output() { } #ifdef APP_METAVERSE - // 0 - ETP, 21 - MST REG, 22 - MST TX, 3 - MESSAGE, 41 - AVA REG, 42 - AVA TX, 5 - CERT, 61 - MIT REG, 62 - MIT TX if (G_coin_config->kind == COIN_KIND_METAVERSE) { // Parsing displayable outputs ETP_OUT_TYPE = 255;