Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: MrBison on September 14, 2010, 03:58:29 PM



Title: A PHP digital bitcoin store
Post by: MrBison on September 14, 2010, 03:58:29 PM
This is a (very bad) piece of PHP code that uses JSON-RPC to create a bitcoin store for digital information (For example, a password to a certain file or log-in info for a certain site). It uses JSON-RPC PHP client script to connect with bitcoind.

Code:
<?php
// (c) MrBison [m.zubrov@gmail.com], 2010
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful (and fun!),
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

require_once ('./includes/jsonRPCClient.php');

function 
randomseed()
{
  list(
$tmp1$tmp2) = explode(' 'microtime());
  return (float) 
$tmp1 + ((float) $tmp2 100000);
}
mt_srand(randomseed());

if (!isset(
$_COOKIE["bitcoinsessionid"])) { $session mt_rand() + (int)(microtime()*1000); } else { $session = (int) $_COOKIE["bitcoinsessionid"]; }
if (!
is_numeric($session)) die ("This looks like an SQL injection attempt.");
setcookie("bitcoinsessionid"$sessiontime()+2592000); //the cookie is valid for 30 days.

$bitcoin = new jsonRPCClient("http://rpcuser:rpcpassword@127.0.0.1:8332/") or die("Cannot connect"); 
$link mysql_connect("mysqlserver""mysqluser""mysqlpass") or die("Could not connect: " mysql_error());
mysql_select_db("bitcoin");

if ((isset(
$_GET["getaddress"])) && (is_numeric($_GET["getaddress"]))) {
// if we are asked for an address
$id $_GET["getaddress"];

$query "SELECT address FROM addresses WHERE id = "$id " AND sessionid = " $session;

$result mysql_query($query) or die("Query failed : " mysql_error());

$row mysql_fetch_array($resultMYSQL_ASSOC); if (isset($row["address"])) { $address $row["address"]; } else {
$address $bitcoin->getnewaddress("Temporary address") or die ("Sorry, cannot create an address");
$query "INSERT INTO addresses (id, address, sessionid) VALUES (" $id ", \"" $address "\"," $session ")";
mysql_query($query) or die("Query failed : " mysql_error()); }

//here we check if someone else didn't already purchase this item
$query "SELECT address FROM addresses WHERE id = "$id " AND sessionid != " $session;
$result mysql_query($query) or die("Query failed : " mysql_error());
$row mysql_fetch_array($resultMYSQL_ASSOC); if (isset($row["address"])) die("Sorry, this item is already being partially or fully paid by someone else."); 

$query "SELECT price FROM goods WHERE id = " $id;
$pricex mysql_query($query);
$row mysql_fetch_array($pricexMYSQL_ASSOC);
$price $row["price"];

$paid = (float)$bitcoin->getreceivedbyaddress($address1);

echo 
"Please send " $price " to BitCoin address " $address " . <br />";
echo 
"Already sent: " $paid "<br />";
echo 
"<a href='?getaddress=" $id "'>Refresh</a>";
if (
$price <= $paid) {
echo 
"Paid fully.<br />";
$result mysql_query("SELECT name, description, price FROM goods WHERE id = " $id) or die("Query failed 0: " mysql_error());
$row mysql_fetch_array($resultMYSQL_ASSOC);
echo 
"Your password is: <b>" $row["password"] . "</b><br /><a href='?delete=" $id "'>Confirm and delete</a><br />"; }
else {
echo 
"You have "$price $paid " left to pay. <br />"; }

else

if ((isset(
$_GET["delete"])) && (is_numeric($_GET["delete"]))) {
$id $_GET["delete"];
$query "SELECT address FROM addresses WHERE id = "$id " AND sessionid = " $session//Only the ones who paid fully can delete items
$result mysql_query($query) or die("Query failed : " mysql_error()); $row mysql_fetch_array($resultMYSQL_ASSOC);
if (isset(
$row["address"])) { $address $row["address"]; } else echo "Sorry, this operation is permitted only to users that purchased the item.";
$query "SELECT price FROM goods WHERE id = " $id;
$pricex mysql_query($query);
$row mysql_fetch_array($pricexMYSQL_ASSOC);
$price $row["price"];
$paid = (float)$bitcoin->getreceivedbyaddress($address1);
if (
$paid >= $price) {
//if this user really purchased it
$query "DELETE FROM goods WHERE id = "$id;
$result mysql_query($query) or die("Cannot delete the item: " mysql_error());
}
}

else if(!isset(
$_GET["show"]) || !is_numeric($_GET["show"])) {
$result mysql_query("SELECT id, name, description, price FROM goods") or die("Query failed 1: " mysql_error()); 
while (
$row mysql_fetch_array($resultMYSQL_ASSOC)) {
printf ("<a href='bitcoin.php?show=%s'><b>%s</b></a><br />%s<br />Price: <b>%s</b>"$row["id"], $row["name"], $row["description"], $row["price"]); }
} else {
$id $_GET["show"];
$result mysql_query("SELECT name, description, price FROM goods WHERE id = " $id) or die("Query failed 2: " mysql_error());
while (
$row mysql_fetch_array($resultMYSQL_ASSOC)) {
printf ("<b>%s</b><br />%s<br />Price: <b>%s</b><br /><a href='bitcoin.php?getaddress=%s'>Buy with BitCoin</a>"$row["name"], $row["description"], $row["price"], $id); }

}

mysql_free_result($result);
mysql_close($link);
?>

The system is supposed to be anonymous (so it uses SessionIDs) and probably even secure (since all data sent by user are numeric (ID of an item or SessionID), they are filtered).

It uses two MySQL tables: "goods" and "addresses". The first one contains 5 fields, "id" (int), "name" (varchar), "description" (mediumtext), "price" (double) and "password" (mediumtext, this field contains the information user gets when he pays for an item fully). "addresses" contains of "id" (the ID of an item), "address" (bitcoin address used to receive money for that item) and "sessionid" (SessionID of a user who decides to buy an item).

I know, this code is bad, but 1) it works (it was tested :) ), 2) I just don't know where should I use it :)
Maybe this will serve as some kind of a tutorial to some bitcoiners wishing to use JSON-RPC and PHP, or anything else, I don't know.


