SC CODE: Function InitializePrivate() Uint64
10 IF init() == 0 THEN GOTO 30
20 RETURN 1
30 STORE("var_header_name", "blocks.js")
31 STORE("var_header_description", "")
32 STORE("var_header_icon", "")
33 STORE("dURL", "")
34 STORE("docType", "TELA-JS-1")
35 STORE("subDir", "/")
36 STORE("fileCheckC", "015473bf20e8401305617accca7382da05d4ed2ce579c195d80e871df7713024")
37 STORE("fileCheckS", "05185a6b7e944490953e29baab8450774e697ffffbd045790252e02d991a5974")
100 RETURN 0
End Function
Function init() Uint64
10 IF EXISTS("owner") == 0 THEN GOTO 30
20 RETURN 1
30 STORE("owner", address())
50 STORE("docVersion", "1.0.0")
60 STORE("hash", HEX(TXID()))
70 STORE("likes", 0)
80 STORE("dislikes", 0)
100 RETURN 0
End Function
Function address() String
10 DIM s as String
20 LET s = SIGNER()
30 IF IS_ADDRESS_VALID(s) THEN GOTO 50
40 RETURN "anon"
50 RETURN ADDRESS_STRING(s)
End Function
Function Rate(r Uint64) Uint64
10 DIM addr as String
15 LET addr = address()
16 IF r < 100 && EXISTS(addr) == 0 && addr != "anon" THEN GOTO 30
20 RETURN 1
30 STORE(addr, ""+r+"_"+BLOCK_HEIGHT())
40 IF r < 50 THEN GOTO 70
50 STORE("likes", LOAD("likes")+1)
60 RETURN 0
70 STORE("dislikes", LOAD("dislikes")+1)
100 RETURN 0
End Function
/*
// DERO Explorer v2.0 - Blocks Module
const module = (function() {
'use strict';
var D = window.DeroExplorer, S = D.state, U = D.utils, ui = D.ui, R = D.router, M = D.modules;
var B = { page: 0, perPage: 15, total: 0, loading: false, cache: new Map(), maxCache: 100 };
function init() {
window.addEventListener('explorer:viewChange', handleView);
window.addEventListener('explorer:connected', function() { if (S.currentView === 'dashboard') loadRecent(); });
window.addEventListener('explorer:newBlock', handleNew);
}
function handleView(e) {
var v = e.detail.view, p = e.detail.param;
if (v === 'blocks') renderList();
else if (v === 'blockDetail' && p) renderDetail(p);
else if (v === 'dashboard') loadRecent();
}
function handleNew(e) {
if (S.currentView === 'dashboard' || (S.currentView === 'blocks' && B.page === 0)) loadRecent();
}
async function renderList() {
var el = document.getElementById('view-blocks');
if (!el) return;
el.innerHTML = '<div class="section-card">' + ui.sectionHeader({ icon: '[B]', title: 'All Blocks', badge: { text: 'LIVE', class: 'badge-live' } }) +
'<div class="section-content"><div class="data-table"><div class="table-header table-header-blocks"><span>Height</span><span>Hash</span><span>Age</span><span>TXs</span><span>Reward</span></div>' +
'<div id="blocks-table-body"><div class="loading-state"><div class="loading-spinner"></div><span>Loading blocks...</span></div></div></div><div id="blocks-pagination"></div></div></div>';
await loadPage(0);
}
async function loadPage(page) {
if (B.loading) return;
B.loading = true;
var body = document.getElementById('blocks-table-body');
if (!body) return;
try {
var conn = M.get('connectivity');
if (!conn) throw new Error('No connectivity');
var info = await conn.getNetworkInfo();
B.total = info.topoheight;
B.page = page;
var start = info.topoheight - (page * B.perPage);
var blocks = await fetchRange(start, B.perPage, conn);
body.innerHTML = renderRows(blocks);
renderPagination();
} catch (e) {
body.innerHTML = '<div class="empty-state"><div class="empty-icon">!</div><p>Failed to load blocks</p></div>';
} finally { B.loading = false; }
}
async function fetchRange(start, count, conn) {
var blocks = [], promises = [];
for (var i = 0; i < count && start - i > 0; i++) {
var h = start - i;
if (B.cache.has(h)) blocks[i] = B.cache.get(h);
else {
(function(idx, height) {
promises.push(conn.getBlock(height).then(function(b) { cacheBlock(height, b); blocks[idx] = b; }).catch(function() { blocks[idx] = null; }));
})(i, h);
}
}
await Promise.all(promises);
return blocks.filter(function(b) { return b !== null; });
}
function cacheBlock(h, b) {
if (B.cache.size >= B.maxCache) B.cache.delete(B.cache.keys().next().value);
B.cache.set(h, b);
}
function renderRows(blocks) {
if (!blocks.length) return '<div class="empty-state"><p>No blocks found</p></div>';
return blocks.map(function(b) {
var hdr = b.block_header, txs = (b.txs?.length || 0) + 1;
return '<div class="table-row table-row-blocks" onclick="viewBlock(' + hdr.height + ')"><span class="col-height">' + U.fmtNum(hdr.height) + '</span><span class="col-hash mono">' + hdr.hash + '</span><span class="col-age">' + U.fmtAge(hdr.timestamp) + '</span><span class="col-txs">' + txs + '</span><span class="col-reward">' + U.fmtDERO(hdr.reward, 2) + '</span></div>';
}).join('');
}
function renderPagination() {
var el = document.getElementById('blocks-pagination');
if (!el) return;
var total = Math.ceil(B.total / B.perPage);
el.innerHTML = '<div class="pagination"><button class="page-btn" ' + (B.page === 0 ? 'disabled' : '') + ' onclick="DeroExplorer.modules.get(\'blocks\').goToPage(' + (B.page - 1) + ')">< Prev</button><span class="page-info">Page ' + (B.page + 1) + ' of ' + U.fmtNum(total) + '</span><button class="page-btn" ' + (B.page >= total - 1 ? 'disabled' : '') + ' onclick="DeroExplorer.modules.get(\'blocks\').goToPage(' + (B.page + 1) + ')">Next ></button></div>';
}
function goToPage(p) { if (p >= 0) loadPage(p); }
async function loadRecent() {
var el = document.getElementById('blocks-list');
if (!el) return;
try {
var conn = M.get('connectivity');
if (!conn) throw new Error('No connectivity');
var info = await conn.getNetworkInfo();
S.networkInfo = info;
updateStats(info);
var blocks = await fetchRange(info.topoheight, 10, conn);
el.innerHTML = renderRows(blocks);
var upd = document.getElementById('last-update');
if (upd) upd.textContent = new Date().toLocaleTimeString();
} catch (e) { el.innerHTML = '<div class="empty-state"><p>Failed to load recent blocks</p></div>'; }
}
function updateStats(info) {
var u = { 'stat-height': U.fmtNum(info.topoheight), 'stat-hashrate': U.fmtHashrate(info.hashrate), 'stat-difficulty': U.fmtCompact(info.difficulty), 'stat-supply': U.fmtNum(info.totalSupply) + ' DERO' };
for (var id in u) { var el = document.getElementById(id); if (el) el.textContent = u[id]; }
}
async function renderDetail(h) {
var el = document.getElementById('view-blockDetail');
if (!el) { var main = document.getElementById('main-content'); el = document.createElement('div'); el.id = 'view-blockDetail'; main.appendChild(el); }
el.classList.remove('hidden');
ui.showLoading(el, 'Loading block...');
try {
var conn = M.get('connectivity'), height = parseInt(h), block;
if (conn.hasEnhancedFeatures()) block = await conn.getBlockDetails(height);
else block = await conn.getBlock(height);
if (!block) throw new Error('Block not found');
el.innerHTML = renderDetailHTML(block);
} catch (e) { ui.showError(el, 'Block Not Found', e.message); }
}
function extractMinerAddress(b) {
// Try multiple possible locations for miner address
if (b.miner_address) return b.miner_address;
if (b.block_header?.miner_address) return b.block_header.miner_address;
if (b.block_header?.miners && Array.isArray(b.block_header.miners) && b.block_header.miners.length > 0) {
return b.block_header.miners[0];
}
if (b.miners && Array.isArray(b.miners) && b.miners.length > 0) {
return b.miners[0];
}
// Try to extract from miner_tx if available (for future enhancement)
if (b.miner_tx?.destinations && Array.isArray(b.miner_tx.destinations) && b.miner_tx.destinations.length > 0) {
var dest = b.miner_tx.destinations[0];
if (dest.address) return dest.address;
}
return null;
}
function renderDetailHTML(b) {
var hdr = b.block_header, txs = (b.txs?.length || 0) + 1;
var minerAddr = extractMinerAddress(b);
return '<div class="detail-view"><div class="detail-nav"><button class="btn btn-ghost" onclick="goBack()">< Back</button><div class="detail-nav-arrows">' +
(hdr.height > 1 ? '<button class="btn btn-ghost" onclick="viewBlock(' + (hdr.height - 1) + ')">< Block ' + U.fmtNum(hdr.height - 1) + '</button>' : '') +
'<button class="btn btn-ghost" onclick="viewBlock(' + (hdr.height + 1) + ')">Block ' + U.fmtNum(hdr.height + 1) + ' ></button></div></div>' +
'<div class="section-card">' + ui.sectionHeader({ icon: '[B]', title: 'Block ' + U.fmtNum(hdr.height), meta: U.fmtAge(hdr.timestamp) }) +
'<div class="section-content"><div class="detail-grid"><div class="detail-column"><h4 class="detail-subtitle">Block Information</h4>' +
ui.detailRow('Height', U.fmtNum(hdr.height)) + ui.detailRow('Topoheight', U.fmtNum(hdr.topoheight)) +
ui.detailRow('Timestamp', U.fmtLocalTime(hdr.timestamp)) + ui.detailRow('Age', U.fmtAge(hdr.timestamp)) +
ui.detailRow('Hash', hdr.hash, { mono: true, copyable: true }) +
(hdr.tips?.[0] ? ui.detailRow('Previous', U.truncHash(hdr.tips[0], 12, 8), { mono: true }) : '') +
'</div><div class="detail-column"><h4 class="detail-subtitle">Mining Information</h4>' +
(minerAddr ? ui.detailRow('Miner', minerAddr, { mono: true }) : ui.detailRow('Miner', '<span class="text-muted">Not available</span>')) +
ui.detailRow('Reward', U.fmtDERO(hdr.reward) + ' DERO') + ui.detailRow('Difficulty', U.fmtNum(hdr.difficulty)) +
ui.detailRow('Nonce', hdr.nonce) + ui.detailRow('Size', U.fmtBytes(hdr.block_size || hdr.block_weight)) +
ui.detailRow('Transactions', txs.toString()) + '</div></div></div></div>' +
'<div class="section-card">' + ui.sectionHeader({ icon: '[T]', title: 'Transactions (' + txs + ')', badge: { text: 'CONFIRMED', class: 'badge-ok' } }) +
'<div class="section-content">' + renderBlockTxs(b) + '</div></div></div>';
}
function renderBlockTxs(b) {
var hdr = b.block_header, txs = b.txs || [];
var html = '<div class="tx-list"><div class="tx-item tx-coinbase"><div class="tx-item-left"><span class="tx-type badge badge-ok">COINBASE</span><span class="tx-hash mono">' +
(b.miner_tx?.hash ? U.truncHash(b.miner_tx.hash) : 'Mining Reward') + '</span></div><div class="tx-item-right"><span class="tx-amount text-ok">+' + U.fmtDERO(hdr.reward) + ' DERO</span></div></div>';
txs.forEach(function(tx) {
html += '<div class="tx-item" onclick="viewTx(\'' + tx + '\')"><div class="tx-item-left"><span class="tx-type badge badge-pending">TX</span><span class="tx-hash mono">' + U.truncHash(tx, 16, 12) + '</span></div><div class="tx-item-right"><span class="tx-action">View ></span></div></div>';
});
if (txs.length === 0) html += '<div class="tx-item-empty"><span class="text-muted">No regular transactions in this block</span></div>';
return html + '</div>';
}
return { init: init, loadBlocksPage: loadPage, goToPage: goToPage, loadRecentBlocks: loadRecent, renderBlockDetail: renderDetail, getState: function() { return B; } };
})();
*/ |
| SC Arguments: [Name:SC_ACTION Type:uint64 Value:'1' Name:SC_CODE Type:string Value:'Function InitializePrivate() Uint64
10 IF init() == 0 THEN GOTO 30
20 RETURN 1
30 STORE("var_header_name", "blocks.js")
31 STORE("var_header_description", "")
32 STORE("var_header_icon", "")
33 STORE("dURL", "")
34 STORE("docType", "TELA-JS-1")
35 STORE("subDir", "/")
36 STORE("fileCheckC", "015473bf20e8401305617accca7382da05d4ed2ce579c195d80e871df7713024")
37 STORE("fileCheckS", "05185a6b7e944490953e29baab8450774e697ffffbd045790252e02d991a5974")
100 RETURN 0
End Function
Function init() Uint64
10 IF EXISTS("owner") == 0 THEN GOTO 30
20 RETURN 1
30 STORE("owner", address())
50 STORE("docVersion", "1.0.0")
60 STORE("hash", HEX(TXID()))
70 STORE("likes", 0)
80 STORE("dislikes", 0)
100 RETURN 0
End Function
Function address() String
10 DIM s as String
20 LET s = SIGNER()
30 IF IS_ADDRESS_VALID(s) THEN GOTO 50
40 RETURN "anon"
50 RETURN ADDRESS_STRING(s)
End Function
Function Rate(r Uint64) Uint64
10 DIM addr as String
15 LET addr = address()
16 IF r < 100 && EXISTS(addr) == 0 && addr != "anon" THEN GOTO 30
20 RETURN 1
30 STORE(addr, ""+r+"_"+BLOCK_HEIGHT())
40 IF r < 50 THEN GOTO 70
50 STORE("likes", LOAD("likes")+1)
60 RETURN 0
70 STORE("dislikes", LOAD("dislikes")+1)
100 RETURN 0
End Function
/*
// DERO Explorer v2.0 - Blocks Module
const module = (function() {
'use strict';
var D = window.DeroExplorer, S = D.state, U = D.utils, ui = D.ui, R = D.router, M = D.modules;
var B = { page: 0, perPage: 15, total: 0, loading: false, cache: new Map(), maxCache: 100 };
function init() {
window.addEventListener('explorer:viewChange', handleView);
window.addEventListener('explorer:connected', function() { if (S.currentView === 'dashboard') loadRecent(); });
window.addEventListener('explorer:newBlock', handleNew);
}
function handleView(e) {
var v = e.detail.view, p = e.detail.param;
if (v === 'blocks') renderList();
else if (v === 'blockDetail' && p) renderDetail(p);
else if (v === 'dashboard') loadRecent();
}
function handleNew(e) {
if (S.currentView === 'dashboard' || (S.currentView === 'blocks' && B.page === 0)) loadRecent();
}
async function renderList() {
var el = document.getElementById('view-blocks');
if (!el) return;
el.innerHTML = '<div class="section-card">' + ui.sectionHeader({ icon: '[B]', title: 'All Blocks', badge: { text: 'LIVE', class: 'badge-live' } }) +
'<div class="section-content"><div class="data-table"><div class="table-header table-header-blocks"><span>Height</span><span>Hash</span><span>Age</span><span>TXs</span><span>Reward</span></div>' +
'<div id="blocks-table-body"><div class="loading-state"><div class="loading-spinner"></div><span>Loading blocks...</span></div></div></div><div id="blocks-pagination"></div></div></div>';
await loadPage(0);
}
async function loadPage(page) {
if (B.loading) return;
B.loading = true;
var body = document.getElementById('blocks-table-body');
if (!body) return;
try {
var conn = M.get('connectivity');
if (!conn) throw new Error('No connectivity');
var info = await conn.getNetworkInfo();
B.total = info.topoheight;
B.page = page;
var start = info.topoheight - (page * B.perPage);
var blocks = await fetchRange(start, B.perPage, conn);
body.innerHTML = renderRows(blocks);
renderPagination();
} catch (e) {
body.innerHTML = '<div class="empty-state"><div class="empty-icon">!</div><p>Failed to load blocks</p></div>';
} finally { B.loading = false; }
}
async function fetchRange(start, count, conn) {
var blocks = [], promises = [];
for (var i = 0; i < count && start - i > 0; i++) {
var h = start - i;
if (B.cache.has(h)) blocks[i] = B.cache.get(h);
else {
(function(idx, height) {
promises.push(conn.getBlock(height).then(function(b) { cacheBlock(height, b); blocks[idx] = b; }).catch(function() { blocks[idx] = null; }));
})(i, h);
}
}
await Promise.all(promises);
return blocks.filter(function(b) { return b !== null; });
}
function cacheBlock(h, b) {
if (B.cache.size >= B.maxCache) B.cache.delete(B.cache.keys().next().value);
B.cache.set(h, b);
}
function renderRows(blocks) {
if (!blocks.length) return '<div class="empty-state"><p>No blocks found</p></div>';
return blocks.map(function(b) {
var hdr = b.block_header, txs = (b.txs?.length || 0) + 1;
return '<div class="table-row table-row-blocks" onclick="viewBlock(' + hdr.height + ')"><span class="col-height">' + U.fmtNum(hdr.height) + '</span><span class="col-hash mono">' + hdr.hash + '</span><span class="col-age">' + U.fmtAge(hdr.timestamp) + '</span><span class="col-txs">' + txs + '</span><span class="col-reward">' + U.fmtDERO(hdr.reward, 2) + '</span></div>';
}).join('');
}
function renderPagination() {
var el = document.getElementById('blocks-pagination');
if (!el) return;
var total = Math.ceil(B.total / B.perPage);
el.innerHTML = '<div class="pagination"><button class="page-btn" ' + (B.page === 0 ? 'disabled' : '') + ' onclick="DeroExplorer.modules.get(\'blocks\').goToPage(' + (B.page - 1) + ')">< Prev</button><span class="page-info">Page ' + (B.page + 1) + ' of ' + U.fmtNum(total) + '</span><button class="page-btn" ' + (B.page >= total - 1 ? 'disabled' : '') + ' onclick="DeroExplorer.modules.get(\'blocks\').goToPage(' + (B.page + 1) + ')">Next ></button></div>';
}
function goToPage(p) { if (p >= 0) loadPage(p); }
async function loadRecent() {
var el = document.getElementById('blocks-list');
if (!el) return;
try {
var conn = M.get('connectivity');
if (!conn) throw new Error('No connectivity');
var info = await conn.getNetworkInfo();
S.networkInfo = info;
updateStats(info);
var blocks = await fetchRange(info.topoheight, 10, conn);
el.innerHTML = renderRows(blocks);
var upd = document.getElementById('last-update');
if (upd) upd.textContent = new Date().toLocaleTimeString();
} catch (e) { el.innerHTML = '<div class="empty-state"><p>Failed to load recent blocks</p></div>'; }
}
function updateStats(info) {
var u = { 'stat-height': U.fmtNum(info.topoheight), 'stat-hashrate': U.fmtHashrate(info.hashrate), 'stat-difficulty': U.fmtCompact(info.difficulty), 'stat-supply': U.fmtNum(info.totalSupply) + ' DERO' };
for (var id in u) { var el = document.getElementById(id); if (el) el.textContent = u[id]; }
}
async function renderDetail(h) {
var el = document.getElementById('view-blockDetail');
if (!el) { var main = document.getElementById('main-content'); el = document.createElement('div'); el.id = 'view-blockDetail'; main.appendChild(el); }
el.classList.remove('hidden');
ui.showLoading(el, 'Loading block...');
try {
var conn = M.get('connectivity'), height = parseInt(h), block;
if (conn.hasEnhancedFeatures()) block = await conn.getBlockDetails(height);
else block = await conn.getBlock(height);
if (!block) throw new Error('Block not found');
el.innerHTML = renderDetailHTML(block);
} catch (e) { ui.showError(el, 'Block Not Found', e.message); }
}
function extractMinerAddress(b) {
// Try multiple possible locations for miner address
if (b.miner_address) return b.miner_address;
if (b.block_header?.miner_address) return b.block_header.miner_address;
if (b.block_header?.miners && Array.isArray(b.block_header.miners) && b.block_header.miners.length > 0) {
return b.block_header.miners[0];
}
if (b.miners && Array.isArray(b.miners) && b.miners.length > 0) {
return b.miners[0];
}
// Try to extract from miner_tx if available (for future enhancement)
if (b.miner_tx?.destinations && Array.isArray(b.miner_tx.destinations) && b.miner_tx.destinations.length > 0) {
var dest = b.miner_tx.destinations[0];
if (dest.address) return dest.address;
}
return null;
}
function renderDetailHTML(b) {
var hdr = b.block_header, txs = (b.txs?.length || 0) + 1;
var minerAddr = extractMinerAddress(b);
return '<div class="detail-view"><div class="detail-nav"><button class="btn btn-ghost" onclick="goBack()">< Back</button><div class="detail-nav-arrows">' +
(hdr.height > 1 ? '<button class="btn btn-ghost" onclick="viewBlock(' + (hdr.height - 1) + ')">< Block ' + U.fmtNum(hdr.height - 1) + '</button>' : '') +
'<button class="btn btn-ghost" onclick="viewBlock(' + (hdr.height + 1) + ')">Block ' + U.fmtNum(hdr.height + 1) + ' ></button></div></div>' +
'<div class="section-card">' + ui.sectionHeader({ icon: '[B]', title: 'Block ' + U.fmtNum(hdr.height), meta: U.fmtAge(hdr.timestamp) }) +
'<div class="section-content"><div class="detail-grid"><div class="detail-column"><h4 class="detail-subtitle">Block Information</h4>' +
ui.detailRow('Height', U.fmtNum(hdr.height)) + ui.detailRow('Topoheight', U.fmtNum(hdr.topoheight)) +
ui.detailRow('Timestamp', U.fmtLocalTime(hdr.timestamp)) + ui.detailRow('Age', U.fmtAge(hdr.timestamp)) +
ui.detailRow('Hash', hdr.hash, { mono: true, copyable: true }) +
(hdr.tips?.[0] ? ui.detailRow('Previous', U.truncHash(hdr.tips[0], 12, 8), { mono: true }) : '') +
'</div><div class="detail-column"><h4 class="detail-subtitle">Mining Information</h4>' +
(minerAddr ? ui.detailRow('Miner', minerAddr, { mono: true }) : ui.detailRow('Miner', '<span class="text-muted">Not available</span>')) +
ui.detailRow('Reward', U.fmtDERO(hdr.reward) + ' DERO') + ui.detailRow('Difficulty', U.fmtNum(hdr.difficulty)) +
ui.detailRow('Nonce', hdr.nonce) + ui.detailRow('Size', U.fmtBytes(hdr.block_size || hdr.block_weight)) +
ui.detailRow('Transactions', txs.toString()) + '</div></div></div></div>' +
'<div class="section-card">' + ui.sectionHeader({ icon: '[T]', title: 'Transactions (' + txs + ')', badge: { text: 'CONFIRMED', class: 'badge-ok' } }) +
'<div class="section-content">' + renderBlockTxs(b) + '</div></div></div>';
}
function renderBlockTxs(b) {
var hdr = b.block_header, txs = b.txs || [];
var html = '<div class="tx-list"><div class="tx-item tx-coinbase"><div class="tx-item-left"><span class="tx-type badge badge-ok">COINBASE</span><span class="tx-hash mono">' +
(b.miner_tx?.hash ? U.truncHash(b.miner_tx.hash) : 'Mining Reward') + '</span></div><div class="tx-item-right"><span class="tx-amount text-ok">+' + U.fmtDERO(hdr.reward) + ' DERO</span></div></div>';
txs.forEach(function(tx) {
html += '<div class="tx-item" onclick="viewTx(\'' + tx + '\')"><div class="tx-item-left"><span class="tx-type badge badge-pending">TX</span><span class="tx-hash mono">' + U.truncHash(tx, 16, 12) + '</span></div><div class="tx-item-right"><span class="tx-action">View ></span></div></div>';
});
if (txs.length === 0) html += '<div class="tx-item-empty"><span class="text-muted">No regular transactions in this block</span></div>';
return html + '</div>';
}
return { init: init, loadBlocksPage: loadPage, goToPage: goToPage, loadRecentBlocks: loadRecent, renderBlockDetail: renderDetail, getState: function() { return B; } };
})();
*/'] |