// Increment the explorer height to indicate the next desired block $start++; spectra_log_write(0, "Loading Block: " . $start); // The next block is loaded spectra_block_load($start); // Increment the block count $count_loaded++; } // Log the number of blocks loaded spectra_log_write(0, "Loaded " . $count_loaded . " Blocks."); } /****************************************************************************** Rebuild Balances If Indicated ******************************************************************************/ // Check for the balances flag and rebuild if requested if (system_flag_get("balance_rebuild") > 0) { // There is another script that will handle this include "maint_rebalance.php"; } /****************************************************************************** Reset Maintenance Flags ******************************************************************************/ // Reset the maintenance mode flag system_flag_set("maintenance", 0); // Log the time of completion spectra_log_write(0, "Script maint_crontab.php complete."); /****************************************************************************** Developed By Jake Paysnoe - Copyright © 2015 SPEC Development Team SPEC Block Explorer is released under the MIT Software License. For additional details please read license.txt in this package. ******************************************************************************/
function spectra_orphan_wipe($blockhash) { // Write alog message spectra_log_write(0, "Deleting data for block: " . $blockhash); // Remove Related vin data $clear = mysqli_delete($GLOBALS["tables"]["vin"], "`in_block` = '" . $blockhash . "'"); if ($clear["success"] < 1) { spectra_log_write(1, "Unable to delete vin data for block: " . $blockhash); } // Remove related vout data $clear = mysqli_delete($GLOBALS["tables"]["vout"], "`in_block` = '" . $blockhash . "'"); if ($clear["success"] < 1) { spectra_log_write(1, "Unable to delete vout data for block: " . $blockhash); } // Remove related tx data $clear = mysqli_delete($GLOBALS["tables"]["tx"], "`in_block` = '" . $blockhash . "'"); if ($clear["success"] < 1) { spectra_log_write(1, "Unable to delete tx data for block: " . $blockhash); } // Remove any addresses first seen in this block $clear = mysqli_delete($GLOBALS["tables"]["ledger"], "`firstblock` = '" . $blockhash . "'"); if ($clear["success"] < 1) { spectra_log_write(1, "Unable to delete tx data for block: " . $blockhash); } // Remove the block record $clear = mysqli_delete($GLOBALS["tables"]["block"], "`hash` = '" . $blockhash . "'"); if ($clear["success"] < 1) { spectra_log_write(1, "Unable to delete block data for block: " . $blockhash); } }
function spectra_log_sql($message, $query) { $result = $GLOBALS["db"]["obj"]->query($query); if ($GLOBALS["db"]["obj"]->error) { $buildlog = "Error: " . $message . " - " . $GLOBALS["db"]["obj"]->error; spectra_log_write(1, $buildlog); } else { $buildlog = "Success: " . $message; spectra_log_write(0, $buildlog); } }
<?php // Enable the spectra functionality require_once "../lib/spectra_config.php"; // check for a block number in the command line if (!isset($argv[1]) or $argv[1] == "") { echo "You must provide a block height.\n\n"; exit; } // Verify that a block exists at this height $hash = getblockhash((int) $argv[1]); $block = getblock($hash); if (!isset($block["hash"])) { spectra_log_write(1, "Unable to retrieve block at height " . $argv[1]); } // Process the block with the block parser spectra_block_load((int) $argv[1]); // Some data for the log spectra_log_write(0, "Inserted block at height " . $argv[1]); /****************************************************************************** Developed By Jake Paysnoe - Copyright � 2015 SPEC Development Team SPEC Block Explorer is released under the MIT Software License. For additional details please read license.txt in this package. ******************************************************************************/
function spectra_block_load($block_height) { // Fetch the hash for the specified block height $hash = getblockhash($block_height); // Fetch the block data from the node $block = getblock($hash, TRUE); // The block-level data is sorted into an array to match the // formatting of the prepared statement $parsed_block = spectra_block_parse($block); // Parse and calculate each transaction in the block foreach ($block["tx"] as $txid) { // Parse the transaction by ID $tx_parsed = spectra_tx_parse($txid); // Process the transaction vins foreach ($tx_parsed["vin"] as $index => $vin) { // Parse the vin data together with the tx data $parsed_vin = spectra_vin_parse($tx_parsed, $vin); // Bind and insert the vin data $bound = $GLOBALS["db"]["prep"]["vin"]->bind_param("ssisdssiss", $parsed_vin["src_block"], $parsed_vin["src_tx"], $parsed_vin["src_vout"], $parsed_vin["src_address"], $parsed_vin["src_value"], $parsed_vin["in_block"], $parsed_vin["in_tx"], $parsed_vin["time"], $parsed_vin["coinbase"], $parsed_vin["sequence"]); if (!$bound) { spectra_log_write(1, "(prep_vin: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } $response = $GLOBALS["db"]["prep"]["vin"]->execute(); if ($GLOBALS["db"]["obj"]->errno > 0) { spectra_log_write(1, "(prep_vin: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } // Update the transaction $tx_parsed["val_in"] = bcadd($tx_parsed["val_in"], $parsed_vin["src_value"], 8); // If this is not a generation, update the sending address if ($parsed_vin["src_address"] !== "Generated") { // decode the source address $addr_src = json_decode($parsed_vin["src_address"], 1); // Retrieve information about the source address $record = mysqli_getrow($GLOBALS["tables"]["ledger"], "`address` = '" . $addr_src[0] . "'"); // Increment the outgoing transaction counter for the source address $tx_outcount = $record["data"]["tx_out"] + 1; // Increment the outgoing transaction value for the source address $spent = bcadd($record["data"]["spent"], $parsed_vin["src_value"], 8); // Adjust the source account balance $balance = bcsub($record["data"]["balance"], $parsed_vin["src_value"], 8); // Bind and insert the updated values $bound = $GLOBALS["db"]["prep"]["addvin"]->bind_param("idds", $tx_outcount, $spent, $balance, $addr_src[0]); if (!$bound) { spectra_log_write(1, "(prep_addvin: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } $response = $GLOBALS["db"]["prep"]["addvin"]->execute(); if ($GLOBALS["db"]["obj"]->errno > 0) { spectra_log_write(1, "(prep_addvin: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } } } // It is necessary to watch for a stake modifier in order // to separate coins generated in a block-split from any // tx fees in the block. $modifier = 0; // Process the transaction vouts foreach ($tx_parsed["vout"] as $index => $vout) { // Parse the vout $parsed_vout = spectra_vout_parse($parsed_block["flags"], $tx_parsed, $vout); // Set the modiier flag if this vout is a stake-modifier if (strcasecmp(substr($parsed_vout["addresses"], 2, 14), "Stake Modifier") == 0) { $modifier = 1; } // Insert the vout data $bound = $GLOBALS["db"]["prep"]["vout"]->bind_param("ssidiiss", $parsed_vout["in_block"], $parsed_vout["in_tx"], $parsed_vout["time"], $parsed_vout["value"], $parsed_vout["n"], $parsed_vout["reqsigs"], $parsed_vout["type"], $parsed_vout["addresses"]); if (!$bound) { spectra_log_write(1, "(prep_vout: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } $response = $GLOBALS["db"]["prep"]["vout"]->execute(); if ($GLOBALS["db"]["obj"]->errno > 0) { spectra_log_write(1, "(prep_vout: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } // Update the transaction $tx_parsed["val_out"] = bcadd($tx_parsed["val_out"], $parsed_vout["value"], 8); // If this address is unknown a record is created foreach (json_decode($parsed_vout["addresses"], 1) as $address) { $exists = mysqli_isrow($GLOBALS["tables"]["ledger"], "`address` = '" . $address . "'"); if (!$exists["data"]) { // Format an empty address record $address_new = spectra_address_new(); // Populate the empty record with the supplied values $address_new["address"] = $address; $address_new["firstblock"] = $block["hash"]; // Bind the record for insertion $bound = $GLOBALS["db"]["prep"]["address"]->bind_param("ssididds", $address_new["address"], $address_new["firstblock"], $address_new["tx_in"], $address_new["received"], $address_new["tx_out"], $address_new["spent"], $address_new["balance"], $address_new["owner"]); if (!$bound) { spectra_log_write(1, "(prep_address: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } // Execute the prepared statement $response = $GLOBALS["db"]["prep"]["address"]->execute(); if ($GLOBALS["db"]["obj"]->errno > 0) { spectra_log_write(1, "(prep_address: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } } } // For balancing purposes, in case of a multi-sig tx // Only the first address in the list is credited with // the balance from the transaction // Update address information with values from this tx // Decode the addresses field from the parsed vout $addresses = json_decode($parsed_vout["addresses"], 1); // Retrieve information about the receiving address $record = mysqli_getrow($GLOBALS["tables"]["ledger"], "`address` = '" . $addresses[0] . "'"); // Increment the incoming transaction counter for the receiving address $tx_incount = $record["data"]["tx_in"] + 1; // Increment the incoming transaction value for the receiving address $received = bcadd($record["data"]["received"], $parsed_vout["value"], 8); // Adjust the receiving account balance $balance = bcadd($record["data"]["balance"], $parsed_vout["value"], 8); // Bind and insert the updated values $bound = $GLOBALS["db"]["prep"]["addvout"]->bind_param("idds", $tx_incount, $received, $balance, $addresses[0]); if (!$bound) { spectra_log_write(1, "(prep_addvout: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } $response = $GLOBALS["db"]["prep"]["addvout"]->execute(); if ($GLOBALS["db"]["obj"]->errno > 0) { spectra_log_write(1, "(prep_addvout: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } } // Calculate the fee value for this transaction if ($modifier == 0) { $tx_parsed["val_fee"] = bcsub($tx_parsed["val_in"], $tx_parsed["val_out"], 8); } else { $tx_parsed["val_fee"] = 0; } // Bind and insert the parsed tx $bound = $GLOBALS["db"]["prep"]["tx"]->bind_param("ssiiiisddd", $tx_parsed["in_block"], $tx_parsed["txid"], $tx_parsed["version"], $tx_parsed["time"], $tx_parsed["locktime"], $tx_parsed["blocktime"], $tx_parsed["tx-comment"], $tx_parsed["val_in"], $tx_parsed["val_out"], $tx_parsed["val_fee"]); if (!$bound) { spectra_log_write(1, "(prep_tx: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } $response = $GLOBALS["db"]["prep"]["tx"]->execute(); if ($GLOBALS["db"]["obj"]->errno > 0) { spectra_log_write(1, "(prep_tx: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } // Update the block with the values $parsed_block["val_in"] = bcadd($parsed_block["val_in"], $tx_parsed["val_in"], 8); $parsed_block["val_out"] = bcadd($parsed_block["val_out"], $tx_parsed["val_out"], 8); $parsed_block["val_fee"] = bcadd($parsed_block["val_fee"], $tx_parsed["val_fee"], 8); } // Insert the block data into the database $bound = $GLOBALS["db"]["prep"]["block"]->bind_param("ssiiidssssiisdsssssddd", $parsed_block["hash"], $parsed_block["proofhash"], $parsed_block["size"], $parsed_block["height"], $parsed_block["version"], $parsed_block["mint"], $parsed_block["flags"], $parsed_block["entropybit"], $parsed_block["merkleroot"], $parsed_block["tx"], $parsed_block["time"], $parsed_block["nonce"], $parsed_block["bits"], $parsed_block["difficulty"], $parsed_block["modifier"], $parsed_block["modifierchecksum"], $parsed_block["signature"], $parsed_block["previousblockhash"], $parsed_block["nextblockhash"], $parsed_block["val_in"], $parsed_block["val_out"], $parsed_block["val_fee"]); if (!$bound) { spectra_log_write(1, "(prep_block: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } $response = $GLOBALS["db"]["prep"]["block"]->execute(); if ($GLOBALS["db"]["obj"]->errno > 0) { spectra_log_write(1, "(prep_block: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } // Reset prepared statements for performance spectra_prep_reset(); }
} $GLOBALS["db"]["prep"]["vout"] = $GLOBALS["db"]["obj"]->prepare("INSERT INTO `" . $GLOBALS["tables"]["vout"] . "` (`in_block`, `in_tx`, `time`, `value`, `n`, `reqsigs`, `type`, `addresses`) VALUES (?,?,?,?,?,?,?,?)"); if (!$GLOBALS["db"]["prep"]["vout"]) { spectra_log_write(1, "(prep_vout: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } $GLOBALS["db"]["prep"]["address"] = $GLOBALS["db"]["obj"]->prepare("INSERT INTO `" . $GLOBALS["tables"]["ledger"] . "` (`address`, `firstblock`, `tx_in`, `received`, `tx_out`, `spent`, `balance`, `owner`) VALUES (?,?,?,?,?,?,?,?)"); if (!$GLOBALS["db"]["prep"]["address"]) { spectra_log_write(1, "(prep_address: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } $GLOBALS["db"]["prep"]["addvin"] = $GLOBALS["db"]["obj"]->prepare("UPDATE `" . $GLOBALS["tables"]["ledger"] . "` SET `tx_out` = ?, `spent` = ?, `balance` = ? WHERE `address` = ?"); if (!$GLOBALS["db"]["prep"]["addvin"]) { spectra_log_write(1, "(prep_addvin: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } $GLOBALS["db"]["prep"]["addvout"] = $GLOBALS["db"]["obj"]->prepare("UPDATE `" . $GLOBALS["tables"]["ledger"] . "` SET `tx_in` = ?, `received` = ?, `balance` = ? WHERE `address` = ?"); if (!$GLOBALS["db"]["prep"]["addvout"]) { spectra_log_write(1, "(prep_addvout: " . __LINE__ . ") " . $GLOBALS["db"]["obj"]->error); } } // This function performs a reset on the prepared statments to enhance // database performance when loading a large chain. function spectra_prep_reset() { $GLOBALS["db"]["prep"]["block"]->reset(); $GLOBALS["db"]["prep"]["tx"]->reset(); $GLOBALS["db"]["prep"]["vin"]->reset(); $GLOBALS["db"]["prep"]["vout"]->reset(); $GLOBALS["db"]["prep"]["address"]->reset(); $GLOBALS["db"]["prep"]["addvin"]->reset(); $GLOBALS["db"]["prep"]["addvout"]->reset(); } /******************************************************************************
$num_vin++; } } // Fetch the vouts for the address $list_vout = mysqli_getset($GLOBALS["tables"]["vout"], "`addresses` LIKE '%" . $entry["address"] . "%'"); // Sum the vouts $sum_vout = 0; $num_vout = 0; if ($list_vout["data"] != "") { foreach ($list_vout["data"] as $vout) { $sum_vout = bcadd($sum_vout, $vout["value"], 8); $num_vout++; } } // Calculate the balance $balance = bcsub($sum_vout, $sum_vin, 8); // Update the ledger record $result = $GLOBALS["db"]["obj"]->query("UPDATE `" . $GLOBALS["tables"]["ledger"] . "` SET `tx_in` = '" . $num_vout . "', `received` = '" . $sum_vout . "', `tx_out` = '" . $num_vin . "', `spent` = '" . $sum_vin . "', `balance` = '" . $balance . "' WHERE `address` = '" . $entry["address"] . "'"); } // Increment the set counter $count_loop++; } // Reset the balance rebuild flag system_flag_set("balance_rebuild", 0); // Some data for the log spectra_log_write(0, "Rebalance Complete"); /****************************************************************************** Developed By Jake Paysnoe - Copyright © 2015 SPEC Development Team SPEC Block Explorer is released under the MIT Software License. For additional details please read license.txt in this package. ******************************************************************************/
******************************************************************************/ // Enable the spectra functionality require_once "../lib/spectra_config.php"; // Determine the current block height from the node $targ = getblockcount(); if (is_array($targ)) { spectra_log_write(1, "Communication Error: " . print_r($targ["error"], 1)); } // Most wallets do not display the genesis (0) block. The script // will begin loading with the first mined block at block 1. $load = 1; // Status for the log spectra_log_write(0, "Loading " . $GLOBALS["currency"]["name"] . " Block Chain"); spectra_log_write(0, "Node Height: " . $targ); // The blocks are loaded from the node. while ($load <= $targ) { // Each block is written to the log to ensure that any errors // generated can be tracked to the specific block spectra_log_write(0, "Loading Block: " . $load); // The current block is parsed into the database spectra_block_load($load); // The block counter is updated. $load++; } // Completed status for the log spectra_log_write(0, "No New Block (" . $load . ")"); /****************************************************************************** Developed By Jake Paysnoe - Copyright � 2015 SPEC Development Team SPEC Block Explorer is released under the MIT Software License. For additional details please read license.txt in this package. ******************************************************************************/
<?php // Enable the spectra functionality require_once "../lib/spectra_config.php"; // Reset the maintenance flags system_flag_set("balance_rebuild", 0); system_flag_set("maintenance", 0); // Some data for the log spectra_log_write(0, "System Maintenance flags forced to 0"); /****************************************************************************** Developed By Jake Paysnoe - Copyright � 2015 SPEC Development Team SPEC Block Explorer is released under the MIT Software License. For additional details please read license.txt in this package. ******************************************************************************/