Merge branch 'master' of github.com:zcash-hackworks/ZBXCAT

This commit is contained in:
Jay Graber 2017-10-19 11:10:12 -07:00
commit 9f01f7fc30
7 changed files with 271 additions and 409 deletions

View File

@ -67,8 +67,6 @@ class bitcoinProxy():
def get_keys(self, funder_address, redeemer_address): def get_keys(self, funder_address, redeemer_address):
fundpubkey = CBitcoinAddress(funder_address) fundpubkey = CBitcoinAddress(funder_address)
redeempubkey = CBitcoinAddress(redeemer_address) redeempubkey = CBitcoinAddress(redeemer_address)
# fundpubkey = self.bitcoind.getnewaddress()
# redeempubkey = self.bitcoind.getnewaddress()
return fundpubkey, redeempubkey return fundpubkey, redeempubkey
def privkey(self, address): def privkey(self, address):
@ -79,7 +77,8 @@ class bitcoinProxy():
redeemerAddr = CBitcoinAddress(redeemer) redeemerAddr = CBitcoinAddress(redeemer)
if type(commitment) == str: if type(commitment) == str:
commitment = x(commitment) commitment = x(commitment)
# h = sha256(secret) else:
raise ValueError("Commitment was not a string: {0}".format(commitment))
blocknum = self.bitcoind.getblockcount() blocknum = self.bitcoind.getblockcount()
print("Current blocknum on Bitcoin: ", blocknum) print("Current blocknum on Bitcoin: ", blocknum)
redeemblocknum = blocknum + locktime redeemblocknum = blocknum + locktime

View File

