Sample account system using JSON-RPC needed
We need someone to write sample code, preferably Python or Java, showing the recommended way to use the JSON-RPC interface to create an account system. Most sites that sell things will need something like this. Someone who’s kept up on the JSON-RPC threads here should have some idea how it should work.
When a user is logged in to their account, you show the bitcoin address they can send to to add funds. Before showing it, you check if it’s been used, if it has then you replace it with a new one (getnewaddress
You use getreceivedbylabel
If you’re requiring more than 0 confirmations, it’s nice if you show the current balance (0 confirmations) and the available balance (1 or more confirmations), so they can immediately see that their payment is acknowledged. Not all sites need to wait for confirmations, so the dual current & available should be optional. Most sites selling digital goods are fine to accept 0 confirmations.
A nice sample app for this would be a simple bank site, which would have the above, plus the option to send a payment to a bitcoin address. The sample code should be the simplest possible with the minimum extra stuff to make it a working site.
vekja.net is an example of a site like this.
bitcoinmarket.com is doing all of these things now. perhaps the author of that site can share some code as well.
I should also point out that this site has some JSON code in Python.
http://www.alloscomp.com/bitcoin/
Specifically this code that checks the balance and sends it to a static address.
#!/usr/bin/python
import jsonrpc
MyBCAddress = 'YOUR BITCOIN ADDRESS HERE'
b = jsonrpc.ServiceProxy("http://localhost:8332/")
bal = float(b.getbalance())
if bal > 0.01:
print "We have a balance of {0:.2f}BC. Sending...".format(bal)
b.sendtoaddress(MyBCAddress,bal)
else:
print "No coins here." I’ve been meaning to post this for some time. I wanted to clean it up into a simple example, so it would be easy to understand. I don’t know when I’ll have a chance now. So… I’ll just go ahead and post it as is. Maybe it will help somebody.
It probably isn’t the best approach (after talking to Satoshi a while back). In fact, I haven’t tried applying the new functions in the API, that were added later on and now in Version .3. But, it is battle tested. Why fix what isn’t broken (yet)? It runs as a separate process on the machine with the Bitcoin server. The only thing I left out was a break handler for the while loop. Anytime you see “list(something_inside)”, realize it’s a query to the database using SQLObject.
When I go through it again, I’ll post a revision here.
#! /usr/bin/python
import jsonrpc
import time
import datetime
from database import *
class BitcoinInterface(object):
def __init__(self):
self.access = jsonrpc.ServiceProxy("http://127.0.0.1:8332")
return
def issueBitcoinAddresses(self):
localBitcoinAddresses = list(Address.select(AND(Address.q.type_ == "localBitcoin", Address.q.value == None))) # Get all unassigned local Bitcoin Addresses
for localBitcoinAddress in localBitcoinAddresses:
localBitcoinAddress.value = self.access.getnewaddress()
client = Client.get(localBitcoinAddress.clientID)
print "New Address:\nUsername: %s\nClientID: %i\nValue: %s\n" % (client.username, client.id, localBitcoinAddress.value)
return
def takeDeposits(self):
localBitcoinAddresses = list(Address.select(AND(Address.q.type_ == "localBitcoin", Address.q.value != None))) # Get all assigned local Bitcoin Addresses
for localBitcoinAddress in localBitcoinAddresses:
amountReceived = self.access.getamountreceived(localBitcoinAddress.value)
if amountReceived > localBitcoinAddress.amountReceived:
client = Client.get(localBitcoinAddress.clientID)
quantity = amountReceived - localBitcoinAddress.amountReceived
client.bitcoins = client.bitcoins + quantity
localBitcoinAddress.amountReceived = amountReceived
transaction = Transaction(clientID = client.id)
transaction.datetime = datetime.datetime.now()
transaction.type_ = "Deposit"
transaction.quantity = quantity # Transaction quantity is positive for "Deposit"
print "Deposit:\nUsername: %s\nClientID: %i\nQuantity: %f\n" % (client.username, client.id, quantity)
return
def issueWithdrawals(self):
clients = list(Client.select(Client.q.bitcoinsToWithdraw > 0))
for client in clients:
if client.bitcoinsToWithdraw <= client.bitcoins: # Redundancy check
foreignBitcoinAddress = list(Address.select(AND(Address.q.clientID == client.id, Address.q.type_ == "foreignBitcoin")))[0]
try:
quantity = client.bitcoinsToWithdraw
self.access.sendtoaddress(foreignBitcoinAddress.value, quantity)
client.bitcoins = client.bitcoins - quantity
transaction = Transaction(clientID = client.id)
transaction.datetime = datetime.datetime.now()
transaction.type_ = "Withdrawal"
transaction.quantity = -quantity # Transaction quantity is negative for "Withdrawal"
client.bitcoinsToWithdraw = 0
print "Withdrawal:\nUsername: %s\nClientID: %i\nQuantity: %f\n" % (client.username, client.id, quantity)
except:
print "Failed Withdrawal:\nUsername: %s\nClientID: %i\nQuantity: %f\n" % (client.username, client.id, client.bitcoinsToWithdraw)
else:
print "Failed Withdrawal, Not Enough Bitcoins:\nUsername: %s\nClientID: %i\n" % (client.username, client.id)
return
bitcoinInterface = BitcoinInterface()
while 1:
bitcoinInterface.issueBitcoinAddresses()
bitcoinInterface.takeDeposits()
bitcoinInterface.issueWithdrawals()
time.sleep(300)