2017-04-11 17:13:25 -07:00
|
|
|
import requests
|
|
|
|
import json
|
|
|
|
|
|
|
|
from pyZcash.settings import *
|
|
|
|
|
|
|
|
class ZDaemon(object):
|
|
|
|
|
|
|
|
id_count = 0
|
|
|
|
|
2017-04-18 14:57:33 -07:00
|
|
|
def __init__(self, network=NETWORK, user=RPCUSER, password=RPCPASSWORD, timeout=TIMEOUT):
|
2017-04-11 17:13:25 -07:00
|
|
|
#TODO: check utf safety
|
2017-04-18 14:57:33 -07:00
|
|
|
self.network = network
|
2017-04-11 17:13:25 -07:00
|
|
|
self.user = user.encode('utf8')
|
|
|
|
self.password = password.encode('utf8')
|
|
|
|
self.timeout = timeout
|
|
|
|
|
|
|
|
def _call(self, method, *args):
|
|
|
|
jsondata = json.dumps({ 'version': '2',
|
|
|
|
'method': method,
|
|
|
|
'params': args,
|
|
|
|
'id': self.id_count})
|
|
|
|
|
2017-04-18 14:57:33 -07:00
|
|
|
r = requests.post(self.network, auth=(self.user,self.password), data=jsondata, timeout=self.timeout)
|
2017-04-11 17:13:25 -07:00
|
|
|
|
|
|
|
self.id_count += 1
|
2017-04-18 14:57:33 -07:00
|
|
|
|
2017-04-11 17:13:25 -07:00
|
|
|
resp = json.loads(r.text)
|
|
|
|
|
|
|
|
#TODO: deal with errors better.
|
|
|
|
error = resp['error']
|
|
|
|
if error:
|
2019-10-14 13:09:04 -07:00
|
|
|
print('Error calling {}:{}'.format(method, error))
|
2017-04-11 17:13:25 -07:00
|
|
|
|
|
|
|
return resp['result']
|
|
|
|
|
2017-04-18 14:57:33 -07:00
|
|
|
|
2017-04-11 17:13:25 -07:00
|
|
|
#Block Info
|
|
|
|
def getBlockHash(self, blockheight):
|
|
|
|
return self._call('getblockhash', blockheight)
|
|
|
|
|
|
|
|
def getBlockByHash(self, blockhash):
|
|
|
|
return self._call('getblock', blockhash)
|
|
|
|
|
|
|
|
def getBlockByHeight(self, blockheight):
|
|
|
|
return self.getBlockByHash(self.getBlockHash(blockheight))
|
|
|
|
|
2017-04-18 15:55:48 -07:00
|
|
|
# Custom methods to get Network Info
|
2017-04-11 17:13:25 -07:00
|
|
|
def getNetworkHeight(self):
|
|
|
|
return self._call('getblockcount')
|
|
|
|
|
|
|
|
def getNetworkDifficulty(self):
|
|
|
|
return self._call('getdifficulty')
|
|
|
|
|
|
|
|
def getVersion(self):
|
|
|
|
info = self._call('getnetworkinfo')
|
|
|
|
client = info['subversion']
|
|
|
|
version = client.strip('/').split(':')[1]
|
|
|
|
return version
|
|
|
|
|
|
|
|
def getConnectionCount(self):
|
|
|
|
return self._call('getconnectioncount')
|
|
|
|
|
|
|
|
|
2017-04-18 15:55:48 -07:00
|
|
|
# Wallet Info (transparent)
|
|
|
|
def getbalance(self):
|
|
|
|
return self._call('getbalance')
|
|
|
|
|
|
|
|
def listunspent(self, minconf=1):
|
2017-04-11 17:13:25 -07:00
|
|
|
return self._call('listunspent', minconf)
|
|
|
|
|
|
|
|
#Raw Txs
|
2017-04-18 15:55:48 -07:00
|
|
|
def gettransaction(self, txid):
|
2017-04-11 17:13:25 -07:00
|
|
|
return self._call('gettransaction', txid)
|
|
|
|
|
2017-05-03 16:50:37 -07:00
|
|
|
def getrawtransaction(self, txid, verbose=0):
|
|
|
|
# default verbose=0 returns serialized, hex-encoded data
|
|
|
|
# verbose=1, returns a JSON obj of tx
|
|
|
|
return self._call('getrawtransaction', txid, verbose)
|
|
|
|
|
|
|
|
def decoderawtransaction(self, txhex):
|
|
|
|
return self.call('decoderawtransaction', txhex)
|
|
|
|
|
2017-04-11 17:13:25 -07:00
|
|
|
# taddr methods
|
2017-04-18 15:55:48 -07:00
|
|
|
def getnewaddress(self):
|
|
|
|
return self._call('getnewaddress')
|
2017-04-11 17:13:25 -07:00
|
|
|
|
2017-04-18 15:55:48 -07:00
|
|
|
def sendtoaddress(self, taddress, amount):
|
2017-04-11 17:13:25 -07:00
|
|
|
return self._call('sendtoaddress', taddress, amount)
|
|
|
|
|
2017-04-20 10:28:19 -07:00
|
|
|
def listunspent(self):
|
|
|
|
return self._call('listunspent')
|
|
|
|
|
|
|
|
# Custom method to find a taddr with spendable utxos for z_sendmany
|
2017-04-20 14:30:32 -07:00
|
|
|
def find_taddr_with_unspent(self):
|
2017-04-20 10:28:19 -07:00
|
|
|
unspent = self._call('listunspent')
|
2017-04-20 14:30:32 -07:00
|
|
|
for utxo in unspent:
|
|
|
|
if utxo['spendable'] == True and utxo['amount'] > 0.1:
|
|
|
|
# Check that it's not a coinbase tx
|
|
|
|
tx = zd.gettransaction(utxo['txid'])
|
|
|
|
if 'generated' not in tx:
|
|
|
|
return tx['address']
|
2017-04-18 15:55:48 -07:00
|
|
|
|
2017-04-20 15:10:03 -07:00
|
|
|
def sweep_coinbase(self, zaddr):
|
2017-10-18 10:03:34 -07:00
|
|
|
addrs = []
|
2017-04-20 15:10:03 -07:00
|
|
|
utxos = self.listunspent()
|
|
|
|
for utxo in utxos:
|
2017-10-18 10:03:34 -07:00
|
|
|
if 'generated' in utxo and utxo['generated'] == True:
|
|
|
|
if utxo['address'] not in addrs:
|
|
|
|
addrs.append(utxo['address'])
|
|
|
|
for addr in addrs:
|
|
|
|
res = self._call('z_shieldcoinbase', addr, zaddr)
|
2019-10-14 13:09:04 -07:00
|
|
|
print('{}'.format(res))
|
2017-04-20 15:10:03 -07:00
|
|
|
|
2017-04-11 17:13:25 -07:00
|
|
|
# zaddr methods
|
2017-04-20 18:06:40 -07:00
|
|
|
def z_gettotalbalance(self):
|
|
|
|
return self._call('z_gettotalbalance')
|
|
|
|
|
2017-04-11 17:13:25 -07:00
|
|
|
def z_getnewaddress(self):
|
|
|
|
return self._call('z_getnewaddress')
|
|
|
|
|
|
|
|
def z_listaddresses(self):
|
|
|
|
return self._call('z_listaddresses')
|
|
|
|
|
2017-04-18 14:57:33 -07:00
|
|
|
def z_listreceivedbyaddress(self, zaddr, minconf=1):
|
|
|
|
return self._call('z_listreceivedbyaddress', zaddr, minconf)
|
|
|
|
|
2017-04-20 10:02:37 -07:00
|
|
|
def z_getoperationstatus(self, opid):
|
|
|
|
return self._call('z_getoperationstatus', ["{0}".format(opid)])
|
|
|
|
|
|
|
|
def z_getoperationresult(self, opid):
|
|
|
|
return self._call('z_getoperationresult', ["{0}".format(opid)])
|
|
|
|
|
2017-04-18 14:57:33 -07:00
|
|
|
# With addition of encrypted memo field
|
2017-05-13 21:25:59 -07:00
|
|
|
def z_sendmany(self, sender, receiver, amount=0.0001, memo='', fee=0.0001):
|
2017-04-18 14:57:33 -07:00
|
|
|
amts_array = []
|
|
|
|
if memo == '':
|
|
|
|
amounts = {"address": receiver, "amount": amount}
|
|
|
|
else:
|
|
|
|
memo = memo.encode('hex')
|
|
|
|
amounts = {"address": receiver, "amount": amount, "memo": memo}
|
|
|
|
amts_array.append(amounts)
|
2017-05-13 21:25:59 -07:00
|
|
|
return self._call('z_sendmany', sender, amts_array, 1, fee)
|