From 470d1475a14578ad2f2daaa5fd6a278c023e787c Mon Sep 17 00:00:00 2001 From: Dan Janosik Date: Mon, 6 Aug 2018 12:19:14 -0400 Subject: [PATCH] - shared template for tx io details (used on tx + block pages) - ui tweaks --- views/includes/block-content.pug | 123 ++----------- views/includes/transaction-io-details.pug | 97 ++++++++++ views/transaction.pug | 207 ++++++++-------------- 3 files changed, 192 insertions(+), 235 deletions(-) create mode 100644 views/includes/transaction-io-details.pug diff --git a/views/includes/block-content.pug b/views/includes/block-content.pug index 4d72d10..0734d63 100644 --- a/views/includes/block-content.pug +++ b/views/includes/block-content.pug @@ -45,11 +45,11 @@ div(class="tab-content") if (result.getblock.previousblockhash) a(class="word-wrap", href=("/block/" + result.getblock.previousblockhash)) #{result.getblock.previousblockhash} br - span(class="text-muted") ##{(result.getblock.height - 1).toLocaleString()} + span (##{(result.getblock.height - 1).toLocaleString()}) else if (result.getblock.hash == genesisBlockHash) span None - span(class="text-muted") (genesis block) + span (genesis block) if (false) tr @@ -81,11 +81,6 @@ div(class="tab-content") - var currencyValue = new Decimal(result.getblock.totalFees).dividedBy(result.getblock.tx.length); include ./value-display.pug - tr - td(class="properties-header") Size - td(class="monospace") - span #{result.getblock.size.toLocaleString()} bytes - if (result.getblock.weight) tr td(class="properties-header") Weight @@ -93,13 +88,18 @@ div(class="tab-content") span #{result.getblock.weight.toLocaleString()} wu span(class="text-muted") (#{new Decimal(100 * result.getblock.weight / coinConfig.maxBlockWeight).toDecimalPlaces(2)}% full) + tr + td(class="properties-header") Size + td(class="monospace") + span #{result.getblock.size.toLocaleString()} bytes + tr td(class="properties-header") Confirmations td(class="monospace") if (result.getblock.confirmations < 6) strong(class="text-warning") #{result.getblock.confirmations} else - strong(class="text-success") #{result.getblock.confirmations.toLocaleString()} + strong(class="text-success font-weight-bold") #{result.getblock.confirmations.toLocaleString()} div(class="col-md-6") @@ -110,10 +110,10 @@ div(class="tab-content") if (result.getblock.nextblockhash) a(href=("/block/" + result.getblock.nextblockhash)) #{result.getblock.nextblockhash} br - span(class="text-muted") ##{(result.getblock.height + 1).toLocaleString()} + span (##{(result.getblock.height + 1).toLocaleString()}) else span None - span(class="text-muted") (latest block) + span(class="text-muted") (latest block) tr - var scales = [ {val:1000000000000000, name:"quadrillion"}, {val:1000000000000, name:"trillion"}, {val:1000000000, name:"billion"}, {val:1000000, name:"million"} ]; @@ -192,7 +192,10 @@ div(class="tab-content") a(href=(paginationBaseUrl + "?limit=100"), class="btn btn-sm btn-primary px-2", class=(limit == 100 ? "active" : false)) 100 a(href=(paginationBaseUrl + "?limit=3000"), class="btn btn-sm btn-primary px-2", class=(limit >= txCount ? "active" : false)) all - + + - var fontawesomeInputName = "sign-in-alt"; + - var fontawesomeOutputName = "sign-out-alt"; + div(class="card-body") each tx, txIndex in result.transactions //pre @@ -212,100 +215,10 @@ div(class="tab-content") //pre // code #{JSON.stringify(result.txInputsByTransaction[tx.txid], null, 4)} if (true) - div(class="row") - div(class="col-md-6") - //h6 Input (#{tx.vin.length.toLocaleString()}) - if (result.txInputsByTransaction[tx.txid]) - - var totalInputValue = new Decimal(0); - table(class="table mb-0") - if (tx.vin[0].coinbase) - - totalInputValue = totalInputValue.plus(new Decimal(coinConfig.blockRewardFunction(result.getblock.height))); - tr - th 1 - td(class="border-top-0") - span(class="tag monospace") coinbase - span(class="monospace") Newly minted coins - td(class="border-top-0") - - var currencyValue = coinConfig.blockRewardFunction(result.getblock.height); - include ./value-display.pug - - each txInput, txInputIndex in result.txInputsByTransaction[tx.txid] - if (txInput) - - var vout = txInput.vout[tx.vin[txInputIndex].vout]; - - tr - th #{(txInputIndex + 1)} - - td(class=(txInputIndex == 0 ? "border-top-0" : false)) - if (vout.scriptPubKey && vout.scriptPubKey.addresses) - div(class="monospace", style="word-break: break-word;") - a(href=("/address/" + vout.scriptPubKey.addresses[0])) #{vout.scriptPubKey.addresses[0]} - - span(class="monospace small") via - a(href=("/tx/" + txInput.txid + "#output-" + tx.vin[txInputIndex].vout), class="monospace") tx:#{txInput.txid.substring(0, 20)}...[#{tx.vin[txInputIndex].vout}] - td(class=(txInputIndex == 0 ? "border-top-0" : false)) - if (vout.value) - - totalInputValue = totalInputValue.plus(new Decimal(vout.value)); - - - var currencyValue = vout.value; - include ./value-display.pug - - - var coinbaseCount = tx.vin[0].coinbase ? 1 : 0; - if ((tx.vin.length - coinbaseCount) > result.txInputsByTransaction[tx.txid].length) - tr - td - td - span(class="monospace text-muted") #{(tx.vin.length - result.txInputsByTransaction[tx.txid].length).toLocaleString()} more... - td - else - tr - th - td - td - strong - - var currencyValue = totalInputValue; - include ./value-display.pug - - - div(class="col-md-6") - //h6 Output (#{tx.vout.length.toLocaleString()}) - - var totalOutputValue = new Decimal(0); - table(class="table mb-0") - tbody - each vout, voutIndex in tx.vout - tr - th #{(voutIndex + 1)} - td(class=(voutIndex == 0 ? "border-top-0" : false)) - if (vout.scriptPubKey) - if (vout.scriptPubKey.addresses) - a(id=("output-" + voutIndex), href=("/address/" + vout.scriptPubKey.addresses[0])) - div(class="monospace", style="word-break: break-word;") #{vout.scriptPubKey.addresses[0]} - - else if (vout.scriptPubKey.hex && vout.scriptPubKey.hex.startsWith('6a24aa21a9ed')) - span(class="monospace") Segregated Witness committment - a(href="https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#commitment-structure", data-toggle="tooltip", title="View developer docs", target="_blank") - i(class="fas fa-info-circle") - else if (vout.scriptPubKey.asm && vout.scriptPubKey.asm.startsWith('OP_RETURN ')) - span(class="monospace") OP_RETURN: - span(class="monospace text-muted") #{utils.hex2ascii(vout.scriptPubKey.asm.substring("OP_RETURN ".length))} - - else - span(class="monospace text-danger") Unable to decode output: - br - span(class="monospace") type=#{vout.scriptPubKey.type}, asm=#{vout.scriptPubKey.asm} - td(class=(voutIndex == 0 ? "border-top-0" : false)) - - var currencyValue = vout.value; - include ./value-display.pug - - - totalOutputValue = totalOutputValue.plus(vout.value); - - tr - th - td - td - strong - - var currencyValue = totalOutputValue; - include ./value-display.pug + - var txInputs = result.txInputsByTransaction[tx.txid]; + + include ./transaction-io-details.pug + //pre // code #{JSON.stringify(tx, null, 4)} diff --git a/views/includes/transaction-io-details.pug b/views/includes/transaction-io-details.pug new file mode 100644 index 0000000..c8ed5c8 --- /dev/null +++ b/views/includes/transaction-io-details.pug @@ -0,0 +1,97 @@ +- var fontawesomeInputName = "sign-in-alt"; +- var fontawesomeOutputName = "sign-out-alt"; + + +div(class="row") + div(class="col-md-6") + if (txInputs) + table(class="table mb-0") + if (tx.vin[0].coinbase) + tr + th(class="pl-0 pr-1 monospace") + a(data-toggle="tooltip", title="Input #1", style="white-space: nowrap;") + i(class=("fas fa-" + fontawesomeInputName + " mr-2")) + span 1 + + td(class="border-top-0") + span(class="tag monospace") coinbase + span(class="monospace") Newly minted coins + + td(class="border-top-0") + - var currencyValue = coinConfig.blockRewardFunction(result.getblock.height); + include ./value-display.pug + + each txInput, txInputIndex in txInputs + if (txInput) + - var vout = txInput.vout[tx.vin[txInputIndex].vout]; + + tr + th(class="pl-0 pr-1 monospace") + a(data-toggle="tooltip", title=("Input #" + (txInputIndex + 1)), style="white-space: nowrap;") + i(class=("fas fa-" + fontawesomeInputName + " mr-2")) + span #{(txInputIndex + 1)} + + //pre + // code #{JSON.stringify(txInput)} + + td(class=(txInputIndex == 0 ? "border-top-0" : false), class="pl-0") + if (vout.scriptPubKey && vout.scriptPubKey.addresses) + div(class="monospace", style="word-break: break-word;") + a(href=("/address/" + vout.scriptPubKey.addresses[0])) #{vout.scriptPubKey.addresses[0]} + span(class="small monospace") via + a(href=("/tx/" + txInput.txid + "#output-" + tx.vin[txInputIndex].vout), class="monospace") #{txInput.txid.substring(0, 20)}...[#{tx.vin[txInputIndex].vout}] + + td(class=(txInputIndex == 0 ? "border-top-0" : false), class="pl-0") + if (vout.value) + - var currencyValue = vout.value; + include ./value-display.pug + + tr + th + td + td + strong + - var currencyValue = totalInputValue; + include ./value-display.pug + + + div(class="col-md-6") + table(class="table mb-0") + tbody + each vout, voutIndex in tx.vout + tr + th(class="pl-0 pr-1 monospace") + a(data-toggle="tooltip", title=("Output #" + (voutIndex + 1)), style="white-space: nowrap;") + i(class=("fas fa-" + fontawesomeOutputName + " mr-2")) + span #{(voutIndex + 1)} + + td(class=(voutIndex == 0 ? "border-top-0" : false), class="pl-0") + if (vout.scriptPubKey) + if (vout.scriptPubKey.addresses) + a(id=("output-" + voutIndex), href=("/address/" + vout.scriptPubKey.addresses[0])) + div(class="monospace", style="word-break: break-word;") #{vout.scriptPubKey.addresses[0]} + + else if (vout.scriptPubKey.hex && vout.scriptPubKey.hex.startsWith('6a24aa21a9ed')) + span(class="monospace") Segregated Witness committment + a(href="https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#commitment-structure", data-toggle="tooltip", title="View developer docs", target="_blank") + i(class="fas fa-info-circle") + else if (vout.scriptPubKey.asm && vout.scriptPubKey.asm.startsWith('OP_RETURN ')) + span(class="monospace") OP_RETURN: + span(class="monospace text-muted") #{utils.hex2ascii(vout.scriptPubKey.asm.substring("OP_RETURN ".length))} + else + span(class="monospace text-danger") Unable to decode output: + br + span(class="monospace") type=#{vout.scriptPubKey.type}, asm=#{vout.scriptPubKey.asm} + td(class=(voutIndex == 0 ? "border-top-0" : false), class="pl-0") + - var currencyValue = vout.value; + include ./value-display.pug + + tr + th + td + td + strong + - var currencyValue = totalOutputValue; + include ./value-display.pug + + diff --git a/views/transaction.pug b/views/transaction.pug index fb00331..e048248 100644 --- a/views/transaction.pug +++ b/views/transaction.pug @@ -76,7 +76,7 @@ block content a(href=("/block/" + result.getrawtransaction.blockhash)) #{result.getrawtransaction.blockhash} if (result.getblock.height) br - span(class="text-muted") (#{result.getblock.height.toLocaleString()}) + span (##{result.getblock.height.toLocaleString()}) else span N/A span(class="text-muted") (unconfirmed) @@ -149,9 +149,26 @@ block content td(class="text-danger") - var currencyValue = new Decimal(blockRewardMax).minus(totalOutputValue); include includes/value-display.pug - + a(class="ml-2", data-toggle="tooltip", title="The miner of this block failed to collect this value. As a result, it is lost.") i(class="fas fa-info-circle") + + tr + - var minerInfo = utils.getMinerFromCoinbaseTx(result.getrawtransaction); + + td(class="properties-header") Miner + td + if (minerInfo) + span #{minerInfo.name} + if (minerInfo.identifiedBy) + span(data-toggle="tooltip", title=("Identified by: " + minerInfo.identifiedBy)) + i(class="fas fa-info-circle") + else + span ? + span(data-toggle="tooltip", title="Unable to identify miner") + i(class="fas fa-info-circle") + + else tr td(class="properties-header") Fee Paid @@ -178,9 +195,6 @@ block content div(style="background-color: #f0f0f0; padding: 5px 10px;", class="mb-3") span(class="monospace word-wrap") #{utils.hex2ascii(result.getrawtransaction.vin[0].coinbase)} - - var fontawesomeInputName = "arrow-down"; - - var fontawesomeOutputName = "arrow-up"; - div(class="card mb-3") div(class="card-header") h2(class="h6 mb-0") @@ -200,133 +214,66 @@ block content div(class="card-body") - div(class="row") - div(class="col-md-6") - if (result.txInputs) - table(class="table mb-0") - if (result.getrawtransaction.vin[0].coinbase) - tr - th - a(data-toggle="tooltip", title="Input #1") - i(class=("fas fa-" + fontawesomeInputName + " mr-2")) - span 1 - td(class="border-top-0") - span(class="tag monospace") coinbase - span(class="monospace") Newly minted coins - td(class="border-top-0") - - var currencyValue = coinConfig.blockRewardFunction(result.getblock.height); - include includes/value-display.pug - - each txInput, txInputIndex in result.txInputs - if (txInput) - - var vout = txInput.vout[result.getrawtransaction.vin[txInputIndex].vout]; - - tr - th - a(data-toggle="tooltip", title=("Input #" + (txInputIndex + 1))) - i(class=("fas fa-" + fontawesomeInputName + " mr-2")) - span #{(txInputIndex + 1)} - - //pre - // code #{JSON.stringify(txInput)} - - td(class=(txInputIndex == 0 ? "border-top-0" : false)) - if (vout.scriptPubKey && vout.scriptPubKey.addresses) - div(class="monospace", style="word-break: break-word;") - a(href=("/address/" + vout.scriptPubKey.addresses[0])) #{vout.scriptPubKey.addresses[0]} - span(class="small monospace") via - a(href=("/tx/" + txInput.txid + "#output-" + result.getrawtransaction.vin[txInputIndex].vout), class="monospace") #{txInput.txid.substring(0, 20)}...[#{result.getrawtransaction.vin[txInputIndex].vout}] - td(class=(txInputIndex == 0 ? "border-top-0" : false)) - if (vout.value) - - var currencyValue = vout.value; - include includes/value-display.pug - - tr - th - td - td - strong - - var currencyValue = totalInputValue; - include includes/value-display.pug - - - div(class="col-md-6") - table(class="table mb-0") - tbody - each vout, voutIndex in result.getrawtransaction.vout - tr - th - a(data-toggle="tooltip", title=("Output #" + (voutIndex + 1))) - i(class=("fas fa-" + fontawesomeOutputName + " mr-2")) - span #{(voutIndex + 1)} - td(class=(voutIndex == 0 ? "border-top-0" : false)) - if (vout.scriptPubKey) - if (vout.scriptPubKey.addresses) - a(id=("output-" + voutIndex), href=("/address/" + vout.scriptPubKey.addresses[0])) - div(class="monospace", style="word-break: break-word;") #{vout.scriptPubKey.addresses[0]} - - else if (vout.scriptPubKey.hex && vout.scriptPubKey.hex.startsWith('6a24aa21a9ed')) - span(class="monospace") Segregated Witness committment - a(href="https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#commitment-structure", data-toggle="tooltip", title="View developer docs", target="_blank") - i(class="fas fa-info-circle") - else if (vout.scriptPubKey.asm && vout.scriptPubKey.asm.startsWith('OP_RETURN ')) - span(class="monospace") OP_RETURN: - span(class="monospace text-muted") #{utils.hex2ascii(vout.scriptPubKey.asm.substring("OP_RETURN ".length))} - else - span(class="monospace text-danger") Unable to decode output: - br - span(class="monospace") type=#{vout.scriptPubKey.type}, asm=#{vout.scriptPubKey.asm} - td(class=(voutIndex == 0 ? "border-top-0" : false)) - - var currencyValue = vout.value; - include includes/value-display.pug - - tr - th - td - td - strong - - var currencyValue = totalOutputValue; - include includes/value-display.pug + - var tx = result.getrawtransaction; + - var txInputs = result.txInputs; + include includes/transaction-io-details.pug + + - var fontawesomeInputName = "sign-in-alt"; + - var fontawesomeOutputName = "sign-out-alt"; div(id="tab-scripts", class="tab-pane", role="tabpanel") - h3(class="h5") Input Scripts - table(class="table table-striped mb-5") - thead - tr - th(style="width: 50px;") - th Script Sig (asm) - tbody - each vin, vinIndex in result.getrawtransaction.vin - tr - th #{vinIndex + 1} - td - if (vin.scriptSig && vin.scriptSig.asm) - span(class="word-wrap monospace") #{vin.scriptSig.asm} - - else if (vin.coinbase) - div(style="line-height: 1.75em;") - span(class="tag") coinbase - br - span(class="word-wrap monospace") #{vin.coinbase} - br - span(class="word-wrap monospace text-muted") (decoded) #{utils.hex2ascii(vin.coinbase)} - - h3(class="h5") Output Scripts - table(class="table table-striped") - thead - tr - th(style="width: 50px;") - th Script Pub Key (asm) - tbody - each vout, voutIndex in result.getrawtransaction.vout - tr - th #{voutIndex + 1} - td - if (vout.scriptPubKey && vout.scriptPubKey.asm) - span(class="word-wrap monospace") #{vout.scriptPubKey.asm} - if (vout.scriptPubKey.asm.startsWith("OP_RETURN")) - br - span(class="word-wrap monospace text-muted") (decoded) #{utils.hex2ascii(vout.scriptPubKey.asm)} + div(class="card mb-3") + div(class="card-header") + span(class="h6") Input Scripts + div(class="card-body") + table(class="table table-striped mb-5") + thead + tr + th(style="width: 50px;") + th Script Sig (asm) + tbody + each vin, vinIndex in result.getrawtransaction.vin + tr + th(class="pl-0") + a(data-toggle="tooltip", title=("Input #" + (vinIndex + 1)), style="white-space: nowrap;") + i(class=("fas fa-" + fontawesomeInputName + " mr-2")) + span #{(vinIndex + 1)} + + td + if (vin.scriptSig && vin.scriptSig.asm) + span(class="word-wrap monospace") #{vin.scriptSig.asm} + + else if (vin.coinbase) + div(style="line-height: 1.75em;") + span(class="tag") coinbase + br + span(class="word-wrap monospace") #{vin.coinbase} + br + span(class="word-wrap monospace text-muted") (decoded) #{utils.hex2ascii(vin.coinbase)} + + div(class="card mb-3") + div(class="card-header") + span(class="h6") Output Scripts + div(class="card-body") + table(class="table table-striped") + thead + tr + th(style="width: 50px;") + th Script Pub Key (asm) + tbody + each vout, voutIndex in result.getrawtransaction.vout + tr + th(class="pl-0") + a(data-toggle="tooltip", title=("Output #" + (voutIndex + 1)), style="white-space: nowrap;") + i(class=("fas fa-" + fontawesomeOutputName + " mr-2")) + span #{(voutIndex + 1)} + + td + if (vout.scriptPubKey && vout.scriptPubKey.asm) + span(class="word-wrap monospace") #{vout.scriptPubKey.asm} + if (vout.scriptPubKey.asm.startsWith("OP_RETURN")) + br + span(class="word-wrap monospace text-muted") (decoded) #{utils.hex2ascii(vout.scriptPubKey.asm)} div(id="tab-raw", class="tab-pane", role="tabpanel") div(class="highlight")