@ -9,43 +9,38 @@ import xcat.utils as utils
from xcat.protocol import Protocol from xcat.protocol import Protocol
from xcat.trades import Trade from xcat.trades import Trade
class CLI():
def __init__(self):
self.db = DB()
self.protocol = Protocol()
def save_state(trade, tradeid): def checkSellStatus(self, tradeid):
db = DB() trade = self.db.get(tradeid)
utils.save(trade) status = self.seller_check_status(trade)
db.create(trade, tradeid)
def checkSellStatus(tradeid):
db = DB()
protocol = Protocol()
trade = db.get(tradeid)
status = seller_check_status(trade)
print("Trade status: {0}\n".format(status)) print("Trade status: {0}\n".format(status))
if status == 'init': if status == 'init':
userInput.authorize_fund_sell(trade) userInput.authorize_fund_sell(trade)
fund_tx = protocol.fund_sell_contract(trade) fund_tx = self.protocol.fund_sell_contract(trade)
print("Sent fund_tx", fund_tx) print("Sent fund_tx", fund_tx)
trade.sell.fund_tx = fund_tx trade.sell.fund_tx = fund_tx
save_state(trade, tradeid) self.db.create(trade, tradeid)
elif status == 'buyerFunded': elif status == 'buyerFunded':
secret = db.get_secret(tradeid) secret = self.db.get_secret(tradeid)
print("Retrieved secret to redeem funds for " print("Retrieved secret to redeem funds for "
"{0}: {1}".format(tradeid, secret)) "{0}: {1}".format(tradeid, secret))
txs = protocol.seller_redeem_p2sh(trade, secret) txs = self.protocol.seller_redeem_p2sh(trade, secret)
if 'redeem_tx' in txs: if 'redeem_tx' in txs:
trade.buy.redeem_tx = txs['redeem_tx'] trade.buy.redeem_tx = txs['redeem_tx']
print("Redeem tx: ", txs['redeem_tx']) print("Redeem tx: ", txs['redeem_tx'])
if 'refund_tx' in txs: if 'refund_tx' in txs:
trade.buy.redeem_tx = txs['refund_tx'] trade.buy.redeem_tx = txs['refund_tx']
print("Buyer refund tx: ", txs['refund_tx']) print("Buyer refund tx: ", txs['refund_tx'])
txs = protocol.refund_contract(trade.sell) # Refund to seller txs = self.protocol.refund_contract(trade.sell) # Refund to seller
print("Your refund txid: ", txs['refund_tx']) print("Your refund txid: ", txs['refund_tx'])
save_state(trade, tradeid) self.db.create(trade, tradeid)
# Remove from db? Or just from temporary file storage # Remove from db? Or just from temporary file storage
utils.cleanup(tradeid) utils.cleanup(tradeid)
@ -59,11 +54,10 @@ def checkSellStatus(tradeid):
"this trade.") "this trade.")
def buyer_check_status(trade): def buyer_check_status(self, trade):
protocol = Protocol() sellState = self.protocol.check_fund_status(
sellState = protocol.check_fund_status(
trade.sell.currency, trade.sell.p2sh) trade.sell.currency, trade.sell.p2sh)
buyState = protocol.check_fund_status( buyState = self.protocol.check_fund_status(
trade.buy.currency, trade.buy.p2sh) trade.buy.currency, trade.buy.p2sh)
if sellState == 'funded' and buyState == 'empty': if sellState == 'funded' and buyState == 'empty':
return 'sellerFunded' # step1 return 'sellerFunded' # step1
@ -79,11 +73,10 @@ def buyer_check_status(trade):
return 'init' return 'init'
def seller_check_status(trade): def seller_check_status(self, trade):
protocol = Protocol() sellState = self.protocol.check_fund_status(
sellState = protocol.check_fund_status(
trade.sell.currency, trade.sell.p2sh) trade.sell.currency, trade.sell.p2sh)
buyState = protocol.check_fund_status( buyState = self.protocol.check_fund_status(
trade.buy.currency, trade.buy.p2sh) trade.buy.currency, trade.buy.p2sh)
if sellState == 'funded' and buyState == 'empty': if sellState == 'funded' and buyState == 'empty':
return 'sellerFunded' # step1 return 'sellerFunded' # step1
@ -99,11 +92,9 @@ def seller_check_status(trade):
return 'init' # step0 return 'init' # step0
def checkBuyStatus(tradeid): def checkBuyStatus(self, tradeid):
db = DB() trade = self.db.get(tradeid)
protocol = Protocol() status = self.buyer_check_status(trade)
trade = db.get(tradeid)
status = buyer_check_status(trade)
print("Trade status: {0}\n".format(status)) print("Trade status: {0}\n".format(status))
if status == 'init': if status == 'init':
print("Trade has not yet started, waiting for seller to fund the " print("Trade has not yet started, waiting for seller to fund the "
@ -116,24 +107,24 @@ def checkBuyStatus(tradeid):
"behalf.") "behalf.")
print("Trade commitment", trade.commitment) print("Trade commitment", trade.commitment)
# if verify_p2sh(trade): # if verify_p2sh(trade):
fund_tx = protocol.fund_contract(trade.buy) fund_tx = self.protocol.fund_contract(trade.buy)
print("\nYou sent this funding tx: ", fund_tx) print("\nYou sent this funding tx: ", fund_tx)
trade.buy.fund_tx = fund_tx trade.buy.fund_tx = fund_tx
save_state(trade, tradeid) self.db.create(trade, tradeid)
elif status == 'sellerRedeemed': elif status == 'sellerRedeemed':
secret = protocol.find_secret_from_fundtx(trade.buy.currency, secret = self.protocol.find_secret_from_fundtx(trade.buy.currency,
trade.buy.p2sh, trade.buy.p2sh,
trade.buy.fund_tx) trade.buy.fund_tx)
if secret is not None: if secret is not None:
print("Found secret on blockchain in seller's redeem tx: ", secret) print("Found secret on blockchain in seller's redeem tx: ", secret)
txs = protocol.redeem_p2sh(trade.sell, secret) txs = self.protocol.redeem_p2sh(trade.sell, secret)
if 'redeem_tx' in txs: if 'redeem_tx' in txs:
trade.sell.redeem_tx = txs['redeem_tx'] trade.sell.redeem_tx = txs['redeem_tx']
print("Redeem txid: ", trade.sell.redeem_tx) print("Redeem txid: ", trade.sell.redeem_tx)
elif 'refund_tx' in txs: elif 'refund_tx' in txs:
trade.sell.redeem_tx = txs['refund_tx'] trade.sell.redeem_tx = txs['refund_tx']
print("Refund tx: ", txs['refund_tx']) print("Refund tx: ", txs['refund_tx'])
save_state(trade, tradeid) self.db.create(trade, tradeid)
print("XCAT trade complete!") print("XCAT trade complete!")
else: else:
# Search if tx has been refunded from p2sh # Search if tx has been refunded from p2sh
@ -141,23 +132,22 @@ def checkBuyStatus(tradeid):
# Import a trade in hex, and save to db # Import a trade in hex, and save to db
def importtrade(tradeid, hexstr=''): def importtrade(self, tradeid, hexstr=''):
protocol = Protocol()
trade = utils.x2s(hexstr) trade = utils.x2s(hexstr)
trade = Trade(trade) trade = Trade(trade)
protocol.import_addrs(trade) self.protocol.import_addrs(trade)
print(trade.toJSON()) print(trade.toJSON())
save_state(trade, tradeid) self.db.create(trade, tradeid)
def wormhole_importtrade(): def wormhole_importtrade(self):
res = subprocess.call('wormhole receive', shell=True) res = subprocess.call('wormhole receive', shell=True)
if res == 0: if res == 0:
tradeid = input("Enter filename of received trade data to import " tradeid = input("Enter filename of received trade data to import "
"(printed on line above): ") "(printed on line above): ")
with open(tradeid) as infile: with open(tradeid) as infile:
hexstr = infile.readline().strip() hexstr = infile.readline().strip()
importtrade(tradeid, hexstr) self.importtrade(tradeid, hexstr)
print("Successfully imported trade using magic-wormhole") print("Successfully imported trade using magic-wormhole")
os.remove(tradeid) os.remove(tradeid)
else: else:
@ -165,9 +155,8 @@ def wormhole_importtrade():
# Export a trade by its tradeid # Export a trade by its tradeid
def exporttrade(tradeid, wormhole=False): def exporttrade(self, tradeid, wormhole=False):
db = DB() trade = self.db.get(tradeid)
trade = db.get(tradeid)
hexstr = utils.s2x(trade.toJSON()) hexstr = utils.s2x(trade.toJSON())
if wormhole: if wormhole:
tradefile = os.path.join(utils.ROOT_DIR, '.tmp/{0}'.format(tradeid)) tradefile = os.path.join(utils.ROOT_DIR, '.tmp/{0}'.format(tradeid))
@ -180,81 +169,69 @@ def exporttrade(tradeid, wormhole=False):
print(hexstr) print(hexstr)
return hexstr return hexstr
def findtrade(self, tradeid):
def findtrade(tradeid): trade = self.db.get(tradeid)
db = DB()
trade = db.get(tradeid)
print(trade.toJSON()) print(trade.toJSON())
return trade return trade
def find_role(self, contract):
def find_role(contract):
protocol = Protocol()
# When regtest created both addrs on same machine, role is both. # When regtest created both addrs on same machine, role is both.
if protocol.is_myaddr(contract.initiator): if self.protocol.is_myaddr(contract.initiator):
if protocol.is_myaddr(contract.fulfiller): if self.protocol.is_myaddr(contract.fulfiller):
return 'test' return 'test'
else: else:
return 'initiator' return 'initiator'
else: else:
if protocol.is_myaddr(contract.fulfiller): if self.protocol.is_myaddr(contract.fulfiller):
return 'fulfiller' return 'fulfiller'
else: else:
raise ValueError('You are not a participant in this contract.') raise ValueError('You are not a participant in this contract.')
def checktrade(tradeid): def checktrade(self, tradeid):
db = DB()
print("In checktrade") print("In checktrade")
trade = db.get(tradeid) trade = self.db.get(tradeid)
if find_role(trade.sell) == 'test': if find_role(trade.sell) == 'test':
input("Is this a test? Both buyer and seller addresses are yours, " input("Is this a test? Both buyer and seller addresses are yours, "
"press 'enter' to test.") "press 'enter' to test.")
checkSellStatus(tradeid) self.checkSellStatus(tradeid)
checkBuyStatus(tradeid) self.checkBuyStatus(tradeid)
checkSellStatus(tradeid) self.checkSellStatus(tradeid)
checkBuyStatus(tradeid) self.checkBuyStatus(tradeid)
elif find_role(trade.sell) == 'initiator': elif find_role(trade.sell) == 'initiator':
print("You are the seller in this trade.") print("You are the seller in this trade.")
# role = 'seller' # role = 'seller'
checkSellStatus(tradeid) self.checkSellStatus(tradeid)
else: else:
print("You are the buyer in this trade.") print("You are the buyer in this trade.")
# role = 'buyer' # role = 'buyer'
checkBuyStatus(tradeid) self.checkBuyStatus(tradeid)
def newtrade(self, tradeid, **kwargs):
def newtrade(tradeid, **kwargs):
protocol = Protocol()
print("Creating new XCAT trade...") print("Creating new XCAT trade...")
utils.erase_trade() utils.erase_trade()
conf = kwargs['conf'] if 'conf' in kwargs else 'regtest' conf = kwargs['conf'] if 'conf' in kwargs else 'regtest'
network = kwargs['network'] if 'network' in kwargs else 'regtest' network = kwargs['network'] if 'network' in kwargs else 'regtest'
tradeid, trade = self.protocol.initialize_trade(tradeid, conf=conf, network=network)
tradeid, trade = protocol.initialize_trade(
tradeid,
conf=conf,
network=network)
print("New trade created: {0}".format(trade)) print("New trade created: {0}".format(trade))
trade = protocol.seller_init(tradeid, trade, network=network) trade, secret = self.protocol.seller_init(tradeid, trade, network=network)
print("\nUse 'xcat exporttrade [tradeid]' to export the trade and sent " self.db.save_secret(tradeid, secret)
"to the buyer.\n") print("\nGenerated a secret preimage to lock funds. This will only "
"be stored locally: {0}".format(secret))
print("\nUse 'xcat exporttrade [tradeid]' to export the trade and send to the buyer.\n")
save_state(trade, tradeid) self.db.create(trade, tradeid)
return trade return trade
def listtrades(self):
def listtrades():
db = DB()
print("Trades") print("Trades")
trade_list = db.dump() trade_list = self.db.dump()
for trade in trade_list: for trade in trade_list:
print("{0}: {1}".format(trade[0], trade[1])) print("{0}: {1}".format(trade[0], trade[1]))
def main(): def main():
cli = CLI()
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawTextHelpFormatter, formatter_class=argparse.RawTextHelpFormatter,
description=textwrap.dedent('''\ description=textwrap.dedent('''\
@ -266,26 +243,15 @@ def main():
findtrade "tradeid" - find a trade by the tradeid findtrade "tradeid" - find a trade by the tradeid
''')) '''))
parser.add_argument("command", action="store", help="list commands")
parser.add_argument( parser.add_argument("arguments", action="store", nargs="*", help="add arguments")
"command", action="store", help="list commands") parser.add_argument("-d", "--debug", action="store_true", help="Enable debug mode. Defaults to false")
parser.add_argument( parser.add_argument("-w", "--wormhole", action="store_true", help="Transfer trade data through magic-wormhole")
"arguments", action="store", nargs="*", help="add arguments") parser.add_argument("-c", "--conf", action="store", help="Use trade data in conf file ('testnet' or 'regtest'), or pass trade data in on cli as json.")
parser.add_argument( parser.add_argument("-n", "--network", action="store", help="Set network to regtest or mainnet. Defaults to testnet while in alpha.")
"-w", "--wormhole", action="store_true", # parser.add_argument("--daemon", "-d", action="store_true", help="Run as daemon process")
help="Transfer trade data through magic-wormhole")
parser.add_argument(
"-c", "--conf", action="store",
help="Use default trade data in conf file.")
parser.add_argument(
"-n", "--network", action="store",
help=("Set network to regtest or mainnet. "
"Defaults to testnet while in alpha."))
# parser.add_argument(
# "--daemon", "-d", action="store_true",
# help="Run as daemon process")
args = parser.parse_args() args = parser.parse_args()
print(args)
if hasattr(args, 'debug'): if hasattr(args, 'debug'):
numeric_level = getattr(logging, 'DEBUG', None) numeric_level = getattr(logging, 'DEBUG', None)
@ -304,35 +270,35 @@ def main():
if command == 'importtrade': if command == 'importtrade':
if args.wormhole: if args.wormhole:
wormhole_importtrade() cli.wormhole_importtrade()
else: else:
if len(args.arguments) != 2: if len(args.arguments) != 2:
utils.throw("Usage: importtrade [tradeid] [hexstring]") utils.throw("Usage: importtrade [tradeid] [hexstring]")
tradeid = args.arguments[0] tradeid = args.arguments[0]
hexstr = args.arguments[1] hexstr = args.arguments[1]
importtrade(tradeid, hexstr) cli.importtrade(tradeid, hexstr)
elif command == 'exporttrade': elif command == 'exporttrade':
if len(args.arguments) < 1: if len(args.arguments) < 1:
utils.throw("Usage: exporttrade [tradeid]") utils.throw("Usage: exporttrade [tradeid]")
tradeid = args.arguments[0] tradeid = args.arguments[0]
exporttrade(tradeid, args.wormhole) cli.exporttrade(tradeid, args.wormhole)
elif command == "findtrade": elif command == "findtrade":
if len(args.arguments) < 1: if len(args.arguments) < 1:
utils.throw("Usage: findtrade [tradeid]") utils.throw("Usage: findtrade [tradeid]")
print("Finding trade") print("Finding trade")
key = args.arguments[0] key = args.arguments[0]
findtrade(key) cli.findtrade(key)
elif command == 'checktrade': elif command == 'checktrade':
if len(args.arguments) < 1: if len(args.arguments) < 1:
utils.throw("Usage: checktrade [tradeid]") utils.throw("Usage: checktrade [tradeid]")
tradeid = args.arguments[0] tradeid = args.arguments[0]
checktrade(tradeid) cli.checktrade(tradeid)
elif command == 'listtrades': elif command == 'listtrades':
listtrades() cli.listtrades()
# TODO: function to tell if tradeid already exists for newtrade # TODO: function to tell if tradeid already exists for newtrade
@ -341,31 +307,27 @@ def main():
utils.throw("Usage: newtrade [tradeid]") utils.throw("Usage: newtrade [tradeid]")
tradeid = args.arguments[0] tradeid = args.arguments[0]
if args.conf is None: if args.conf is None:
newtrade(tradeid, network=NETWORK, conf='cli') conf = 'cli'
else: else:
newtrade(tradeid, network=NETWORK, conf=args.conf) conf = args.conf
cli.newtrade(tradeid, network=NETWORK, conf=conf)
elif command == "daemon": elif command == "daemon":
# TODO: not implemented # TODO: not implemented
print("Run as daemon process") print("Run as daemon process")
# Ad hoc testing of workflow starts here # Ad hoc testing of workflow starts here
elif command == "step1": elif command == "step1":
tradeid = args.arguments[0] tradeid = args.arguments[0]
checkSellStatus(tradeid) cli.checkSellStatus(tradeid)
elif command == "step2": elif command == "step2":
tradeid = args.arguments[0] tradeid = args.arguments[0]
checkBuyStatus(tradeid) cli.checkBuyStatus(tradeid)
elif command == "step3": elif command == "step3":
# protocol = Protocol() # cli.protocol.generate(31)
# protocol.generate(31)
tradeid = args.arguments[0] tradeid = args.arguments[0]
checkSellStatus(tradeid) cli.checkSellStatus(tradeid)
elif command == "step4": elif command == "step4":
# generate(1) # cli.protocol.generate(1)
tradeid = args.arguments[0] tradeid = args.arguments[0]
checkBuyStatus(tradeid) cli.checkBuyStatus(tradeid)