Title: Re: A PHP digital bitcoin store
Post by: BioMike on September 14, 2010, 04:47:51 PM
Damn, that's hard to read. With a quick view, it looks solid/usable.

Might be more useful/structured as an oo class.


Title: Re: A PHP digital bitcoin store
Post by: MrBison on September 16, 2010, 05:24:11 PM
Added some comments, made some fixes, remade it into an archive with JSON-RPC (authors specified in a JSON-RPC file). Both JSON-RPC PHP and this script are licensed under GPLv2 (or later).


Title: Re: A PHP digital bitcoin store
Post by: sergio on May 15, 2012, 08:39:08 AM
The overall code is good, however it does have a few problems that are easy to fix.

Problem 1:
Let say buyer A chooses to purchase item 1, but  does not pay for it, well item 1 gets reserved for buyer A so that he/she can pay for it, now lets say we have another buyer B that tries to purchase the same item he will get a warning that the item is being purchased which is correct, but then the original buyer A gets the same message and no one can purchase the item now.

Problem 2:
Let say we have a buyer that gets a bitcoin address for each of the items in the cart by clicking on purchase, but never sends any bitcoins, now  none of the items are available anymore to anyone else.

When does it work:
It does work when a buyer makes the purchase and sends the bitcoin to the provided address and no one interferes with the purchase by trying to buyit.

How to fix:
add 2 extra fields to the goods database, one indicating that the item has been reserved for purchase by the buyer that generated the bitcoin address, and another field with a time field to expire the purchase if it does not get payed within a certain amount of time.
Also provide some anti spam mechanism to prevent a buyer from selecting everything, limit the amount of purchases until they get paid.

I will say the code is overall pretty good it just needs a little fixing, the design is nice and simple which is a good thing.




Title: Re: A PHP digital bitcoin store
Post by: sergio on June 13, 2020, 12:15:23 AM
I used this script for many years with some modifications, and it worked quite well for selling voip cards using btcvoip.com now dead due to market reasons, I still had this script on my server but it was stolen by Mexican police, when they into my place broke and did massive destruction.

Thanks for the script it really helped and overall it works well, one of the things I had to change was session timeout which was too low, especially now that bitcoin transactions take a long time, and some very minor changes.