これをずっと投稿しようと思っていた。シンプルな例として整理して、理解しやすくしたかった。今やそのチャンスがいつになるか分からない。だから……このまま投稿することにする。誰かの役に立つかもしれない。
これはおそらく最良のアプローチではない(少し前にサトシと話した結果)。実際、後から追加されて 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)