diff --git a/src/components/Transaction/TransactionInputViewer.vue b/src/components/Transaction/TransactionInputViewer.vue new file mode 100644 index 00000000..203d5c36 --- /dev/null +++ b/src/components/Transaction/TransactionInputViewer.vue @@ -0,0 +1,292 @@ + + + + + + diff --git a/src/components/TransactionOverview.vue b/src/components/TransactionOverview.vue index 9f499741..91d5d326 100644 --- a/src/components/TransactionOverview.vue +++ b/src/components/TransactionOverview.vue @@ -1,6 +1,6 @@ @@ -483,7 +519,13 @@ watch(() => showMoreDetails.value, (newShowMoreDetails) => {
-
{{ trx.input }}
+
+ +
@@ -524,6 +566,7 @@ watch(() => showMoreDetails.value, (newShowMoreDetails) => { } &__col-val { flex-grow: 1; + overflow: hidden; } &__row { padding: 0.5rem 0; diff --git a/src/i18n/de-de/index.js b/src/i18n/de-de/index.js index 4e692bc7..4a76fa65 100644 --- a/src/i18n/de-de/index.js +++ b/src/i18n/de-de/index.js @@ -274,6 +274,15 @@ export default { download_image: 'Bild herunterladen', confirm_download_image: 'Bestätigen Sie, dass Sie dieses Bild herunterladen möchten', confirm: 'Bestätigen', + input_viewer: { + name: 'Name', + type: 'Typ', + data: 'Daten', + default_view: 'Standardansicht', + original_view: 'Originalansicht', + decoded_view: 'Dekodierte Ansicht', + copy_button_desc: 'Parametertabelle', + }, transaction: { in: 'in', out: 'out', diff --git a/src/i18n/en-us/index.js b/src/i18n/en-us/index.js index 5a48164e..d1f0a296 100644 --- a/src/i18n/en-us/index.js +++ b/src/i18n/en-us/index.js @@ -225,6 +225,15 @@ export default { download_image: 'Download Image', confirm_download_image: 'Confirm you want to download this image', confirm: 'Confirm', + input_viewer: { + name: 'Name', + type: 'Type', + data: 'Data', + default_view: 'Default View', + original_view: 'Original View', + decoded_view: 'Decoded View', + copy_button_desc: 'parameters table', + }, approvals: { token_id: 'Token ID', approved: 'Approved', diff --git a/src/i18n/es-es/index.js b/src/i18n/es-es/index.js index ea97a23a..1c859b63 100644 --- a/src/i18n/es-es/index.js +++ b/src/i18n/es-es/index.js @@ -275,6 +275,15 @@ export default { download_image: 'Descargar imagen', confirm_download_image: 'Confirma que quieres descargar esta imagen', confirm: 'Confirmar', + input_viewer: { + name: 'Nombre', + type: 'Tipo', + data: 'Datos', + default_view: 'Vista predeterminada', + original_view: 'Vista original', + decoded_view: 'Vista decodificada', + copy_button_desc: 'tabla de parámetros', + }, transaction: { in: 'entra', out: 'sale', diff --git a/src/i18n/fr-fr/index.js b/src/i18n/fr-fr/index.js index 683cc01a..2a3fde13 100644 --- a/src/i18n/fr-fr/index.js +++ b/src/i18n/fr-fr/index.js @@ -220,6 +220,15 @@ export default { download_image: 'Télécharger l’image', confirm_download_image: 'Confirmez que vous voulez télécharger cette image', confirm: 'Confirmer', + input_viewer: { + name: 'Nom', + type: 'Type', + data: 'Données', + default_view: 'Vue par défaut', + original_view: 'Vue originale', + decoded_view: 'Vue décodée', + copy_button_desc: 'tableau des paramètres', + }, approvals: { token_id: 'ID Jeton', approved: 'Approuvé', diff --git a/src/i18n/pt-br/index.js b/src/i18n/pt-br/index.js index 4664733c..f29537ff 100644 --- a/src/i18n/pt-br/index.js +++ b/src/i18n/pt-br/index.js @@ -274,6 +274,15 @@ export default { download_image: 'Baixar imagem', confirm_download_image: 'Confirme que deseja baixar esta imagem', confirm: 'Confirmar', + input_viewer: { + name: 'Nome', + type: 'Tipo', + data: 'Dados', + default_view: 'Vista padrão', + original_view: 'Vista original', + decoded_view: 'Vista decodificada', + copy_button_desc: 'tabela de parâmetros', + }, transaction: { in: 'in', out: 'out', diff --git a/src/lib/transaction-utils.ts b/src/lib/transaction-utils.ts index d8fd0b01..2ff37add 100644 --- a/src/lib/transaction-utils.ts +++ b/src/lib/transaction-utils.ts @@ -66,6 +66,48 @@ export const loadTransaction = async (hash: string): Promise { + const value = values[index]; + let length = 64; // Longitud predeterminada para uint256, bool, etc. + let inputPortion = ''; + + if (input.type === 'address') { + length = 64; + inputPortion = inputString.slice(offset, offset + length); + } else if (input.type === 'uint128' || input.type.startsWith('uint')) { + inputPortion = inputString.slice(offset, offset + length); + } else if (input.type === 'bool') { + inputPortion = inputString.slice(offset, offset + length); + } else if (input.type === 'string' || input.type.startsWith('bytes')) { + const dataOffset = parseInt(inputString.slice(offset, offset + 64), 16) * 2; + const dataLength = parseInt(inputString.slice(dataOffset, dataOffset + 64), 16) * 2; + inputPortion = inputString.slice(dataOffset + 64, dataOffset + 64 + dataLength); + length = 64; // Reinicia la longitud a 64 para los punteros + } + + const result = { + name: input.name, + type: input.type, + value: value, + input: inputPortion, + }; + + offset += length; + return result; + }); + + return list; +} + +export interface DecodedTransactionInput { + method: string; + name: string; + args: {name: string, type: string, input: string, value: unknown}[]; + input: string; +} export const getParsedInternalTransactions = async (hash: string, $t: (k:string)=>string) => new Promise<{itxs:unknown[], parsedItxs:unknown[]}>((resolve, reject) => { const query = `/transaction/${hash}/internal?limit=1000&sort=ASC&offset=0&includeAbi=1`; @@ -92,6 +134,7 @@ export const getParsedInternalTransactions = async (hash: string, $t: (k:string) itx.callType = itx.action.callType; const contract = await contractManager.getContract(itx.action.to); let inputs, outputs, args, name, isTransferETH = false; + let decoded: DecodedTransactionInput|null = null; if (itx.type === 'create') { name = $t('components.transaction.contract_deployment'); @@ -117,10 +160,26 @@ export const getParsedInternalTransactions = async (hash: string, $t: (k:string) inputs = parsedTransaction.functionFragment ? parsedTransaction.functionFragment.inputs : parsedTransaction.inputs; + + // Extraemos "setValue" de la string "setValue(string,uint128,uint128)" + const mothod = name ? name.split('(')[0] : ''; + + const values = args; + const decodedArgs = parseInput(itx.action.input, inputs, values); + + decoded = { + mothod, + name: name, + args: decodedArgs, + input: itx.action.input, + } as unknown as DecodedTransactionInput; } } itxs.push(itx); + + parsedItxs.push({ + decoded, index: itx.index, type: itx.type, args: args, diff --git a/src/pages/TransactionPage.vue b/src/pages/TransactionPage.vue index 38475997..c980c273 100644 --- a/src/pages/TransactionPage.vue +++ b/src/pages/TransactionPage.vue @@ -31,6 +31,7 @@ watch(() => route.params.hash, async (newValue) => { hash.value = typeof newValue === 'string' ? newValue : newValue[0]; trx.value = await loadTransaction(hash.value); trxNotFound.value = !trx.value; + }, { immediate: true });