Re: JSON-RPC を使用したサンプルアカウントシステムが必要

人物: dwdollar

これをずっと投稿しようと思っていた。シンプルな例として整理して、理解しやすくしたかった。今やそのチャンスがいつになるか分からない。だから……このまま投稿することにする。誰かの役に立つかもしれない。

これはおそらく最良のアプローチではない(少し前にサトシと話した結果)。実際、後から追加されて Version .3 に入っている API の新機能はまだ適用していない。だが、実戦で検証されている。壊れていない(まだ)ものを直す必要があるか? Bitcoin サーバーを動かしているマシン上で別プロセスとして動く。唯一省略したのは while ループの break ハンドラだけだ。「list(something_inside)」を見たら、それは SQLObject を使ったデータベースへのクエリだと思ってくれ。

もう一度見直したら、ここに改訂版を投稿する。

#! /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)