Add new settings to save+display multi-algo data

-New settings allow reading of the hash algorithm used to mine a particular block for coins that support this feature and have the algorithm data stored in the raw block data
-An "Algorithm" column has been added to the block page and main transaction homepage when multi-algo data is enabled
-The /ext/getlasttxs api will now return the hash algorithm if reading of the multi-algo data is enabled
This commit is contained in:
Joe Uhren
2024-02-06 19:44:11 -07:00
parent 860209a5f9
commit d86beee960
9 changed files with 79 additions and 20 deletions
+1 -1
View File
@@ -136,7 +136,7 @@ Table of Contents
- **getmasternoderewardstotal:** Returns the total number of coins earned in masternode rewards for a specific address that arrived after a specific block height *\*only applicable to masternode coins* - **getmasternoderewardstotal:** Returns the total number of coins earned in masternode rewards for a specific address that arrived after a specific block height *\*only applicable to masternode coins*
- **Claim Address:** Allows anyone to set custom display names for wallet addresses that they own using the **Sign Message** feature from their local wallet. Includes *bad word* filter support. - **Claim Address:** Allows anyone to set custom display names for wallet addresses that they own using the **Sign Message** feature from their local wallet. Includes *bad word* filter support.
- **Orphaned Blocks:** Displays a list of orphaned blocks with links to the next and previous "good" blocks - **Orphaned Blocks:** Displays a list of orphaned blocks with links to the next and previous "good" blocks
- **Block Info:** Displays block summary and list of transactions for a specific block height - **Block Info:** Displays block summary and list of transactions for a specific block height along with optional hash algorithm for multi-algo coins
- **Transaction Info:** Displays transaction summary, optional OP_RETURN value, list of input addresses and output addresses for a specific transaction - **Transaction Info:** Displays transaction summary, optional OP_RETURN value, list of input addresses and output addresses for a specific transaction
- **Address Info:** Displays wallet address summary (balance, total sent, total received, QR code) and a list of latest transactions for a specific wallet address - **Address Info:** Displays wallet address summary (balance, total sent, total received, QR code) and a list of latest transactions for a specific wallet address
- Choose from 26 built-in themes with tweakable settings such as light and dark options to customize the look and feel of the explorer: - Choose from 26 built-in themes with tweakable settings such as light and dark options to customize the look and feel of the explorer:
+27 -7
View File
@@ -590,10 +590,13 @@ module.exports = {
if (tx) { if (tx) {
// collection has data // collection has data
// determine if tx_type field exists // determine if tx_type field exists
check_add_db_field(Tx, 'tx_type', null, function(exists) { check_add_db_field(Tx, 'tx_type', null, function() {
// determine if op_return field exists // determine if op_return field exists
check_add_db_field(Tx, 'op_return', null, function(exists) { check_add_db_field(Tx, 'op_return', null, function() {
return cb(true); // determine if algo field exists
check_add_db_field(Tx, 'algo', null, function() {
return cb(true);
});
}); });
}); });
} else } else
@@ -882,16 +885,24 @@ module.exports = {
row.push((txs[i].total / 100000000)); row.push((txs[i].total / 100000000));
row.push(txs[i].timestamp); row.push(txs[i].timestamp);
if (settings.block_page.multi_algorithm.show_algo == true)
row.push('algo:' + (txs[i].algo == null ? '' : txs[i].algo));
data.push(row); data.push(row);
} else { } else {
data.push({ let data_entry = {
blockindex: txs[i].blockindex, blockindex: txs[i].blockindex,
blockhash: txs[i].blockhash, blockhash: txs[i].blockhash,
txid: txs[i].txid, txid: txs[i].txid,
recipients: txs[i].vout.length, recipients: txs[i].vout.length,
amount: (txs[i].total / 100000000), amount: (txs[i].total / 100000000),
timestamp: txs[i].timestamp timestamp: txs[i].timestamp
}); };
if (settings.block_page.multi_algorithm.show_algo == true)
data_entry.algo = (txs[i].algo == null ? '' : txs[i].algo);
data.push(data_entry);
} }
} }
@@ -1931,7 +1942,7 @@ module.exports = {
} }
}, },
save_tx: function(txid, blockheight, cb) { save_tx: function(txid, blockheight, block, cb) {
lib.get_rawtransaction(txid, function(tx) { lib.get_rawtransaction(txid, function(tx) {
if (tx && tx != 'There was an error. Check your console.') { if (tx && tx != 'There was an error. Check your console.') {
lib.prepare_vin(tx, function(vin, tx_type_vin) { lib.prepare_vin(tx, function(vin, tx_type_vin) {
@@ -1967,6 +1978,8 @@ module.exports = {
}, function() { }, function() {
lib.calculate_total(vout, function(total) { lib.calculate_total(vout, function(total) {
var op_return = null; var op_return = null;
var algo = null;
// check if the op_return value should be decoded and saved // check if the op_return value should be decoded and saved
if (settings.transaction_page.show_op_return) { if (settings.transaction_page.show_op_return) {
// loop through vout to find the op_return value // loop through vout to find the op_return value
@@ -1979,6 +1992,12 @@ module.exports = {
}); });
} }
// check if the algo value should be saved
if (settings.block_page.multi_algorithm.show_algo) {
// get the algo value
algo = block[settings.block_page.multi_algorithm.key_name];
}
var newTx = new Tx({ var newTx = new Tx({
txid: tx.txid, txid: tx.txid,
vin: (vin == null || vin.length == 0 ? [] : nvin), vin: (vin == null || vin.length == 0 ? [] : nvin),
@@ -1988,7 +2007,8 @@ module.exports = {
blockhash: tx.blockhash, blockhash: tx.blockhash,
blockindex: blockheight, blockindex: blockheight,
tx_type: (tx_type_vout == null ? tx_type_vin : tx_type_vout), tx_type: (tx_type_vout == null ? tx_type_vin : tx_type_vout),
op_return: op_return op_return: op_return,
algo: algo
}); });
newTx.save().then(() => { newTx.save().then(() => {
+12 -1
View File
@@ -498,7 +498,18 @@ exports.block_page = {
// genesis_block: Your coins genesis block hash is used to determine the beginning of the blockchain // genesis_block: Your coins genesis block hash is used to determine the beginning of the blockchain
// For many bitcoin clones you can use the following cmd to get the block hash of the genesis block: coin-cli getblockhash 0 // For many bitcoin clones you can use the following cmd to get the block hash of the genesis block: coin-cli getblockhash 0
// NOTE: If this value is not entered correctly it will not be possible for the explorer to find or navigate to the genesis block, neither via block or transaction hash // NOTE: If this value is not entered correctly it will not be possible for the explorer to find or navigate to the genesis block, neither via block or transaction hash
"genesis_block": "00014f36c648cdbc750f7dd28487a23cd9e0b0f95f5fccc5b5d01367e3f57469" "genesis_block": "00014f36c648cdbc750f7dd28487a23cd9e0b0f95f5fccc5b5d01367e3f57469",
// multi_algorithm: a collection of settings that can be used to show a new column with the hash algorithm that was used to mine a particular block for multi-algo coins
// If enabled, a new column will be displayed on the block page and main transaction homepage that displays the hash algorithm used to mine a particular block or tx
// NOTE: Changing any of the options in this section will require a full reindex of the blockchain data before previously synced blocks can display the algorithm
"multi_algorithm": {
// show_algo: Determine whether to read and display the hash algorithm that was used to mine a particular block for multi-algo coins
// NOTE: Enabling this option will require a full reindex of the blockchain data before previously synced blocks can display the algorithm
"show_algo": false,
// key_name: The name of the key or identifier in the raw block data that determines which hash algorithm was used to mine a particular block
// NOTE: Changing this option will require a full reindex of the blockchain data before previously synced blocks can display the algorithm
"key_name": "pow_algo"
}
}; };
// transaction_page: a collection of settings that pertain to the transaction/tx page // transaction_page: a collection of settings that pertain to the transaction/tx page
+2 -1
View File
@@ -10,7 +10,8 @@ var TxSchema = new Schema({
blockhash: { type: String, index: true }, blockhash: { type: String, index: true },
blockindex: {type: Number, default: 0, index: true}, blockindex: {type: Number, default: 0, index: true},
tx_type: { type: String, default: null }, tx_type: { type: String, default: null },
op_return: { type: String, default: null } op_return: { type: String, default: null },
algo: { type: String, default: null }
}, {id: false}); }, {id: false});
TxSchema.index({total: 1, total: -1, blockindex: 1, blockindex: -1}); TxSchema.index({total: 1, total: -1, blockindex: 1, blockindex: -1});
+1 -1
View File
@@ -66,7 +66,7 @@ mongoose.connect(dbString).then(() => {
next_tx(); next_tx();
}, timeout); }, timeout);
} else { } else {
db.save_tx(txid, block_height, function(err, tx_has_vout) { db.save_tx(txid, block_height, block, function(err, tx_has_vout) {
if (err) if (err)
console.log(err); console.log(err);
else else
+2 -2
View File
@@ -120,7 +120,7 @@ function update_tx_db(coin, start, end, txes, timeout, check_only, cb) {
// check if this tx should be added to the local database // check if this tx should be added to the local database
if (tx_deleted || !tx) { if (tx_deleted || !tx) {
// save the transaction to local database // save the transaction to local database
db.save_tx(txid, block_height, function(err, tx_has_vout) { db.save_tx(txid, block_height, block, function(err, tx_has_vout) {
if (err) if (err)
console.log(err); console.log(err);
else else
@@ -673,7 +673,7 @@ function check_add_tx(txid, blockhash, tx_count, cb) {
// check if the block was found // check if the block was found
if (block) { if (block) {
// save the tx to the local database // save the tx to the local database
db.save_tx(txid, block.height, function(save_tx_err, tx_has_vout) { db.save_tx(txid, block.height, block, function(save_tx_err, tx_has_vout) {
// check if there were any save errors // check if there were any save errors
if (save_tx_err) if (save_tx_err)
console.log(save_tx_err); console.log(save_tx_err);
+12 -1
View File
@@ -582,7 +582,18 @@
// genesis_block: Your coins genesis block hash is used to determine the beginning of the blockchain // genesis_block: Your coins genesis block hash is used to determine the beginning of the blockchain
// For many bitcoin clones you can use the following cmd to get the block hash of the genesis block: coin-cli getblockhash 0 // For many bitcoin clones you can use the following cmd to get the block hash of the genesis block: coin-cli getblockhash 0
// NOTE: If this value is not entered correctly it will not be possible for the explorer to find or navigate to the genesis block, neither via block or transaction hash // NOTE: If this value is not entered correctly it will not be possible for the explorer to find or navigate to the genesis block, neither via block or transaction hash
"genesis_block": "00014f36c648cdbc750f7dd28487a23cd9e0b0f95f5fccc5b5d01367e3f57469" "genesis_block": "00014f36c648cdbc750f7dd28487a23cd9e0b0f95f5fccc5b5d01367e3f57469",
// multi_algorithm: a collection of settings that can be used to show a new column with the hash algorithm that was used to mine a particular block for multi-algo coins
// If enabled, a new column will be displayed on the block page and main transaction homepage that displays the hash algorithm used to mine a particular block or tx
// NOTE: Changing any of the options in this section will require a full reindex of the blockchain data before previously synced blocks can display the algorithm
"multi_algorithm": {
// show_algo: Determine whether to read and display the hash algorithm that was used to mine a particular block for multi-algo coins
// NOTE: Enabling this option will require a full reindex of the blockchain data before previously synced blocks can display the algorithm
"show_algo": false,
// key_name: The name of the key or identifier in the raw block data that determines which hash algorithm was used to mine a particular block
// NOTE: Changing this option will require a full reindex of the blockchain data before previously synced blocks can display the algorithm
"key_name": "pow_algo"
}
}, },
// transaction_page: a collection of settings that pertain to the transaction/tx page // transaction_page: a collection of settings that pertain to the transaction/tx page
+4
View File
@@ -75,6 +75,8 @@ block content
tr(class=theadClasses) tr(class=theadClasses)
th.text-center #{settings.locale.height} th.text-center #{settings.locale.height}
th.text-center #{settings.locale.difficulty} th.text-center #{settings.locale.difficulty}
if settings.block_page.multi_algorithm.show_algo == true
th.text-center='Algorithm'
th.text-center #{settings.locale.confirmations} th.text-center #{settings.locale.confirmations}
if settings.blockchain_specific.heavycoin.enabled == true if settings.blockchain_specific.heavycoin.enabled == true
th.text-center Vote th.text-center Vote
@@ -91,6 +93,8 @@ block content
td.text-center=block.height td.text-center=block.height
td.text-center #{splitDifficulty[0]}. td.text-center #{splitDifficulty[0]}.
span.decimal #{splitDifficulty[1]} span.decimal #{splitDifficulty[1]}
if settings.block_page.multi_algorithm.show_algo == true
td.text-center=block[settings.block_page.multi_algorithm.key_name]
if block.confirmations >= confirmations if block.confirmations >= confirmations
td.text-center.table-success=block.confirmations td.text-center.table-success=block.confirmations
else if block.confirmations < (confirmations / 2) else if block.confirmations < (confirmations / 2)
+18 -6
View File
@@ -61,20 +61,30 @@ block content
} }
}, },
rowCallback: function(row, data, index) { rowCallback: function(row, data, index) {
var blockindex = data[0]; //variables for better readability // variables for better readability
var blockhash = data[1]; //variables for better readability var blockindex = data[0];
var txhash = data[2]; //variables for better readability var blockhash = data[1];
var outputs = data[3]; //variables for better readability var txhash = data[2];
var amount = Number(data[4]).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); //variables for better readability var outputs = data[3];
var amount = Number(data[4]).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
var amountParts = amount.split('.'); var amountParts = amount.split('.');
var amount = amountParts[0] + '.<span class="decimal">' + amountParts[1] + '</span>'; var amount = amountParts[0] + '.<span class="decimal">' + amountParts[1] + '</span>';
var timestamp = data[5]; var timestamp = data[5];
var offset = 0;
$("td:eq(0)", row).html('<a href="/tx/' + txhash + '"><span class="fa-regular fa-eye" data-bs-toggle="tooltip" data-bs-placement="top" title="#{settings.locale.view_tx}"></span></a>').addClass('text-center d-table-cell d-md-none'); $("td:eq(0)", row).html('<a href="/tx/' + txhash + '"><span class="fa-regular fa-eye" data-bs-toggle="tooltip" data-bs-placement="top" title="#{settings.locale.view_tx}"></span></a>').addClass('text-center d-table-cell d-md-none');
$("td:eq(1)", row).html('<a href="/block/' + blockhash + '">' + blockindex + '</a>'); $("td:eq(1)", row).html('<a href="/block/' + blockhash + '">' + blockindex + '</a>');
$("td:eq(2)", row).html('<a href="/tx/' + txhash + '">' + txhash + '</a>').addClass("text-center breakWord d-none d-md-table-cell"); $("td:eq(2)", row).html('<a href="/tx/' + txhash + '">' + txhash + '</a>').addClass("text-center breakWord d-none d-md-table-cell");
$("td:eq(3)", row).html(outputs).addClass("text-center d-none d-sm-table-cell"); $("td:eq(3)", row).html(outputs).addClass("text-center d-none d-sm-table-cell");
$("td:eq(4)", row).html(amount); $("td:eq(4)", row).html(amount);
$("td:eq(5)", row).html('<span' + (#{settings.shared_pages.date_time.enable_alt_timezone_tooltips} == true ? ' data-bs-toggle="tooltip" data-bs-placement="auto" title="' + format_unixtime(timestamp, true) + '"' : '') + '>' + format_unixtime(timestamp) + '</span>').addClass('text-center');
if (#{settings.block_page.multi_algorithm.show_algo} == true) {
var algo = (data.length > 6 && data[6].indexOf('algo:') == 0 ? data[6].substring('algo:'.length) : '');
$("td:eq(5)", row).html(algo);
offset = 1;
}
$("td:eq(" + (5 + offset) + ")", row).html('<span' + (#{settings.shared_pages.date_time.enable_alt_timezone_tooltips} == true ? ' data-bs-toggle="tooltip" data-bs-placement="auto" title="' + format_unixtime(timestamp, true) + '"' : '') + '>' + format_unixtime(timestamp) + '</span>').addClass('text-center');
}, },
fnDrawCallback: function(settings) { fnDrawCallback: function(settings) {
fixDataTableColumns(); fixDataTableColumns();
@@ -169,5 +179,7 @@ block content
th.text-center.d-none.d-sm-table-cell #{settings.locale.tx_recipients} th.text-center.d-none.d-sm-table-cell #{settings.locale.tx_recipients}
th.text-center #{settings.locale.mkt_amount} th.text-center #{settings.locale.mkt_amount}
span.small.fw-normal (#{settings.coin.symbol}) span.small.fw-normal (#{settings.coin.symbol})
if settings.block_page.multi_algorithm.show_algo == true
th.text-center="Algorithm"
th.text-center #{settings.locale.timestamp} th.text-center #{settings.locale.timestamp}
tbody.text-center tbody.text-center