View File

@ -5,11 +5,9 @@ from xcat.xcatconf import ADDRS
from xcat.trades import Contract, Trade from xcat.trades import Contract, Trade
from xcat.bitcoinRPC import bitcoinProxy from xcat.bitcoinRPC import bitcoinProxy
from xcat.zcashRPC import zcashProxy from xcat.zcashRPC import zcashProxy
from xcat.db import DB import json
class Protocol(): class Protocol():
def __init__(self): def __init__(self):
self.bitcoinRPC = bitcoinProxy() self.bitcoinRPC = bitcoinProxy()
self.zcashRPC = zcashProxy() self.zcashRPC = zcashProxy()
@ -186,6 +184,22 @@ class Protocol():
"{0} {1}!".format(buy.amount, buy.currency)) "{0} {1}!".format(buy.amount, buy.currency))
return txs return txs
def seller_init(self, tradeid, trade, network):
secret = utils.generate_password()
hash_of_secret = utils.sha256(secret)
# TODO: Implement locktimes and mock block passage of time
sell_locktime = 20
buy_locktime = 10 # Must be more than first tx
print("Creating pay-to-script-hash for sell contract...")
# create the p2sh addrs
self.create_sell_p2sh(trade, hash_of_secret, sell_locktime)
self.create_buy_p2sh(trade, hash_of_secret, buy_locktime)
trade.commitment = utils.b2x(hash_of_secret)
print("TRADE after seller init {0}".format(trade.toJSON()))
return trade, secret
def initialize_trade(self, tradeid, **kwargs): def initialize_trade(self, tradeid, **kwargs):
trade = Trade() trade = Trade()
conf = kwargs['conf'] conf = kwargs['conf']
@ -195,9 +209,16 @@ class Protocol():
amounts = userInput.get_trade_amounts() amounts = userInput.get_trade_amounts()
print("AMOUNTS", amounts) print("AMOUNTS", amounts)
else: else:
init_addrs = ADDRS[conf]['initiator'] print("Conf in init trade", conf)
fulfill_addrs = ADDRS[conf]['fulfiller'] if conf == 'testnet' or conf == 'regtest':
amounts = ADDRS[conf]['amounts'] # If json is not passed on cli, use ADDR obj from xcatconf.py
conf = ADDRS[conf]
else:
# Allow for passing in multiple trades at a time
conf = json.loads(conf)[0]
init_addrs = conf['initiator']
fulfill_addrs = conf['fulfiller']
amounts = conf['amounts']
sell = amounts['sell'] sell = amounts['sell']
buy = amounts['buy'] buy = amounts['buy']
@ -214,24 +235,3 @@ class Protocol():
print(trade.sell.__dict__) print(trade.sell.__dict__)
print(trade.buy.__dict__) print(trade.buy.__dict__)
return tradeid, trade return tradeid, trade
def seller_init(self, tradeid, trade, network):
db = DB()
secret = utils.generate_password()
db.save_secret(tradeid, secret)
print("\nGenerated a secret preimage to lock funds. This will only "
"be stored locally: {0}".format(secret))
hash_of_secret = utils.sha256(secret)
# TODO: Implement locktimes and mock block passage of time
sell_locktime = 20
buy_locktime = 10 # Must be more than first tx
print("Creating pay-to-script-hash for sell contract...")
# create the p2sh addrs
self.create_sell_p2sh(trade, hash_of_secret, sell_locktime)
self.create_buy_p2sh(trade, hash_of_secret, buy_locktime)
trade.commitment = utils.b2x(hash_of_secret)
print("TRADE after seller init {0}".format(trade.toJSON()))
return trade

