Re: Sample account system using JSON-RPC needed

Figures: dwdollar

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)