blockchainExplorer = function(){ // Init array var _known_blocks = null; var _liste_blocks = null; var _classes = ['bg-grey-even','bg-grey-odd']; var _cur_class = 0; var _cur_methode = 'hasard'; var _mode = 1; var _infos = false; function _precisionRound(number) { var precision = 4; var factor = Math.pow(10, precision); return Math.round((number/100000000) * factor) / factor; } function _getblockNameFromHash(hash) { var retour = ''; if (_known_blocks != null) _known_blocks.forEach(function(item){ if (hash == item.hash) retour = item.name; }); return retour; } function _getblocHashFromName(name) { var retour = ''; if (_known_blocks != null) _known_blocks.forEach(function(item){ if (name == item.name) retour = item.hash; }); return retour; } function _convertUTCDateToLocalDate(date) { var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000); var offset = date.getTimezoneOffset() / 60; var hours = date.getHours(); newDate.setHours(hours - offset); return newDate; } function _formatDate(unixtime) { var ladate = new Date(unixtime*1000); var ladateStr = ""; // ladate = _convertUTCDateToLocalDate(ladate); ladateStr += ladate.getFullYear(); ladateStr += "/" +("00"+(ladate.getMonth()+1)).slice(-2); ladateStr += "/" +("00" + ladate.getDate()).slice(-2); ladateStr += " " +("00" + ladate.getHours()).slice(-2); ladateStr += ":" +("00" + ladate.getMinutes()).slice(-2); ladateStr += ":" +("00" + ladate.getSeconds()).slice(-2); return ladateStr; } function _addInfoForBlock(block) { var contenu = ''; var downloadingImage = new Image(); var div_label = block.height; _cur_class = 1 - _cur_class; blockName = _getblockNameFromHash(block.hash); // if (blockName != '') blockName = ' ( '+blockName+' )'; if (_mode > 1) if (block.hash == _liste_blocks['TOP']) { div_label = 'LAST'; if (blockName == '') blockName = 'LAST'; } opacity='1.0'; visibility='hidden'; if (_infos) { opacity='0.3'; visibility='visible'; } contenu += '
'; contenu += '
'; contenu += ' '; if (_mode == 3 ) contenu += ' '; contenu += ' '; contenu += ' '; contenu += ' '; contenu += ' '; contenu += ' '; contenu += ' '; if (_mode != 3 ) contenu += ' '; contenu += ' '; contenu += '
name'+blockName+'
height'+block.height+'
timestamp'+_formatDate(block.time)+'
nonce'+block.nonce+'
nb tx'+block.n_tx+'
outputs'+_precisionRound(block.topisto_outputs).toFixed(4)+'
inputs'+_precisionRound(block.topisto_inputs).toFixed(4)+'
fees'+_precisionRound(block.topisto_fees).toFixed(4)+'
reward'+_precisionRound(block.topisto_reward).toFixed(4)+'
'; contenu += '
'; contenu += '
'; $('#info_'+div_label).html(contenu); downloadingImage.onload = function(){ var div0 = document.getElementById('img_'+block.height); div0.style.backgroundImage = "url(" + this.src + ")"; div0.style.backgroundRepeat = "no-repeat"; div0.style.backgroundPosition = "center"; div0.style.backgroundSize = "auto 100%"; flag_nav = true; }; downloadingImage.src = 'images/block_image.php?methode='+_cur_methode+'&hash='+block.hash; return true; } function _addDiv(block_height) { var contenu = ''; contenu += '
'; contenu += '
'; contenu += '###BLOCK_DESC###'; contenu += '
'; contenu += '
'; return contenu; } function _addDivForBlock(block_height, onTop = false) { var lediv = document.getElementById('info_'+block_height); if (lediv === null) { var tmp; var contenu = _addDiv(block_height); var block_desc = ''; block_desc += '
'; block_desc += '

BLOCK '+block_height+' ...

'; block_desc += '
'; tmp = contenu.replace('###BLOCK_DESC###',block_desc) if (onTop) { tmp += $('#blockchain').html(); $('#blockchain').html(tmp); } else { $('#blockchain').append(tmp); } } return true; } function _addDivForVoid() { return _addDivForBlock('void'); } function _gotoBlock(block_name) { $(document).scrollTop( $("#explorer").offset().top ); // Bloquer la navigation pendant le calcul if (!flag_nav) { window.alert('A block image is currently computed, please wait ...'); return false; } flag_nav = false; if (block_name == 'NEXT') { flag_nav = true; // Supprimer un block if (cur_height.length < 3) { window.alert('No Next Block, you are at '+$('#blockSelector').val()+' block !'); return false; } _liste_blocks['PREVIOUS'] = _liste_blocks['BLOCK_'+cur_height[cur_height.length-1]]; cur_height.pop(); _toggleForwardBtn(); $('#block_'+cur_height[cur_height.length-2]).slideDown(400, function() { // Animation complete. $('#blockchain').children('div:last').remove(); _cur_class = 1 - _cur_class; }); } else { // Ajouter un block _addDivForBlock(cur_height[cur_height.length-1] - 1); // Décaler d'un block vers le haut if (cur_height.length > 1) $('#block_'+cur_height[cur_height.length-2]).slideUp(); block_hash = ''; if (block_name != 'LAST') block_hash = '?block_hash='+_liste_blocks[block_name]; $.getJSON('data/getBlockInfo.php'+block_hash, function( data ) { _liste_blocks['PREVIOUS'] = data.prev; _liste_blocks['BLOCK_'+data.height] = data.hash; _addInfoForBlock(data); _toggleForwardBtn(); }); } return true; } function _addTopBlock(data, flag = false) { if (flag) return "ajouterTopBlock"; // Maintenir la liste des blocks _liste_blocks['TOP'] = data.hash; _liste_blocks['BLOCK_'+data.height] = data.hash; // Ajouter un div if (_mode < 2) _addDivForBlock(data.height,true); // Mettre les infos dans le div _addInfoForBlock(data); topistoConsole.log('Last Block on top : '+data.hash); } function _addBottomBlock() { // Mettre les infos du block block_hash = '?block_hash='+_liste_blocks['BOTTOM']; $.getJSON('data/getBlockInfo.php'+block_hash, function( data ) { // Ajouter un div _addDivForBlock(data.height, false); // Mettre les infos dans le div _addInfoForBlock(data); _liste_blocks['BLOCK_'+data.height] = data.hash; _liste_blocks['LENGTH'] += 1; switch(_mode) { case 0: case 1: // Récursivité pour précharger par paquets if (data.height > 0) _liste_blocks['BOTTOM'] = data.prev; break; case 2: case 3: if (data.height > 0) _liste_blocks['BOTTOM'] = _known_blocks[_liste_blocks['LENGTH']-1].hash; break; } if (_liste_blocks['LENGTH'] % 10) _addBottomBlock(); }); } function _initBlockchain(block_name) { var block_hash = ''; _liste_blocks = []; _liste_blocks['LENGTH'] = 0; $(document).scrollTop( $("#explorer").offset().top ); $('#blockchain').html(''); if (block_name != 'LAST') block_hash = '?block_hash='+_getblocHashFromName(block_name); $.getJSON('data/getBlockInfo.php'+block_hash, function( data ) { _liste_blocks['TOP'] = data.hash; _liste_blocks['BLOCK_'+data.height] = data.hash; _liste_blocks['LENGTH'] += 1; div_label = data.height; switch(_mode) { case 0: case 1: // Récursivité pour précharger par paquets _liste_blocks['BOTTOM'] = data.prev; break; case 2: case 3: div_label = 'LAST'; _liste_blocks['BOTTOM'] = _known_blocks[0].hash; break; } _addDivForBlock(div_label); _addInfoForBlock(data); blockchainListener.addBlockHook(_addTopBlock); _addBottomBlock(); }); return true; } function _blockSelectorChange() { _initBlockchain($('#blockSelector').val()); } function _initBlockSelector() { // Init the selector var select = $('#blockSelector'); $.each(_liste_blocks, function (key, bloc) { select.append(new Option(bloc.name, bloc.name)); }); } function _init(mode = 1) { _mode = mode; if (_known_blocks == null) { $.getJSON('data/getKnownBlocksList.php', function( data ) { _known_blocks = data; _known_blocks.sort(function(a,b){ // sort desc ... if (a.height < b.height) return 1; if (a.height > b.height) return -1; return 0; }); return true; }); } return _initBlockchain('LAST'); } function _toggleInfos() { var infos = Array.from(document.getElementsByClassName('block_infos')); _infos = ! _infos; infos.forEach((item, index) => { if (_infos) { item.style.visibility = 'visible'; item.style.background = 'rgba(255,255,255,0.5)'; } else item.style.visibility = 'hidden'; }); } return { addTopBlock: _addTopBlock, addBottomBlock: _addBottomBlock, getblocHashFromName: _getblocHashFromName, toggleInfos: _toggleInfos, init: _init }; }();