Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Metaverse #145

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions Makefile
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,16 @@ 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
DEFINES += APP_METAVERSE
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

Expand Down Expand Up @@ -318,6 +325,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
Binary file added blue_app_metaverse.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added blue_badge_metaverse.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion include/btchip_bcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
27 changes: 25 additions & 2 deletions include/btchip_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -250,6 +250,11 @@ struct btchip_context_s {
unsigned char nExpiryHeight[4];
unsigned char nLockTime[4];
unsigned char sigHashType[4];

#ifdef APP_METAVERSE
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
};
typedef struct btchip_context_s btchip_context_t;

Expand Down Expand Up @@ -292,7 +297,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 {
Expand All @@ -316,4 +322,21 @@ typedef struct btchip_altcoin_config_s {

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]
#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
#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
3 changes: 2 additions & 1 deletion include/btchip_filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Binary file added metaverse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nanos_app_metaverse.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nanos_badge_metaverse.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nanox_app_metaverse.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
239 changes: 239 additions & 0 deletions src/btchip_apdu_hash_input_finalize_full.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +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));
#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);
}
Expand Down Expand Up @@ -106,7 +112,30 @@ 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; // Always display some transaction output types (even when it is for the same address as input)
}
}
#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) {
PRINTF("Error : Multiple change output found");
THROW(EXCEPTION);
}
btchip_context_D.changeOutputFound++;
displayable = false;

return displayable;
}
#endif

if (btchip_context_D.changeOutputFound) {
PRINTF("Error : Multiple change output found");
THROW(EXCEPTION);
Expand Down Expand Up @@ -171,6 +200,197 @@ static bool handle_output_state() {
if (btchip_context_D.currentOutput[8] < 0xFD) {
scriptSize = btchip_context_D.currentOutput[8];
discardSize = 1;

#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;

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'

ETP_COUNTER += *ETP_POINTER + 1; // issuer
ETP_COUNTER += *ETP_POINTER + 1; // recipient address
ETP_COUNTER += *ETP_POINTER + 1; // description

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, 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;
Expand Down Expand Up @@ -252,6 +472,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; // Disable BTCHIP_OUTPUT_HANDLE_LEGACY;
}
#endif

// Check state
BEGIN_TRY {
TRY {
Expand All @@ -263,6 +489,19 @@ unsigned short btchip_apdu_hash_input_finalize_full_internal(
}

if (p1 == FINALIZE_P1_CHANGEINFO) {
#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;
}
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) {
// Already validated, should be prevented on the client side
Expand Down
14 changes: 4 additions & 10 deletions src/btchip_bcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading