function processtransaction($tx, $blockhash, $blocknum)
{
    //returns tx value
    global $db;
    $txhash = $tx->hash;
    $txsize = $tx->size;
    $rawtx = indent(json_encode($tx));
    if (pg_num_rows(pg_query_params($db, "SELECT hash FROM transactions WHERE hash=decode(\$1,'hex');", array($txhash))) === 0) {
        pg_query_params($db, "INSERT INTO transactions(hash,block,raw,size) VALUES (decode(\$1,'hex'),decode(\$2,'hex'),\$3,\$4);", array($txhash, $blockhash, $rawtx, $txsize));
    } else {
        if (pg_num_rows(pg_query_params($db, "SELECT hash FROM transactions WHERE hash=decode(\$1,'hex') AND block<>decode(\$2,'hex');", array($txhash, $blockhash))) == 1) {
            echo "***Duplicate transaction: adding special record***";
            sleep(30);
            pg_query_params($db, "INSERT INTO special VALUES (decode(\$1,'hex'),decode(\$2,'hex'),'Duplicate');", array($txhash, $blockhash));
            return "0";
        } else {
            die("Can't insert tx");
        }
    }
    foreach ($tx->in as $input) {
        $type = NULL;
        $prev = NULL;
        $previndex = NULL;
        $hash160 = NULL;
        $scriptsig = NULL;
        $index = NULL;
        $value = NULL;
        echo "INPUT\n";
        if (isset($input->coinbase)) {
            $type = "Generation";
            $value = bcdiv("50", floor(pow(2, floor($blocknum / 210000))), 8);
            $scriptsig = $input->coinbase;
        } else {
            $prev = $input->prev_out->hash;
            $index = $input->prev_out->n;
            $scriptsig = $input->scriptSig;
            $simplescriptsig = simplifyscript($scriptsig);
            echo "Simplescriptsig: " . $simplescriptsig . "\$\n";
            $prevtx = pg_fetch_assoc(pg_query_params($db, "SELECT value,type,encode(hash160,'hex') AS hash160 FROM outputs WHERE index=\$1 AND tx=decode(\$2,'hex');", array($index, $prev)));
            if (!$prevtx) {
                error_log("testnet critical failure");
                die("Error: Failed getting prev tx...");
            }
            $value = $prevtx["value"];
            $type = $prevtx["type"];
            $hash160 = $prevtx["hash160"];
            if ($type == "Address") {
                if (preg_match("/^[0-9a-f]+ [0-9a-f]{66,130}\$/", $simplescriptsig)) {
                    $pubkey = preg_replace("/^[0-9a-f]+ ([0-9a-f]{66,130})\$/", "\$1", $simplescriptsig);
                    $hash160 = strtolower(hash160($pubkey));
                    updateKeys($hash160, $pubkey, $blockhash);
                }
            }
            if (is_null($type)) {
                error_log("testnet critical failure");
                die("Error: No input type");
            }
        }
        pg_query_params($db, "INSERT INTO inputs (tx,prev,index,value,scriptsig,hash160,type,block) VALUES (decode(\$1,'hex'),decode(\$2,'hex'),\$3,\$4,\$5,decode(\$6,'hex'),\$7,decode(\$8,'hex'))", array($txhash, $prev, $index, $value, $scriptsig, $hash160, $type, $blockhash));
        echo "Type: " . $type . "\$\n";
        echo "Value: " . $value . "\$\n";
        echo "Prev: " . $prev . "\$\n";
        echo "TxHash: " . $txhash . "\$\n";
        echo "Index: " . $index . "\$\n";
        echo "ScriptSig: " . $scriptsig . "\$\n";
        echo "Hash160: " . $hash160 . "\$\n";
    }
    $index = -1;
    $txvalue = "0";
    foreach ($tx->out as $output) {
        $hash160 = NULL;
        $type = NULL;
        $index++;
        echo "OUTPUT\n";
        $value = $output->value;
        $txvalue = bcadd($txvalue, $value, 8);
        $scriptpubkey = $output->scriptPubKey;
        $simplescriptpk = simplifyscript($scriptpubkey);
        echo "Simplescriptpubkey: " . $simplescriptpk . "\$\n";
        //To pubkey
        if (preg_match("/^[0-9a-f]{66,130} OP_CHECKSIG\$/", $simplescriptpk)) {
            $type = "Pubkey";
            $pubkey = preg_replace("/^([0-9a-f]{66,130}) OP_CHECKSIG\$/", "\$1", $simplescriptpk);
            $hash160 = strtolower(hash160($pubkey));
            updateKeys($hash160, $pubkey, $blockhash);
        }
        //To BC address
        if (preg_match("/^OP_DUP OP_HASH160 [0-9a-f]{40} OP_EQUALVERIFY OP_CHECKSIG\$/", $simplescriptpk)) {
            $type = "Address";
            $hash160 = preg_replace("/^OP_DUP OP_HASH160 ([0-9a-f]{40}) OP_EQUALVERIFY OP_CHECKSIG\$/", "\$1", $simplescriptpk);
            updateKeys($hash160, NULL, $blockhash);
        }
        if (is_null($type)) {
            $type = "Strange";
        }
        pg_query_params($db, "INSERT INTO outputs (tx,index,value,scriptpubkey,hash160,type,block) VALUES (decode(\$1,'hex'),\$2,\$3,\$4,decode(\$5,'hex'),\$6,decode(\$7,'hex'));", array($txhash, $index, $value, $scriptpubkey, $hash160, $type, $blockhash));
        echo "Hash160: " . $hash160 . "\$\n";
        echo "Type: " . $type . "\$\n";
        echo "Index: " . $index . "\$\n";
        echo "Value: " . $value . "\$\n";
        echo "Scriptpubkey: " . $scriptpubkey . "\$\n";
    }
    pg_query_params($db, "UPDATE transactions SET fee=(SELECT (SELECT sum(value) FROM inputs WHERE tx=decode(\$1,'hex'))-(SELECT sum(value) from outputs WHERE tx=decode(\$1,'hex'))) WHERE hash=decode(\$1,'hex');", array($txhash));
    return $txvalue;
}
function pubKeyToAddress($pubkey)
{
    return hash160ToAddress(hash160($pubkey));
}
 public function pubKeyToAddress($pubkey)
 {
     return $this->hash160ToAddress(hash160($pubkey));
 }