Add error handling, improve display

This commit is contained in:
Jay Graber 2017-05-23 14:12:01 -07:00
parent 11101c98d0
commit 0cfb0b7166
5 changed files with 51 additions and 23 deletions

View File

@ -1 +1 @@
{"t2QVxM3CdtjTtXC7P9eNvUoL22DWp7CzxFq": {"funder": "tmTjZSg4pX2Us6V5HttiwFZwj464fD2ZgpY", "zec_redeemScript": "63a820936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af8876a9143ea29256c9d2888ca23de42a8b8e69ca2ec235b16702b600b17576a914c5acca6ef39c843c7a9c3ad01b2da95fe2edf5ba6888ac", "redeemblocknum": 182, "p2sh": "t2QVxM3CdtjTtXC7P9eNvUoL22DWp7CzxFq", "redeemer": "tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ"}, "2N8TRB2xd9Xfsk7LuMif4CuPf8tQf5dSrdU": {"funder": "myfFr5twPYNwgeXyjCmGcrzXtCmfmWXKYp", "zec_redeemScript": "63a820936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af8876a9147788b4511a25fba1092e67b307a6dcdb6da125d967029200b17576a914c7043e62a7391596116f54f6a64c8548e97d3fd96888ac", "redeemblocknum": 146, "p2sh": "2N8TRB2xd9Xfsk7LuMif4CuPf8tQf5dSrdU", "redeemer": "mrQzUGU1dwsWRx5gsKKSDPNtrsP65vCA3Z"}}
{"t2QrLFUqmp1v1xQSE3hmgwcYuinRb3BRWMm": {"funder": "tmTjZSg4pX2Us6V5HttiwFZwj464fD2ZgpY", "redeemer": "tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ", "redeemblocknum": 182, "zec_redeemScript": "63a820343e398e4e99a68e7de6ec57f00b6a14a8e6d0a7dd714efbab4dcbd385f4f3038876a9143ea29256c9d2888ca23de42a8b8e69ca2ec235b16702b600b17576a914c5acca6ef39c843c7a9c3ad01b2da95fe2edf5ba6888ac", "p2sh": "t2QrLFUqmp1v1xQSE3hmgwcYuinRb3BRWMm"}, "2MuWU5BpLpqJvvzkCPq8gFHA4VFFGyvjaJf": {"funder": "myfFr5twPYNwgeXyjCmGcrzXtCmfmWXKYp", "redeemer": "mrQzUGU1dwsWRx5gsKKSDPNtrsP65vCA3Z", "redeemblocknum": 146, "zec_redeemScript": "63a820343e398e4e99a68e7de6ec57f00b6a14a8e6d0a7dd714efbab4dcbd385f4f3038876a9147788b4511a25fba1092e67b307a6dcdb6da125d967029200b17576a914c7043e62a7391596116f54f6a64c8548e97d3fd96888ac", "p2sh": "2MuWU5BpLpqJvvzkCPq8gFHA4VFFGyvjaJf"}}

View File

@ -19,6 +19,10 @@ def get_trade():
except:
return None
def erase_trade():
with open('xcat.json', 'w') as outfile:
outfile.write('')
def get_contract():
with open('contract.json') as data_file:
contractdb = json.load(data_file)

View File