View File

@ -1,103 +0,0 @@
import xcat.zcash
import xcat.bitcoin
from xcat import *
htlcTrade = Trade()
print("Starting test of xcat...")
def get_initiator_addresses():
return {'bitcoin': 'myfFr5twPYNwgeXyjCmGcrzXtCmfmWXKYp', 'zcash': 'tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ'}
def get_fulfiller_addresses():
return {'bitcoin': 'mrQzUGU1dwsWRx5gsKKSDPNtrsP65vCA3Z', 'zcash': 'tmTjZSg4pX2Us6V5HttiwFZwj464fD2ZgpY'}
def initiate(trade):
# Get amounts
amounts = {"sell": {"currency": "bitcoin", "amount": "0.5"}, "buy": {"currency": "zcash", "amount": "1.12"}}
sell = amounts['sell']
buy = amounts['buy']
sell_currency = sell['currency']
buy_currency = buy['currency']
# Get addresses
init_addrs = get_initiator_addresses()
sell['initiator'] = init_addrs[sell_currency]
buy['initiator'] = init_addrs[buy_currency]
fulfill_addrs = get_fulfiller_addresses()
sell['fulfiller'] = fulfill_addrs[sell_currency]
buy['fulfiller'] = fulfill_addrs[buy_currency]
# initializing contract classes with addresses, currencies, and amounts
trade.sell = Contract(sell)
trade.buy = Contract(buy)
print(trade.sell.__dict__)
print(trade.buy.__dict__)
secret = generate_password()
print("Generating secret to lock funds:", secret)
save_secret(secret)
# TODO: Implement locktimes and mock block passage of time
sell_locktime = 2
buy_locktime = 4 # Must be more than first tx
create_sell_p2sh(trade, secret, sell_locktime)
txid = fund_sell_contract(trade)
print("Sent")
create_buy_p2sh(trade, secret, buy_locktime)
def fulfill(trade):
buy = trade.buy
sell = trade.sell
buy_p2sh_balance = check_p2sh(buy.currency, buy.p2sh)
sell_p2sh_balance = check_p2sh(sell.currency, sell.p2sh)
if buy_p2sh_balance == 0:
print("Buy amt:", buy.amount)
txid = fund_buy_contract(trade)
print("Fund tx txid:", txid)
else:
raise ValueError("Sell p2sh not funded, buyer cannot redeem")
def redeem_one(trade):
buy = trade.buy
if trade.sell.get_status() == 'redeemed':
raise RuntimeError("Sell contract status was already redeemed before seller could redeem buyer's tx")
else:
secret = get_secret()
print("GETTING SECRET IN TEST:", secret)
tx_type, txid = redeem_p2sh(trade.buy, secret)
print("\nTX Type", tx_type)
setattr(trade.buy, tx_type, txid)
save(trade)
print("You have redeemed {0} {1}!".format(buy.amount, buy.currency))
def redeem_two(trade):
if trade.sell.get_status() == 'redeemed':
raise RuntimeError("Sell contract was redeemed before buyer could retrieve funds")
elif trade.buy.get_status() == 'refunded':
print("buy was refunded to buyer")
else:
# Buy contract is where seller disclosed secret in redeeming
if trade.buy.currency == 'bitcoin':
secret = bXcat.parse_secret(trade.buy.redeem_tx)
else:
secret = zXcat.parse_secret(trade.buy.redeem_tx)
print("Found secret in seller's redeem tx", secret)
redeem_tx = redeem_p2sh(trade.sell, secret)
setattr(trade.sell, 'redeem_tx', redeem_tx)
save(trade)
def generate_blocks(num):
bXcat.generate(num)
zXcat.generate(num)
initiate(htlcTrade)
fulfill(htlcTrade)
generate_blocks(6)
redeem_one(htlcTrade)
redeem_two(htlcTrade)
# addr = CBitcoinAddress('tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ')
# print(addr)
# # print(b2x('tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ'))
# print(b2x(addr))

