Update Block class to PSR-2

This commit is contained in:
pxgamer
2018-05-29 15:35:37 +01:00
parent 425bdcb504
commit 44c9eb5ce6

View File

@@ -1,10 +1,9 @@
<?php <?php
class Block { class Block
{
public function add($height, $public_key, $nonce, $data, $date, $signature, $difficulty, $reward_signature, $argon)
{
public function add($height, $public_key, $nonce, $data, $date, $signature, $difficulty, $reward_signature, $argon){
global $db; global $db;
$acc = new Account; $acc = new Account;
$trx = new Transaction; $trx = new Transaction;
@@ -17,16 +16,23 @@ public function add($height, $public_key, $nonce, $data, $date, $signature, $dif
// create the hash / block id // create the hash / block id
$hash = $this->hash($generator, $height, $date, $nonce, $data, $signature, $difficulty, $argon); $hash = $this->hash($generator, $height, $date, $nonce, $data, $signature, $difficulty, $argon);
//fix for the broken base58 library used until block 16900, trimming the first 0 bytes. //fix for the broken base58 library used until block 16900, trimming the first 0 bytes.
if($height<16900) $hash=ltrim($hash,'1'); if ($height < 16900) {
$hash = ltrim($hash, '1');
}
$json = json_encode($data); $json = json_encode($data);
// create the block data and check it against the signature // create the block data and check it against the signature
$info = "{$generator}-{$height}-{$date}-{$nonce}-{$json}-{$difficulty}-{$argon}"; $info = "{$generator}-{$height}-{$date}-{$nonce}-{$json}-{$difficulty}-{$argon}";
if(!$acc->check_signature($info,$signature,$public_key)) { _log("Block signature check failed"); return false; } if (!$acc->check_signature($info, $signature, $public_key)) {
_log("Block signature check failed");
return false;
}
if (!$this->parse_block($hash, $height, $data, true)) {
if(!$this->parse_block($hash,$height,$data, true)) { _log("Parse block failed"); return false; } _log("Parse block failed");
return false;
}
// lock table to avoid race conditions on blocks // lock table to avoid race conditions on blocks
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE"); $db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE");
@@ -35,21 +41,45 @@ public function add($height, $public_key, $nonce, $data, $date, $signature, $dif
$msg = ''; $msg = '';
// the reward transaction // the reward transaction
$transaction=array("src"=>$generator, "dst"=>$generator, "val"=>$reward, "version"=>0, "date"=>$date, "message"=>$msg, "fee"=>"0.00000000","public_key"=>$public_key); $transaction = [
"src" => $generator,
"dst" => $generator,
"val" => $reward,
"version" => 0,
"date" => $date,
"message" => $msg,
"fee" => "0.00000000",
"public_key" => $public_key,
];
$transaction['signature'] = $reward_signature; $transaction['signature'] = $reward_signature;
// hash the transaction // hash the transaction
$transaction['id'] = $trx->hash($transaction); $transaction['id'] = $trx->hash($transaction);
// check the signature // check the signature
$info = $transaction['val']."-".$transaction['fee']."-".$transaction['dst']."-".$transaction['message']."-".$transaction['version']."-".$transaction['public_key']."-".$transaction['date']; $info = $transaction['val']."-".$transaction['fee']."-".$transaction['dst']."-".$transaction['message']."-".$transaction['version']."-".$transaction['public_key']."-".$transaction['date'];
if(!$acc->check_signature($info,$reward_signature,$public_key)) {_log("Reward signature failed"); return false; } if (!$acc->check_signature($info, $reward_signature, $public_key)) {
_log("Reward signature failed");
return false;
}
// insert the block into the db // insert the block into the db
$db->beginTransaction(); $db->beginTransaction();
$total = count($data); $total = count($data);
$bind=array(":id"=>$hash,":generator"=>$generator, ":signature"=>$signature, ":height"=>$height, ":date"=>$date, ":nonce"=>$nonce, ":difficulty"=>$difficulty,":argon"=>$argon, ":transactions"=>$total); $bind = [
$res=$db->run("INSERT into blocks SET id=:id, generator=:generator, height=:height,`date`=:date,nonce=:nonce, signature=:signature, difficulty=:difficulty, argon=:argon, transactions=:transactions",$bind); ":id" => $hash,
":generator" => $generator,
":signature" => $signature,
":height" => $height,
":date" => $date,
":nonce" => $nonce,
":difficulty" => $difficulty,
":argon" => $argon,
":transactions" => $total,
];
$res = $db->run(
"INSERT into blocks SET id=:id, generator=:generator, height=:height,`date`=:date,nonce=:nonce, signature=:signature, difficulty=:difficulty, argon=:argon, transactions=:transactions",
$bind
);
if ($res != 1) { if ($res != 1) {
// rollback and exit if it fails // rollback and exit if it fails
_log("Block DB insert failed"); _log("Block DB insert failed");
@@ -64,15 +94,19 @@ public function add($height, $public_key, $nonce, $data, $date, $signature, $dif
// parse the block's transactions and insert them to db // parse the block's transactions and insert them to db
$res = $this->parse_block($hash, $height, $data, false); $res = $this->parse_block($hash, $height, $data, false);
// if any fails, rollback // if any fails, rollback
if($res==false) $db->rollback(); if ($res == false) {
else $db->commit(); $db->rollback();
} else {
$db->commit();
}
// relese the locking as everything is finished // relese the locking as everything is finished
$db->exec("UNLOCK TABLES"); $db->exec("UNLOCK TABLES");
return true; return true;
} }
// returns the current block, without the transactions // returns the current block, without the transactions
public function current(){ public function current()
{
global $db; global $db;
$current = $db->row("SELECT * FROM blocks ORDER by height DESC LIMIT 1"); $current = $db->row("SELECT * FROM blocks ORDER by height DESC LIMIT 1");
if (!$current) { if (!$current) {
@@ -80,18 +114,20 @@ public function current(){
return $this->current(true); return $this->current(true);
} }
return $current; return $current;
} }
// returns the previous block // returns the previous block
public function prev(){ public function prev()
{
global $db; global $db;
$current = $db->row("SELECT * FROM blocks ORDER by height DESC LIMIT 1,1"); $current = $db->row("SELECT * FROM blocks ORDER by height DESC LIMIT 1,1");
return $current; return $current;
} }
// calculates the difficulty / base target for a specific block. The higher the difficulty number, the easier it is to win a block. // calculates the difficulty / base target for a specific block. The higher the difficulty number, the easier it is to win a block.
public function difficulty($height=0){ public function difficulty($height = 0)
{
global $db; global $db;
// if no block height is specified, use the current block. // if no block height is specified, use the current block.
@@ -104,15 +140,20 @@ public function difficulty($height=0){
$height = $current['height']; $height = $current['height'];
if($height==10801) return 5555555555; //hard fork 10900 resistance, force new difficulty if ($height == 10801) {
return 5555555555; //hard fork 10900 resistance, force new difficulty
}
// last 20 blocks used to check the block times // last 20 blocks used to check the block times
$limit = 20; $limit = 20;
if($height<20) if ($height < 20) {
$limit = $height - 1; $limit = $height - 1;
}
// for the first 10 blocks, use the genesis difficulty // for the first 10 blocks, use the genesis difficulty
if($height<10) return $current['difficulty']; if ($height < 10) {
return $current['difficulty'];
}
// elapsed time between the last 20 blocks // elapsed time between the last 20 blocks
$first = $db->row("SELECT `date` FROM blocks ORDER by height DESC LIMIT $limit,1"); $first = $db->row("SELECT `date` FROM blocks ORDER by height DESC LIMIT $limit,1");
@@ -136,25 +177,32 @@ public function difficulty($height=0){
} }
//minimum and maximum diff //minimum and maximum diff
if($dif<1000) $dif=1000; if ($dif < 1000) {
if($dif>9223372036854775800) $dif=9223372036854775800; $dif = 1000;
}
if ($dif > 9223372036854775800) {
$dif = 9223372036854775800;
}
return $dif; return $dif;
} }
// calculates the maximum block size and increase by 10% the number of transactions if > 100 on the last 100 blocks // calculates the maximum block size and increase by 10% the number of transactions if > 100 on the last 100 blocks
public function max_transactions(){ public function max_transactions()
{
global $db; global $db;
$current = $this->current(); $current = $this->current();
$limit = $current['height'] - 100; $limit = $current['height'] - 100;
$avg=$db->single("SELECT AVG(transactions) FROM blocks WHERE height>:limit",array(":limit"=>$limit)); $avg = $db->single("SELECT AVG(transactions) FROM blocks WHERE height>:limit", [":limit" => $limit]);
if($avg<100) return 100; if ($avg < 100) {
return 100;
}
return ceil($avg * 1.1); return ceil($avg * 1.1);
} }
// calculate the reward for each block // calculate the reward for each block
public function reward($id,$data=array()){ public function reward($id, $data = [])
{
// starting reward // starting reward
$reward = 1000; $reward = 1000;
@@ -162,12 +210,13 @@ public function reward($id,$data=array()){
$factor = floor($id / 10800) / 100; $factor = floor($id / 10800) / 100;
$reward -= $reward * $factor; $reward -= $reward * $factor;
if($reward<0) $reward=0; if ($reward < 0) {
$reward = 0;
}
// calculate the transaction fees // calculate the transaction fees
$fees = 0; $fees = 0;
if (count($data) > 0) { if (count($data) > 0) {
foreach ($data as $x) { foreach ($data as $x) {
$fees += $x['fee']; $fees += $x['fee'];
} }
@@ -176,36 +225,53 @@ public function reward($id,$data=array()){
} }
// checks the validity of a block // checks the validity of a block
public function check($data){ public function check($data)
{
// argon must have at least 20 chars // argon must have at least 20 chars
if(strlen($data['argon'])<20) { _log("Invalid block argon - $data[argon]"); return false; } if (strlen($data['argon']) < 20) {
_log("Invalid block argon - $data[argon]");
return false;
}
$acc = new Account; $acc = new Account;
// generator's public key must be valid // generator's public key must be valid
if(!$acc->valid_key($data['public_key'])) { _log("Invalid public key - $data[public_key]"); return false; } if (!$acc->valid_key($data['public_key'])) {
_log("Invalid public key - $data[public_key]");
return false;
}
//difficulty should be the same as our calculation //difficulty should be the same as our calculation
if($data['difficulty']!=$this->difficulty()) { _log("Invalid difficulty - $data[difficulty] - ".$this->difficulty()); return false; } if ($data['difficulty'] != $this->difficulty()) {
_log("Invalid difficulty - $data[difficulty] - ".$this->difficulty());
return false;
}
//check the argon hash and the nonce to produce a valid block //check the argon hash and the nonce to produce a valid block
if(!$this->mine($data['public_key'],$data['nonce'], $data['argon'])) { _log("Mine check failed"); return false; } if (!$this->mine($data['public_key'], $data['nonce'], $data['argon'])) {
_log("Mine check failed");
return false;
}
return true; return true;
} }
// creates a new block on this node // creates a new block on this node
public function forge($nonce, $argon, $public_key, $private_key){ public function forge($nonce, $argon, $public_key, $private_key)
{
//check the argon hash and the nonce to produce a valid block //check the argon hash and the nonce to produce a valid block
if (!$this->mine($public_key, $nonce, $argon)) {
if(!$this->mine($public_key,$nonce, $argon)) { _log("Forge failed - Invalid argon"); return false; } _log("Forge failed - Invalid argon");
return false;
}
// the block's date timestamp must be bigger than the last block // the block's date timestamp must be bigger than the last block
$current = $this->current(); $current = $this->current();
$height = $current['height'] += 1; $height = $current['height'] += 1;
$date = time(); $date = time();
if($date<=$current['date']) { _log("Forge failed - Date older than last block"); return false; } if ($date <= $current['date']) {
_log("Forge failed - Date older than last block");
return false;
}
// get the mempool transactions // get the mempool transactions
$txn = new Transaction; $txn = new Transaction;
@@ -225,18 +291,41 @@ public function forge($nonce, $argon, $public_key, $private_key){
// reward transaction and signature // reward transaction and signature
$reward = $this->reward($height, $data); $reward = $this->reward($height, $data);
$msg = ''; $msg = '';
$transaction=array("src"=>$generator, "dst"=>$generator, "val"=>$reward, "version"=>0, "date"=>$date, "message"=>$msg, "fee"=>"0.00000000","public_key"=>$public_key); $transaction = [
"src" => $generator,
"dst" => $generator,
"val" => $reward,
"version" => 0,
"date" => $date,
"message" => $msg,
"fee" => "0.00000000",
"public_key" => $public_key,
];
ksort($transaction); ksort($transaction);
$reward_signature = $txn->sign($transaction, $private_key); $reward_signature = $txn->sign($transaction, $private_key);
// add the block to the blockchain // add the block to the blockchain
$res=$this->add($height, $public_key, $nonce, $data, $date, $signature, $difficulty, $reward_signature, $argon); $res = $this->add(
if(!$res) { _log("Forge failed - Block->Add() failed"); return false; } $height,
$public_key,
$nonce,
$data,
$date,
$signature,
$difficulty,
$reward_signature,
$argon
);
if (!$res) {
_log("Forge failed - Block->Add() failed");
return false;
}
return true; return true;
} }
// check if the arguments are good for mining a specific block // check if the arguments are good for mining a specific block
public function mine($public_key, $nonce, $argon, $difficulty=0, $current_id=0, $current_height=0){ public function mine($public_key, $nonce, $argon, $difficulty = 0, $current_id = 0, $current_height = 0)
{
global $_config; global $_config;
// if no id is specified, we use the current // if no id is specified, we use the current
if ($current_id === 0) { if ($current_id === 0) {
@@ -245,27 +334,39 @@ public function mine($public_key, $nonce, $argon, $difficulty=0, $current_id=0,
$current_height = $current['height']; $current_height = $current['height'];
} }
// get the current difficulty if empty // get the current difficulty if empty
if($difficulty===0) $difficulty=$this->difficulty(); if ($difficulty === 0) {
$difficulty = $this->difficulty();
}
// the argon parameters are hardcoded to avoid any exploits // the argon parameters are hardcoded to avoid any exploits
if($current_height>10800) $argon='$argon2i$v=19$m=524288,t=1,p=1'.$argon; //10800 block hard fork - resistance against gpu if ($current_height > 10800) {
else $argon='$argon2i$v=19$m=16384,t=4,p=4'.$argon; $argon = '$argon2i$v=19$m=524288,t=1,p=1'.$argon; //10800 block hard fork - resistance against gpu
} else {
$argon = '$argon2i$v=19$m=16384,t=4,p=4'.$argon;
}
// the hash base for agon // the hash base for agon
$base = "$public_key-$nonce-".$current_id."-$difficulty"; $base = "$public_key-$nonce-".$current_id."-$difficulty";
// check argon's hash validity // check argon's hash validity
if(!password_verify($base,$argon)) { return false; } if (!password_verify($base, $argon)) {
return false;
}
// all nonces are valid in testnet // all nonces are valid in testnet
if($_config['testnet']==true) return true; if ($_config['testnet'] == true) {
return true;
}
// prepare the base for the hashing // prepare the base for the hashing
$hash = $base.$argon; $hash = $base.$argon;
// hash the base 6 times // hash the base 6 times
for($i=0;$i<5;$i++) $hash=hash("sha512",$hash,true); for ($i = 0; $i < 5;
$i++) {
$hash = hash("sha512", $hash, true);
}
$hash = hash("sha512", $hash); $hash = hash("sha512", $hash);
// split it in 2 char substrings, to be used as hex // split it in 2 char substrings, to be used as hex
@@ -281,55 +382,73 @@ public function mine($public_key, $nonce, $argon, $difficulty=0, $current_id=0,
$result = gmp_div($duration, $difficulty); $result = gmp_div($duration, $difficulty);
// if the deadline >0 and <=240, the arguments are valid fora block win // if the deadline >0 and <=240, the arguments are valid fora block win
if($result>0&&$result<=240) return true; if ($result > 0 && $result <= 240) {
return true;
}
return false; return false;
} }
// parse the block transactions // parse the block transactions
public function parse_block($block, $height, $data, $test=true){ public function parse_block($block, $height, $data, $test = true)
{
global $db; global $db;
// data must be array // data must be array
if($data===false) return false; if ($data === false) {
return false;
}
$acc = new Account; $acc = new Account;
$trx = new Transaction; $trx = new Transaction;
// no transactions means all are valid // no transactions means all are valid
if(count($data)==0) return true; if (count($data) == 0) {
return true;
}
// check if the number of transactions is not bigger than current block size // check if the number of transactions is not bigger than current block size
$max = $this->max_transactions(); $max = $this->max_transactions();
if(count($data)>$max) return false; if (count($data) > $max) {
return false;
}
$balance=array(); $balance = [];
foreach ($data as &$x) { foreach ($data as &$x) {
// get the sender's account if empty // get the sender's account if empty
if(empty($x['src'])) $x['src']=$acc->get_address($x['public_key']); if (empty($x['src'])) {
$x['src'] = $acc->get_address($x['public_key']);
}
//validate the transaction //validate the transaction
if(!$trx->check($x,$height)) return false; if (!$trx->check($x, $height)) {
return false;
}
// prepare total balance // prepare total balance
$balance[$x['src']] += $x['val'] + $x['fee']; $balance[$x['src']] += $x['val'] + $x['fee'];
// check if the transaction is already on the blockchain // check if the transaction is already on the blockchain
if($db->single("SELECT COUNT(1) FROM transactions WHERE id=:id",array(":id"=>$x['id']))>0) return false; if ($db->single("SELECT COUNT(1) FROM transactions WHERE id=:id", [":id" => $x['id']]) > 0) {
return false;
}
} }
// check if the account has enough balance to perform the transaction // check if the account has enough balance to perform the transaction
foreach ($balance as $id => $bal) { foreach ($balance as $id => $bal) {
$res=$db->single("SELECT COUNT(1) FROM accounts WHERE id=:id AND balance>=:balance",array(":id"=>$id, ":balance"=>$bal)); $res = $db->single(
if($res==0) return false; // not enough balance for the transactions "SELECT COUNT(1) FROM accounts WHERE id=:id AND balance>=:balance",
[":id" => $id, ":balance" => $bal]
);
if ($res == 0) {
return false; // not enough balance for the transactions
}
} }
// if the test argument is false, add the transactions to the blockchain // if the test argument is false, add the transactions to the blockchain
if ($test == false) { if ($test == false) {
foreach ($data as $d) { foreach ($data as $d) {
$res = $trx->add($block, $height, $d); $res = $trx->add($block, $height, $d);
if($res==false) return false; if ($res == false) {
return false;
}
} }
} }
@@ -338,7 +457,8 @@ public function parse_block($block, $height, $data, $test=true){
// initialize the blockchain, add the genesis block // initialize the blockchain, add the genesis block
private function genesis(){ private function genesis()
{
global $db; global $db;
$signature = 'AN1rKvtLTWvZorbiiNk5TBYXLgxiLakra2byFef9qoz1bmRzhQheRtiWivfGSwP6r8qHJGrf8uBeKjNZP1GZvsdKUVVN2XQoL'; $signature = 'AN1rKvtLTWvZorbiiNk5TBYXLgxiLakra2byFef9qoz1bmRzhQheRtiWivfGSwP6r8qHJGrf8uBeKjNZP1GZvsdKUVVN2XQoL';
$generator = '2P67zUANj7NRKTruQ8nJRHNdKMroY6gLw4NjptTVmYk6Hh1QPYzzfEa9z4gv8qJhuhCNM8p9GDAEDqGUU1awaLW6'; $generator = '2P67zUANj7NRKTruQ8nJRHNdKMroY6gLw4NjptTVmYk6Hh1QPYzzfEa9z4gv8qJhuhCNM8p9GDAEDqGUU1awaLW6';
@@ -348,29 +468,48 @@ private function genesis(){
$difficulty = "5555555555"; $difficulty = "5555555555";
$height = 1; $height = 1;
$data=array(); $data = [];
$date = '1515324995'; $date = '1515324995';
$nonce = '4QRKTSJ+i9Gf9ubPo487eSi+eWOnIBt9w4Y+5J+qbh8='; $nonce = '4QRKTSJ+i9Gf9ubPo487eSi+eWOnIBt9w4Y+5J+qbh8=';
$res=$this->add($height, $public_key, $nonce, $data, $date, $signature, $difficulty, $reward_signature,$argon); $res = $this->add(
if(!$res) api_err("Could not add the genesis block."); $height,
$public_key,
$nonce,
$data,
$date,
$signature,
$difficulty,
$reward_signature,
$argon
);
if (!$res) {
api_err("Could not add the genesis block.");
} }
}
// delete last X blocks // delete last X blocks
public function pop($no=1){ public function pop($no = 1)
{
$current = $this->current(); $current = $this->current();
$this->delete($current['height'] - $no + 1); $this->delete($current['height'] - $no + 1);
} }
// delete all blocks >= height // delete all blocks >= height
public function delete($height){ public function delete($height)
if($height<2) $height=2; {
if ($height < 2) {
$height = 2;
}
global $db; global $db;
$trx = new Transaction; $trx = new Transaction;
$r=$db->run("SELECT * FROM blocks WHERE height>=:height ORDER by height DESC",array(":height"=>$height)); $r = $db->run("SELECT * FROM blocks WHERE height>=:height ORDER by height DESC", [":height" => $height]);
if(count($r)==0) return; if (count($r) == 0) {
return;
}
$db->beginTransaction(); $db->beginTransaction();
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE"); $db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE");
foreach ($r as $x) { foreach ($r as $x) {
@@ -380,7 +519,7 @@ public function delete($height){
$db->exec("UNLOCK TABLES"); $db->exec("UNLOCK TABLES");
return false; return false;
} }
$res=$db->run("DELETE FROM blocks WHERE id=:id",array(":id"=>$x['id'])); $res = $db->run("DELETE FROM blocks WHERE id=:id", [":id" => $x['id']]);
if ($res != 1) { if ($res != 1) {
$db->rollback(); $db->rollback();
$db->exec("UNLOCK TABLES"); $db->exec("UNLOCK TABLES");
@@ -395,14 +534,17 @@ public function delete($height){
// delete specific block // delete specific block
public function delete_id($id){ public function delete_id($id)
{
global $db; global $db;
$trx = new Transaction; $trx = new Transaction;
$x=$db->row("SELECT * FROM blocks WHERE id=:id",array(":id"=>$id)); $x = $db->row("SELECT * FROM blocks WHERE id=:id", [":id" => $id]);
if($x===false) return false; if ($x === false) {
return false;
}
// avoid race conditions on blockchain manipulations // avoid race conditions on blockchain manipulations
$db->beginTransaction(); $db->beginTransaction();
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE"); $db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE");
@@ -415,7 +557,7 @@ public function delete_id($id){
return false; return false;
} }
// remove the actual block // remove the actual block
$res=$db->run("DELETE FROM blocks WHERE id=:id",array(":id"=>$x['id'])); $res = $db->run("DELETE FROM blocks WHERE id=:id", [":id" => $x['id']]);
if ($res != 1) { if ($res != 1) {
//rollback if you can't delete the block //rollback if you can't delete the block
$db->rollback(); $db->rollback();
@@ -430,18 +572,19 @@ public function delete_id($id){
// sign a new block, used when mining // sign a new block, used when mining
public function sign($generator, $height, $date, $nonce, $data, $key, $difficulty, $argon){ public function sign($generator, $height, $date, $nonce, $data, $key, $difficulty, $argon)
{
$json = json_encode($data); $json = json_encode($data);
$info = "{$generator}-{$height}-{$date}-{$nonce}-{$json}-{$difficulty}-{$argon}"; $info = "{$generator}-{$height}-{$date}-{$nonce}-{$json}-{$difficulty}-{$argon}";
$signature = ec_sign($info, $key); $signature = ec_sign($info, $key);
return $signature; return $signature;
} }
// generate the sha512 hash of the block data and converts it to base58 // generate the sha512 hash of the block data and converts it to base58
public function hash($public_key, $height, $date, $nonce, $data, $signature, $difficulty, $argon){ public function hash($public_key, $height, $date, $nonce, $data, $signature, $difficulty, $argon)
{
$json = json_encode($data); $json = json_encode($data);
$hash = hash("sha512", "{$public_key}-{$height}-{$date}-{$nonce}-{$json}-{$signature}-{$difficulty}-{$argon}"); $hash = hash("sha512", "{$public_key}-{$height}-{$date}-{$nonce}-{$json}-{$signature}-{$difficulty}-{$argon}");
return hex2coin($hash); return hex2coin($hash);
@@ -449,19 +592,37 @@ public function hash($public_key, $height, $date, $nonce, $data, $signature, $di
// exports the block data, to be used when submitting to other peers // exports the block data, to be used when submitting to other peers
public function export($id="",$height=""){ public function export($id = "", $height = "")
if(empty($id)&&empty($height)) return false; {
if (empty($id) && empty($height)) {
return false;
}
global $db; global $db;
$trx = new Transaction; $trx = new Transaction;
if(!empty($height)) $block=$db->row("SELECT * FROM blocks WHERE height=:height",array(":height"=>$height)); if (!empty($height)) {
else $block=$db->row("SELECT * FROM blocks WHERE id=:id",array(":id"=>$id)); $block = $db->row("SELECT * FROM blocks WHERE height=:height", [":height" => $height]);
} else {
$block = $db->row("SELECT * FROM blocks WHERE id=:id", [":id" => $id]);
}
if(!$block) return false; if (!$block) {
$r=$db->run("SELECT * FROM transactions WHERE version>0 AND block=:block",array(":block"=>$block['id'])); return false;
$transactions=array(); }
$r = $db->run("SELECT * FROM transactions WHERE version>0 AND block=:block", [":block" => $block['id']]);
$transactions = [];
foreach ($r as $x) { foreach ($r as $x) {
$trans=array("id"=>$x['id'],"dst"=>$x['dst'],"val"=>$x['val'],"fee"=>$x['fee'],"signature"=>$x['signature'], "message"=>$x['message'],"version"=>$x['version'],"date"=>$x['date'], "public_key"=>$x['public_key']); $trans = [
"id" => $x['id'],
"dst" => $x['dst'],
"val" => $x['val'],
"fee" => $x['fee'],
"signature" => $x['signature'],
"message" => $x['message'],
"version" => $x['version'],
"date" => $x['date'],
"public_key" => $x['public_key'],
];
ksort($trans); ksort($trans);
$transactions[$x['id']] = $trans; $transactions[$x['id']] = $trans;
} }
@@ -469,19 +630,23 @@ public function export($id="",$height=""){
$block['data'] = $transactions; $block['data'] = $transactions;
// the reward transaction always has version 0 // the reward transaction always has version 0
$gen=$db->row("SELECT public_key, signature FROM transactions WHERE version=0 AND block=:block",array(":block"=>$block['id'])); $gen = $db->row(
"SELECT public_key, signature FROM transactions WHERE version=0 AND block=:block",
[":block" => $block['id']]
);
$block['public_key'] = $gen['public_key']; $block['public_key'] = $gen['public_key'];
$block['reward_signature'] = $gen['signature']; $block['reward_signature'] = $gen['signature'];
return $block; return $block;
} }
//return a specific block as array //return a specific block as array
public function get($height){ public function get($height)
{
global $db; global $db;
if(empty($height)) return false; if (empty($height)) {
$block=$db->row("SELECT * FROM blocks WHERE height=:height",array(":height"=>$height)); return false;
}
$block = $db->row("SELECT * FROM blocks WHERE height=:height", [":height" => $height]);
return $block; return $block;
} }
} }
?>