get_address($public_key); $bind=array(":id"=>$id, ":public_key"=>$public_key, ":block"=>$block,":public_key2"=>$public_key ); $db->run("INSERT INTO accounts SET id=:id, public_key=:public_key, block=:block, balance=0 ON DUPLICATE KEY UPDATE public_key=if(public_key='',:public_key2,public_key)",$bind); } // inserts just the account without public key public function add_id($id, $block){ global $db; $bind=array(":id"=>$id, ":block"=>$block); $db->run("INSERT ignore INTO accounts SET id=:id, public_key='', block=:block, balance=0",$bind); } // generates Account's address from the public key public function get_address($hash){ //broken base58 addresses, which are block winners, missing the first 0 bytes from the address. if($hash=='PZ8Tyr4Nx8MHsRAGMpZmZ6TWY63dXWSCwCpspGFGQSaF9yVGLamBgymdf8M7FafghmP3oPzQb3W4PZsZApVa41uQrrHRVBH5p9bdoz7c6XeRQHK2TkzWR45e') return '22SoB29oyq2JhMxtBbesL7JioEYytyC6VeFmzvBH6fRQrueSvyZfEXR5oR7ajSQ9mLERn6JKU85EAbVDNChke32'; elseif($hash=='PZ8Tyr4Nx8MHsRAGMpZmZ6TWY63dXWSCzbRyyz5oDNDKhk5jyjg4caRjkbqegMZMrUkuBjVMuYcVfPyc3aKuLmPHS4QEDjCrNGks7Z5oPxwv4yXSv7WJnkbL') return 'AoFnv3SLujrJSa2J7FDTADGD7Eb9kv3KtNAp7YVYQEUPcLE6cC6nLvvhVqcVnRLYF5BFF38C1DyunUtmfJBhyU'; elseif($hash=='PZ8Tyr4Nx8MHsRAGMpZmZ6TWY63dXWSCyradtFFJoaYB4QdcXyBGSXjiASMMnofsT4f5ZNaxTnNDJt91ubemn3LzgKrfQh8CBpqaphkVNoRLub2ctdMnrzG1') return 'RncXQuc7S7aWkvTUJSHEFvYoV3ntAf7bfxEHjSiZNBvQV37MzZtg44L7GAV7szZ3uV8qWqikBewa3piZMqzBqm'; elseif($hash=='PZ8Tyr4Nx8MHsRAGMpZmZ6TWY63dXWSCyjKMBY4ihhJ2G25EVezg7KnoCBVbhdvWfqzNA4LC5R7wgu3VNfJgvqkCq9sKKZcCoCpX6Qr9cN882MoXsfGTvZoj') return 'Rq53oLzpCrb4BdJZ1jqQ2zsixV2ukxVdM4H9uvUhCGJCz1q2wagvuXV4hC6UVwK7HqAt1FenukzhVXgzyG1y32'; // hashes 9 times in sha512 (binary) and encodes in base58 for($i=0;$i<9;$i++) $hash=hash('sha512',$hash, true); return base58_encode($hash); } // checks the ecdsa secp256k1 signature for a specific public key public function check_signature($data, $signature, $public_key){ return ec_verify($data ,$signature, $public_key); } // generates a new account and a public/private key pair public function generate_account(){ // using secp256k1 curve for ECDSA $args = array( "curve_name" => "secp256k1", "private_key_type" => OPENSSL_KEYTYPE_EC, ); // generates a new key pair $key1 = openssl_pkey_new($args); // exports the private key encoded as PEM openssl_pkey_export($key1, $pvkey); // converts the PEM to a base58 format $private_key= pem2coin($pvkey); // exports the private key encoded as PEM $pub = openssl_pkey_get_details($key1); // converts the PEM to a base58 format $public_key= pem2coin($pub['key']); // generates the account's address based on the public key $address=$this->get_address($public_key); return array("address"=>$address, "public_key"=>$public_key,"private_key"=>$private_key); } // check the validity of a base58 encoded key. At the moment, it checks only the characters to be base58. public function valid_key($id){ $chars = str_split("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"); for($i=0;$i=70 and <=128. public function valid($id){ if(strlen($id)<70||strlen($id)>128) return false; $chars = str_split("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"); for($i=0;$isingle("SELECT balance FROM accounts WHERE id=:id",array(":id"=>$id)); if($res===false) $res="0.00000000"; return number_format($res,8,".",""); } // returns the account balance - any pending debits from the mempool public function pending_balance($id){ global $db; $res=$db->single("SELECT balance FROM accounts WHERE id=:id",array(":id"=>$id)); if($res===false) $res="0.00000000"; // if the original balance is 0, no mempool transactions are possible if($res=="0.00000000") return $res; $mem=$db->single("SELECT SUM(val+fee) FROM mempool WHERE src=:id",array(":id"=>$id)); $rez=$res-$mem; return number_format($rez,8,".",""); } // returns all the transactions of a specific address public function get_transactions($id,$limit=100){ global $db; $block=new Block; $current=$block->current(); $public_key=$this->public_key($id); $limit=intval($limit); if($limit>100||$limit<1) $limit=100; $res=$db->run("SELECT * FROM transactions WHERE dst=:dst or public_key=:src ORDER by height DESC LIMIT :limit",array(":src"=>$public_key, ":dst"=>$id, ":limit"=>$limit)); $transactions=array(); foreach($res as $x){ $trans=array("block"=>$x['block'],"height"=>$x['height'], "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['src']=$this->get_address($x['public_key']); $trans['confirmations']=$current['height']-$x['height']; // version 0 -> reward transaction, version 1 -> normal transaction if($x['version']==0) $trans['type']="mining"; elseif($x['version']==1){ if($x['dst']==$id) $trans['type']="credit"; else $trans['type']="debit"; } else { $trans['type']="other"; } ksort($trans); $transactions[]=$trans; } return $transactions; } // returns the transactions from the mempool public function get_mempool_transactions($id){ global $db; $transactions=array(); $res=$db->run("SELECT * FROM mempool WHERE src=:src ORDER by height DESC LIMIT 100",array(":src"=>$id, ":dst"=>$id)); foreach($res as $x){ $trans=array("block"=>$x['block'],"height"=>$x['height'], "id"=>$x['id'],"src"=>$x['src'],"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['type']="mempool"; // they are unconfirmed, so they will have -1 confirmations. $trans['confirmations']=-1; ksort($trans); $transactions[]=$trans; } return $transactions; } // returns the public key for a specific account public function public_key($id){ global $db; $res=$db->single("SELECT public_key FROM accounts WHERE id=:id",array(":id"=>$id)); return $res; } } ?>