View File

@ -92,11 +92,6 @@ if not os.path.exists(tmp_dir):
xcatjson = os.path.join(tmp_dir, 'xcat.json') xcatjson = os.path.join(tmp_dir, 'xcat.json')
def save_trade(trade):
with open(xcatjson, 'w+') as outfile:
json.dump(trade, outfile)
def get_trade(): def get_trade():
with open(xcatjson) as data_file: with open(xcatjson) as data_file:
xcatdb = json.load(data_file) xcatdb = json.load(data_file)
@ -113,7 +108,7 @@ def erase_trade():
except: except:
pass pass
# Dumping trade to json file for development and debugging
def save(trade): def save(trade):
# print("Saving trade") # print("Saving trade")
trade = { trade = {
@ -123,6 +118,9 @@ def save(trade):
} }
save_trade(trade) save_trade(trade)
def save_trade(trade):
with open(xcatjson, 'w+') as outfile:
json.dump(trade, outfile)
# Remove tmp files when trade is complete # Remove tmp files when trade is complete
def cleanup(tradeid): def cleanup(tradeid):

View File

@ -23,3 +23,8 @@ ADDRS = {
"amounts": {'buy': {'currency': 'zcash', 'amount': 0.02}, 'sell': {'currency': 'bitcoin', 'amount': 0.01}} "amounts": {'buy': {'currency': 'zcash', 'amount': 0.02}, 'sell': {'currency': 'bitcoin', 'amount': 0.01}}
} }
} }
NETWORK = 'testnet'
# Pass regtest trade data in on command line
# '[{"initiator": {"bitcoin": "mvc56qCEVj6p57xZ5URNC3v7qbatudHQ9b", "zcash": "tmTF7LMLjvEsGdcepWPUsh4vgJNrKMWwEyc"}, "fulfiller": {"bitcoin": "moRt56gJQGDNK46Y6fYy2HbooKnQXrTGDN", "zcash": "tmK3rGzHDqa78MCwEicx9VcY9ZWX9gCF2nd"}, "amounts": {"buy": {"currency": "zcash", "amount": 0.02}, "sell": {"currency": "bitcoin", "amount": 0.01}}}]'

View File

@ -51,7 +51,8 @@ class zcashProxy():
redeemerAddr = CBitcoinAddress(redeemer) redeemerAddr = CBitcoinAddress(redeemer)
if type(commitment) == str: if type(commitment) == str:
commitment = x(commitment) commitment = x(commitment)
# h = sha256(secret) else:
raise ValueError("Commitment was not a string: {0}".format(commitment))
blocknum = self.zcashd.getblockcount() blocknum = self.zcashd.getblockcount()
print("Current blocknum on Zcash: ", blocknum) print("Current blocknum on Zcash: ", blocknum)
redeemblocknum = blocknum + locktime redeemblocknum = blocknum + locktime