I think the right way to whitelist an ip is to put something like this in your bitcoin.conf file:
rpcallowip=yourwebserverip
I didn't do this. I instead wrote some ocaml code that could on the one hand locally ask bitcoind questions and on the other hand handle simple (but obscure) Q&A via a socket. I don't recommend doing it like I did, but I have trouble getting bitcoind to do what I want.
I'll put some mysql and php here in case it helps you or anyone else who comes across this thread later. In the process of cleaning and documenting these clips of code, I may have introduced errors, but it should give the idea. Also, I'm not giving the full environment (e.g., connecting to mysql from php).
Use at your own risk, and all other such caveats.
This code was for making bitcoin payments to activate an access code in order to obtain access to an online document.
Here is the relevant mysql table. I had a collection of (bitcoin-address,access-code) pairs for each document.
CREATE TABLE IF NOT EXISTS `docaccesscode` (
`docaccesscodeid` mediumint(9) NOT NULL AUTO_INCREMENT,
`docsha` char(64) NOT NULL,
-- price (in satoshis)
`docaccesscodeprice` BIGINT(19),
-- bitcoin address
`docaccesscodeaddr` varchar(34),
-- "access code"
`docaccesscode` varchar(21),
-- hash of access code
`docaccesscodehash` char(64) NOT NULL UNIQUE,
-- has this access code/payment address already been used? If so, put the timestamp. If not, it is NULL
`docaccesscodeused` int(11) DEFAULT NULL,
-- has the payment been made?
`docaccesscodeactive` bool NOT NULL DEFAULT false,
PRIMARY KEY (`docaccesscodeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;
Here is php code to request an access code and an address to pay to activate the access code.
// A helper function to write the number of satoshis in a nice way as "bitcoins, mbits or satoshis"
function satoshivalstr ($s) {
if ($s > 100000000) {
return (($s / 100000000)." bitcoins");
} else if ($s == 100000000) {
return "1 bitcoin";
} else if ($s > 100000) {
return (($s / 100000)." mbits (i.e., ".($s / 100000000)." bitcoins)");
} else if ($s == 100000) {
return "1 mbit (i.e., 0.001 bitcoins)";
} else {
return ($s." satoshis (i.e., ".($s / 100000000)." bitcoins)");
}
}
$tm = time();
// grab an unused address/access code
$newcodel = mysql_query("select docaccesscodeid,docaccesscodeprice,docaccesscodeaddr,docaccesscode from `docaccesscode` where docaccesscodeused
IS NULL and docaccesscodecurr=0 and docsha='".$_REQUEST['d']."' ORDER BY RAND() LIMIT 1");
// set it as used (and record when it was "exposed")
mysql_query("update `docaccesscode` SET docaccesscodeused=".$tm." WHERE docaccesscodeid=".$newcode['docaccesscodeid']);
// Say "here is your access code and please pay this address"
echo 'Access code: '.$newcode['docaccesscode'].'<br/>Pay '.satoshivalstr($newcode['docaccesscodeprice']).' to the address '.$newcode['docaccesscodeaddr'].' to ac\
tivate the access code.</div>';
Clip of php code for checking if a payment has been made (activating an access code). This first asks the mysql database. If it says it's active, the document is presented. If it says it's not yet active (payment has not yet been made), then a function cs() initalizes a socket connecting to my "payment processor server". I send "P".$ach through this socket to indicate that I want to know if the payment for the access code with hash $ach has been received. The payment processor server knows which bitcoin address this corresponds to (so I'm not sending the address itself). The payment processor server (some ocaml code) asks bitcoind about the right address and either responds with the character 'P' for "Paid" or something else. If the socket says its been paid, then the mysql database is updated accordingly and the document is presented.
if ($_REQUEST['accesscode']) {
$ach = hash('ripemd160',$_REQUEST['accesscode']);
$docaccessl = mysql_query("select docaccesscodeactive from `docaccesscode` where docsha='".$_REQUEST['d']."' AND docaccesscodehash='".$ach."'");
if ($docaccess = mysql_fetch_array($docaccessl)) {
if ($docaccess['docaccesscodeactive']) {
presentdoc($doc);
} else {
if ($sock = cs()) {
socket_write($sock,"P".$ach,41);
$o = socket_read($sock,1);
if ($o == 'P') {
mysql_query("update `docaccesscode` set docaccesscodeactive=1 where docsha='".$_REQUEST['d']."' AND docaccesscodehash='".$ach."'");
presentdoc($doc);
} else {
echo 'Access to this document is currently restricted. Your access will be granted after your payment has been received and processed.';
}
} else {
echo 'The payment processor server appears to be down.';
}
}
}
} else {
echo 'You need an active access code to see the document.'
}