@ -1 +1 @@
{"sell": {"secret": "helloworld", "fulfiller": "mrQzUGU1dwsWRx5gsKKSDPNtrsP65vCA3Z", "status": "redeemed", "currency": "bitcoin", "amount": 3.5, "initiator": "myfFr5twPYNwgeXyjCmGcrzXtCmfmWXKYp", "p2sh": "2N8TRB2xd9Xfsk7LuMif4CuPf8tQf5dSrdU", "redeem_tx": "e0947a300016faa5b4f2ff64e5e5c98cb09a1f14f4de68098b3e2679514c8432", "fund_tx": "a943ef89fafe60d82e00129bb5bf51f3c597b7f65bf464df41da7685b88270d7"}, "id": 1, "buy": {"currency": "zcash", "fulfiller": "tmTjZSg4pX2Us6V5HttiwFZwj464fD2ZgpY", "status": "redeemed", "amount": 1.2, "p2sh": "t2QVxM3CdtjTtXC7P9eNvUoL22DWp7CzxFq", "initiator": "tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ", "redeem_tx": "de46faa86b51fcb41694a8b9937ac7ef095801025478544bdb32fa18ef92ffc9", "fund_tx": "5ab08aee8412b5e660a72d5871d2c1435ae21a244476c785d2941e1652c06403"}}
{"id": 1, "buy": {"initiator": "tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ", "fund_tx": "9df973f468ce0b4398a9db2e8710b0ec268a3b3118f996f67f808af97e53a161", "fulfiller": "tmTjZSg4pX2Us6V5HttiwFZwj464fD2ZgpY", "p2sh": "t2QrLFUqmp1v1xQSE3hmgwcYuinRb3BRWMm", "amount": 1.2, "currency": "zcash"}, "sell": {"status": "funded", "fund_tx": "d1f679a3ee51fd563224e8114bed1d79fa6dc54d48163ec12ba17ba1d9e76baa", "p2sh": "2MuWU5BpLpqJvvzkCPq8gFHA4VFFGyvjaJf", "fulfiller": "mrQzUGU1dwsWRx5gsKKSDPNtrsP65vCA3Z", "initiator": "myfFr5twPYNwgeXyjCmGcrzXtCmfmWXKYp", "amount": 3.5, "currency": "bitcoin", "secret": "rabbits"}}

64
xcat.py
View File

