From 1eb91d8e9cac8f54b4c6a60d2be6ed1cbcde5240 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sat, 21 May 2022 14:34:40 +0100 Subject: [PATCH] Add pagination to single block view --- frontend/package-lock.json | 27 +++++++++++++++++++++++++++ frontend/package.json | 3 ++- frontend/src/global.scss | 4 ++++ frontend/src/lib/bitcoinScript.ts | 16 +++++++++++++++- frontend/src/routes/block/[id].svelte | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- frontend/src/routes/index.svelte | 3 ++- indexer/src/main.rs | 2 +- web-api/src/database/blocks.rs | 5 ++++- web-api/src/database/transactions.rs | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- web-api/src/methods/block.rs | 52 +++++++++++++++++++++++++++++++++++++++------------- 10 files changed, 248 insertions(+), 83 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 11464ed..2a0987e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "dependencies": { "buffer": "^6.0.3", + "svelte-time": "^0.7.0", "sveltekit-i18n": "^2.2.1" }, "devDependencies": { @@ -871,6 +872,11 @@ "node": ">=4" } }, + "node_modules/dayjs": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz", + "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2890,6 +2896,14 @@ "sourcemap-codec": "^1.4.8" } }, + "node_modules/svelte-time": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/svelte-time/-/svelte-time-0.7.0.tgz", + "integrity": "sha512-AJFAJInN+Kp0HmOKOMATlSV4A7/j0psmGpaV6KDfYDTBszi0E3p/VOYiayfZ/krTl0CZqBHKRLGPCB7XdAqG9A==", + "dependencies": { + "dayjs": "^1.10.7" + } + }, "node_modules/sveltekit-i18n": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/sveltekit-i18n/-/sveltekit-i18n-2.2.1.tgz", @@ -3725,6 +3739,11 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, + "dayjs": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz", + "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -5036,6 +5055,14 @@ } } }, + "svelte-time": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/svelte-time/-/svelte-time-0.7.0.tgz", + "integrity": "sha512-AJFAJInN+Kp0HmOKOMATlSV4A7/j0psmGpaV6KDfYDTBszi0E3p/VOYiayfZ/krTl0CZqBHKRLGPCB7XdAqG9A==", + "requires": { + "dayjs": "^1.10.7" + } + }, "sveltekit-i18n": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/sveltekit-i18n/-/sveltekit-i18n-2.2.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 953906a..b52575c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -35,6 +35,7 @@ "type": "module", "dependencies": { "buffer": "^6.0.3", - "sveltekit-i18n": "^2.2.1" + "sveltekit-i18n": "^2.2.1", + "svelte-time": "^0.7.0" } } diff --git a/frontend/src/global.scss b/frontend/src/global.scss index 2a049eb..2eaaf9d 100644 --- a/frontend/src/global.scss +++ b/frontend/src/global.scss @@ -6,6 +6,10 @@ body { @apply bg-gray-900; } +time { + @apply decoration-dashed underline cursor-help; +} + a { @apply text-sky-400 transition-all; diff --git a/frontend/src/lib/bitcoinScript.ts b/frontend/src/lib/bitcoinScript.ts index 28d9d06..8f8adb5 100644 --- a/frontend/src/lib/bitcoinScript.ts +++ b/frontend/src/lib/bitcoinScript.ts @@ -15,7 +15,7 @@ export function hexToAsm(hex: string) { } if (byte >= 0x52 && byte <= 0x60) { - out.push(byte-0x50) + out.push(byte - 0x50) continue; } @@ -30,6 +30,20 @@ export function hexToAsm(hex: string) { return out; } +export function briefHexToAsm(hex: string) { + const asm = hexToAsm(hex); + + const OP_RETURN = Operation[Operation.OP_RETURN]; + + for (const op of asm) { + if (op === OP_RETURN) { + return [OP_RETURN]; + } + } + + return asm; +} + enum Operation { OP_FALSE = 0x00, OP_PUSHDATA1 = 0x4c, diff --git a/frontend/src/routes/block/[id].svelte b/frontend/src/routes/block/[id].svelte index 7301541..2daf05f 100644 --- a/frontend/src/routes/block/[id].svelte +++ b/frontend/src/routes/block/[id].svelte @@ -1,11 +1,23 @@
@@ -50,52 +59,108 @@
-

{block.transactions.length} Transactions

+

{block.tx_count} Transaction{block.tx_count > 1 ? 's' : ''}

{#each block.transactions as transaction} -
-

{transaction.hash}

+
+

+ § + {transaction.hash} +

-
- - +
+
{#if transaction.coinbase} -
- - +
+ Coinbase +
{:else} {#each transaction.inputs as input} - - - +
+
+ {input.previous_output?.address || briefHexToAsm(input.script).join('\n')} +
+ + {#if input.previous_output} +
+ {(input.previous_output.value / scale).toFixed(8)} BTC +
+ {/if} +
{/each} {/if} - -
Coinbase
{input.previous_output?.address || hexToAsm(input.script).join('\n')}
+
-
+
- - - - {#each transaction.outputs as output} - - {/each} - -
{output.address || hexToAsm(output.script).join('\n')}
+
+ {#each transaction.outputs as output} +
+
+ {output.address || briefHexToAsm(output.script).join(' ').trim() || output.script} +
+ +
+ {(output.value / scale).toFixed(8)} BTC +
+
+ {/each} +
{/each} + +
diff --git a/frontend/src/routes/index.svelte b/frontend/src/routes/index.svelte index abd6eaf..ffe2de5 100644 --- a/frontend/src/routes/index.svelte +++ b/frontend/src/routes/index.svelte @@ -18,6 +18,7 @@