@ -9,10 +9,10 @@ from pprint import pprint
def check_p2sh(currency, address):
if currency == 'bitcoin':
print("Checking funds in btc p2sh")
print("Checking funds in Bitcoin p2sh")
return bXcat.check_funds(address)
else:
print("Checking funds in zec p2sh")
print("Checking funds in Zcash p2sh")
return zXcat.check_funds(address)
def set_price():
@ -127,21 +127,19 @@ def get_addresses():
def buyer_fulfill():
trade = get_trade()
print('trade', trade)
buy_p2sh = trade['buy']['p2sh']
sell_p2sh = trade['sell']['p2sh']
buy_amount = check_p2sh(trade['buy']['currency'], buy_p2sh)
sell_amount = check_p2sh(trade['sell']['currency'], sell_p2sh)
input("The seller's p2sh is funded with {0} {1}, type 'enter' if this is the amount you want to buy in {1}.".format(trade['sell']['amount'], trade['sell']['currency']))
amount = trade['buy']['amount']
currency = trade['buy']['currency']
if buy_amount == 0:
input("You have not send funds to the contract to buy {1} (amount: {0}), type 'enter' to fund.".format(amount, currency))
input("The seller's p2sh is funded with {0} {1}, type 'enter' if this is the amount you want to buy in {1}.".format(trade['sell']['amount'], trade['sell']['currency']))
input("You have not send funds to the contract to buy {1} (requested amount: {0}), type 'enter' to allow this program to send the agreed upon funds on your behalf.".format(amount, currency))
p2sh = trade['buy']['p2sh']
input("Type 'enter' to allow this program to send the agreed upon funds on your behalf")
txid = fund_htlc(currency, p2sh, amount)
trade['buy']['fund_tx'] = txid
@ -172,7 +170,7 @@ def redeem_p2sh(currency, p2sh, action):
def seller_redeem():
# add locktime as variable?
trade = get_trade()
if trade['buy']['status'] == 'redeemed':
if 'status' in trade['buy'] and trade['buy']['status'] == 'redeemed':
print("You already redeemed the funds and acquired {0} {1}".format(trade['buy']['amount'], trade['buy']['currency']))
exit()
else:
@ -186,13 +184,26 @@ def seller_redeem():
def buyer_redeem():
trade = get_trade()
# Buyer redeems seller's funded tx
p2sh = trade['sell']['p2sh']
currency = trade['sell']['currency']
redeem_tx = redeem_p2sh(currency, p2sh, 'sell')
trade['sell']['redeem_tx'] = redeem_tx
trade['sell']['status'] = 'redeemed'
save_trade(trade)
if 'status' in trade['sell'] and trade['sell']['status'] == 'redeemed':
print("You already redeemed the funds and acquired {0} {1}".format(trade['sell']['amount'], trade['sell']['currency']))
exit()
else:
# Buyer redeems seller's funded tx
p2sh = trade['sell']['p2sh']
currency = trade['sell']['currency']
redeem_tx = redeem_p2sh(currency, p2sh, 'sell')
trade['sell']['redeem_tx'] = redeem_tx
trade['sell']['status'] = 'redeemed'
save_trade(trade)
def print_trade(role):
print("Trade status:")
trade = get_trade()
if role == 'seller':
pprint(trade)
else:
del trade['sell']['secret']
pprint(trade)
if __name__ == '__main__':
print("ZEC <-> BTC XCAT (Cross-Chain Atomic Transactions)")
@ -203,8 +214,13 @@ if __name__ == '__main__':
trade = get_trade()
try:
role = sys.argv[1]
print("Your role in demo:", role)
if sys.argv[1] == 'new':
erase_trade()
role = 'seller'
trade = get_trade()
else:
role = sys.argv[1]
print("Your role in demo:", role)
except:
if trade == None:
print("No active trades available.")
@ -228,14 +244,19 @@ if __name__ == '__main__':
set_price()
get_addresses()
initiate_trade()
print("Status of XCAT trade:")
pprint(get_trade())
print_trade('seller')
elif 'status' in trade['sell']:
if trade['sell']['status'] == 'funded':
if 'fund_tx' in trade['buy']:
# Means buyer has already funded the currency the transaction initiator wants to exchange into
print("Buyer funded the contract where you offered to buy {0}, redeeming funds from {1}...".format(trade['buy']['currency'], trade['buy']['p2sh']))
seller_redeem()
print("You have redeemed {0} {1}!".format(trade['buy']['amount'], trade['buy']['currency']))
print_trade('seller')
else:
print("Buyer has not yet funded the contract where you offered to buy {0}, please wait for them to complete their part.".format(trade['buy']['currency']))
print_trade('seller')
else:
# Need better way of preventing buyer from having secret
if 'status' not in trade['buy'] and trade['sell']['status'] == 'funded':
print("One active trade available, fulfilling buyer contract...")
trade = get_trade()
@ -244,11 +265,14 @@ if __name__ == '__main__':
# For regtest, can mock in a function
# p2sh = trade['buy']['p2sh']
# check_blocks(p2sh)
print_trade('buyer')
elif trade['buy']['status'] == 'redeemed':
# Seller has redeemed buyer's tx, buyer can now redeem.
print("The seller has redeemed the contract where you paid them in {0}, now redeeming your funds from {1}".format(trade['buy']['currency'], trade['sell']['p2sh']))
buyer_redeem()
print("XCAT trade complete!")
print_trade('buyer')
pprint(get_trade())
# Note: there is some little endian weirdness in the bXcat and zXcat files, need to handle the endianness of txids better & more consistently

View File

@ -58,7 +58,6 @@ def fund_htlc(p2sh, amount):
return txid
def check_funds(p2sh):
print("In zXcat check funds")
zcashd.importaddress(p2sh, "", False)
print("Imported address", p2sh)
# Get amount in address
@ -105,6 +104,7 @@ def redeem(p2sh, action):
# TODO: figure out how to better protect privkey?
privkey = zcashd.dumpprivkey(redeemPubKey)
sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
# TODO: Figure out where to store secret preimage securely. Parse from scriptsig of redeemtx
secret = trade['sell']['secret']
preimage = secret.encode('utf-8')