Repackage as python module
This commit is contained in:
parent
043958b840
commit
94abea7bc2
|
@ -1,2 +1,3 @@
|
|||
*.pyc
|
||||
xcatdb/
|
||||
xcat.egg-info/
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
python-bitcoinlib
|
||||
plyvel
|
|
@ -1 +0,0 @@
|
|||
2E8ASX0w
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env python
|
||||
from setuptools import setup, find_packages
|
||||
from xcat import version
|
||||
|
||||
setup(
|
||||
name="xcat",
|
||||
version=version,
|
||||
entry_points = {
|
||||
"console_scripts": ['xcat = xcat.cli:main']
|
||||
},
|
||||
description="Xcat is a package to facilitate cross-chain atomic transactions.",
|
||||
author="arcalinea and arielgabizon",
|
||||
author_email="xcat@z.cash",
|
||||
license="MIT",
|
||||
url="http://github.com/zcash/xcat",
|
||||
packages=find_packages()
|
||||
)
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from xcat.xcat import main
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,5 @@
|
|||
"""
|
||||
Xcat is an implementation of a cross-chain atomic transaction. The protocol currently support trades between Zcash and Bitcoin.
|
||||
"""
|
||||
version_info = (0, 1)
|
||||
version = '.'.join(map(str, version_info))
|
|
@ -0,0 +1,2 @@
|
|||
from .cli import main
|
||||
main()
|
|
@ -14,13 +14,13 @@ from bitcoin.core.script import CScript, OP_DUP, OP_IF, OP_ELSE, OP_ENDIF, OP_HA
|
|||
from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
|
||||
from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret, P2SHBitcoinAddress, P2PKHBitcoinAddress
|
||||
|
||||
from utils import *
|
||||
from xcat.utils import *
|
||||
|
||||
import zcash
|
||||
import zcash.rpc
|
||||
import pprint, json
|
||||
|
||||
from zXcat import parse_script
|
||||
from xcat.zcashRPC import parse_script
|
||||
|
||||
# SelectParams('testnet')
|
||||
SelectParams('regtest')
|
|
@ -1,14 +1,16 @@
|
|||
import argparse, textwrap
|
||||
from utils import *
|
||||
import database as db
|
||||
import bXcat, zXcat
|
||||
from trades import *
|
||||
from xcat import *
|
||||
from xcat.utils import *
|
||||
import xcat.database as db
|
||||
import xcat.bitcoinRPC
|
||||
import xcat.zcashRPC
|
||||
import xcat.userInput
|
||||
from xcat.trades import *
|
||||
from xcat.protocol import *
|
||||
import ast
|
||||
|
||||
def save_state(trade):
|
||||
def save_state(trade, tradeid):
|
||||
save(trade)
|
||||
db.create
|
||||
db.create(trade, tradeid)
|
||||
|
||||
def checkSellStatus(trade):
|
||||
if trade.buy.get_status() == 'funded':
|
||||
|
@ -49,38 +51,58 @@ def checkBuyStatus(trade):
|
|||
print("TXID after buyer redeem", txid)
|
||||
print("XCAT trade complete!")
|
||||
|
||||
# Import a trade in hex, and save to db
|
||||
def importtrade(hexstr):
|
||||
trade = x2s(hexstr)
|
||||
trade = instantiateTrade(ast.literal_eval(trade))
|
||||
save_state(trade)
|
||||
|
||||
# Export a trade by its tradeid
|
||||
def exporttrade(tradeid):
|
||||
# trade = get_trade()
|
||||
trade = db.get(tradeid)
|
||||
hexstr = s2x(str(trade))
|
||||
print(trade)
|
||||
print(hexstr)
|
||||
|
||||
def newtrade(tradeid):
|
||||
erase_trade()
|
||||
role = 'seller'
|
||||
print("Creating new XCAT trade...")
|
||||
trade = seller_init(Trade())
|
||||
# Save it to leveldb
|
||||
# db.create(trade)
|
||||
save_state(trade, tradeid)
|
||||
|
||||
def instantiateTrade(trade):
|
||||
return Trade(buy=Contract(trade['buy']), sell=Contract(trade['sell']))
|
||||
|
||||
if __name__ == '__main__':
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,
|
||||
description=textwrap.dedent('''\
|
||||
== Trades ==
|
||||
newtrade - create a new trade
|
||||
checktrades - check for actions to be taken on existing trades
|
||||
importtrade "hexstr" - import an existing trade from a hex string
|
||||
exporttrade - export the data of an existing xcat trade as a hex string
|
||||
exporttrade - export the data of an existing trade as a hex string. Takes the tradeid as an argument
|
||||
findtrade - find a trade by the txid of the currency being traded out of
|
||||
|
||||
'''))
|
||||
parser.add_argument("command", action="store", help="list commands")
|
||||
parser.add_argument("argument", action="store", nargs="*", help="add an argument")
|
||||
# parser.add_argument("--daemon", "-d", action="store_true", help="Run as daemon process")
|
||||
# TODO: function to view available trades
|
||||
# TODO: function to tell if tradeid already exists for newtrade
|
||||
args = parser.parse_args()
|
||||
|
||||
# how to hold state of role
|
||||
command = args.command
|
||||
if command == 'importtrade':
|
||||
hexstr = args.argument[0]
|
||||
trade = x2s(hexstr)
|
||||
trade = instantiateTrade(ast.literal_eval(trade))
|
||||
save_state(trade)
|
||||
# print(trade.toJ)
|
||||
importtrade(hexstr)
|
||||
elif command == 'exporttrade':
|
||||
trade = get_trade()
|
||||
hexstr = s2x(str(trade))
|
||||
print(trade)
|
||||
print(hexstr)
|
||||
tradeid = args.argument[0]
|
||||
exporttrade(tradeid)
|
||||
elif command == 'checktrades':
|
||||
trade = get_trade()
|
||||
trade = instantiateTrade(trade)
|
||||
|
@ -91,12 +113,12 @@ if __name__ == '__main__':
|
|||
role = 'buyer'
|
||||
checkBuyStatus(trade)
|
||||
elif command == 'newtrade':
|
||||
erase_trade()
|
||||
role = 'seller'
|
||||
print("Creating new XCAT trade...")
|
||||
trade = seller_init(Trade())
|
||||
# Save it to leveldb
|
||||
db.create(trade)
|
||||
try:
|
||||
tradeid = args.argument[0]
|
||||
newtrade(tradeid)
|
||||
except:
|
||||
tradeid = userInput.enter_trade_id()
|
||||
newtrade(tradeid)
|
||||
elif command == "daemon":
|
||||
#TODO: implement
|
||||
print("Run as daemon process")
|
|
@ -1,29 +1,35 @@
|
|||
import plyvel
|
||||
from utils import *
|
||||
from .utils import *
|
||||
import binascii
|
||||
import sys
|
||||
import json
|
||||
|
||||
db = plyvel.DB('/tmp/testdb', create_if_missing=True)
|
||||
|
||||
trade = get_trade()
|
||||
## txid we retrieve by
|
||||
if trade and trade.sell:
|
||||
if hasattr(trade.sell, 'fund_tx'):
|
||||
txid = trade.sell.fund_tx
|
||||
# trade = get_trade()
|
||||
# ## txid we retrieve by
|
||||
# if trade and trade.sell:
|
||||
# if hasattr(trade.sell, 'fund_tx'):
|
||||
# txid = trade.sell.fund_tx
|
||||
|
||||
# Takes object, saves json as bytes
|
||||
def create(trade):
|
||||
def create(trade, tradeid):
|
||||
trade = trade.toJSON()
|
||||
db.put(b(tradeid), b(trade))
|
||||
|
||||
# Uses the funding txid as the key to save trade
|
||||
def createByFundtx(trade):
|
||||
trade = trade.toJSON()
|
||||
# # Save trade by initiating txid
|
||||
jt = json.loads(trade)
|
||||
txid = jt['sell']['fund_tx']
|
||||
# Save trade by initiating txid
|
||||
db.put(b(txid), b(trade))
|
||||
|
||||
def get(txid):
|
||||
return db.get(b(txid))
|
||||
|
||||
# db.delete(b'hello')
|
||||
db.get(b'test')
|
||||
|
||||
# hexstr = get(txid)
|
||||
# print(x2s(hexstr))
|
||||
|
@ -33,8 +39,9 @@ def print_entries():
|
|||
with db.iterator() as it:
|
||||
for k, v in it:
|
||||
j = json.loads(x2s(b2x(v)))
|
||||
print("Key:", k)
|
||||
print('val: ', j)
|
||||
print('sell: ', j['sell'])
|
||||
# print('sell: ', j['sell'])
|
||||
|
||||
# print_entries()
|
||||
# txid = '1171aeda64eff388b3568fa4675d0ca78852911109bbe42e0ef11ad6bf1b159e'
|
|
@ -1,35 +1,35 @@
|
|||
import zXcat
|
||||
import bXcat
|
||||
from utils import *
|
||||
from waiting import *
|
||||
from time import sleep
|
||||
import json
|
||||
import os, sys
|
||||
from pprint import pprint
|
||||
from trades import Contract, Trade
|
||||
import userInput
|
||||
import xcat.zcashRPC
|
||||
import xcat.bitcoinRPC
|
||||
from xcat.utils import *
|
||||
from xcat.trades import Contract, Trade
|
||||
import xcat.userInput
|
||||
|
||||
def check_p2sh(currency, address):
|
||||
if currency == 'bitcoin':
|
||||
print("Checking funds in Bitcoin p2sh")
|
||||
return bXcat.check_funds(address)
|
||||
return bitcoinRPC.check_funds(address)
|
||||
else:
|
||||
print("Checking funds in Zcash p2sh")
|
||||
return zXcat.check_funds(address)
|
||||
return zcashRPC.check_funds(address)
|
||||
|
||||
def create_htlc(currency, funder, redeemer, commitment, locktime):
|
||||
print("Commitment in create_htlc", commitment)
|
||||
if currency == 'bitcoin':
|
||||
sell_p2sh = bXcat.hashtimelockcontract(funder, redeemer, commitment, locktime)
|
||||
sell_p2sh = bitcoinRPC.hashtimelockcontract(funder, redeemer, commitment, locktime)
|
||||
else:
|
||||
sell_p2sh = zXcat.hashtimelockcontract(funder, redeemer, commitment, locktime)
|
||||
sell_p2sh = zcashRPC.hashtimelockcontract(funder, redeemer, commitment, locktime)
|
||||
return sell_p2sh
|
||||
|
||||
def fund_htlc(currency, p2sh, amount):
|
||||
if currency == 'bitcoin':
|
||||
txid = bXcat.fund_htlc(p2sh, amount)
|
||||
txid = bitcoinRPC.fund_htlc(p2sh, amount)
|
||||
else:
|
||||
txid = zXcat.fund_htlc(p2sh, amount)
|
||||
txid = zcashRPC.fund_htlc(p2sh, amount)
|
||||
return txid
|
||||
#
|
||||
# def fund_buy_contract(trade):
|
||||
|
@ -80,25 +80,25 @@ def create_buy_p2sh(trade, commitment, locktime):
|
|||
def auto_redeem_p2sh(contract, secret):
|
||||
currency = contract.currency
|
||||
if currency == 'bitcoin':
|
||||
res = bXcat.auto_redeem(contract, secret)
|
||||
res = bitcoinRPC.auto_redeem(contract, secret)
|
||||
else:
|
||||
res = zXcat.auto_redeem(contract, secret)
|
||||
res = zcashRPC.auto_redeem(contract, secret)
|
||||
return res
|
||||
|
||||
|
||||
def redeem_p2sh(contract, secret):
|
||||
currency = contract.currency
|
||||
if currency == 'bitcoin':
|
||||
res = bXcat.redeem_contract(contract, secret)
|
||||
res = bitcoinRPC.redeem_contract(contract, secret)
|
||||
else:
|
||||
res = zXcat.redeem_contract(contract, secret)
|
||||
res = zcashRPC.redeem_contract(contract, secret)
|
||||
return res
|
||||
|
||||
def parse_secret(chain, txid):
|
||||
if chain == 'bitcoin':
|
||||
secret = bXcat.parse_secret(txid)
|
||||
secret = bitcoinRPC.parse_secret(txid)
|
||||
else:
|
||||
secret = zXcat.parse_secret(txid)
|
||||
secret = zcashRPC.parse_secret(txid)
|
||||
|
||||
#### Main functions determining user flow from command line
|
||||
def buyer_redeem(trade):
|
||||
|
@ -112,9 +112,9 @@ def buyer_redeem(trade):
|
|||
currency = trade.sell.currency
|
||||
# Buy contract is where seller disclosed secret in redeeming
|
||||
if trade.buy.currency == 'bitcoin':
|
||||
secret = bXcat.parse_secret(trade.buy.redeem_tx)
|
||||
secret = bitcoinRPC.parse_secret(trade.buy.redeem_tx)
|
||||
else:
|
||||
secret = zXcat.parse_secret(trade.buy.redeem_tx)
|
||||
secret = zcashRPC.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)
|
|
@ -0,0 +1 @@
|
|||
OBbU9kny
|
|
@ -1,5 +1,5 @@
|
|||
import zXcat
|
||||
import bXcat
|
||||
import xcat.zcash
|
||||
import xcat.bitcoin
|
||||
from xcat import *
|
||||
|
||||
htlcTrade = Trade()
|
|
@ -0,0 +1,21 @@
|
|||
import xcat.database as db
|
||||
import unittest, json
|
||||
import xcat.trades as trades
|
||||
|
||||
class DatabaseTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.data = {"sell": {"amount": 3.5, "redeemScript": "63a82003d58daab37238604b3e57d4a8bdcffa401dc497a9c1aa4f08ffac81616c22b68876a9147788b4511a25fba1092e67b307a6dcdb6da125d967022a04b17576a914c7043e62a7391596116f54f6a64c8548e97d3fd96888ac", "redeemblocknum": 1066, "currency": "bitcoin", "initiator": "myfFr5twPYNwgeXyjCmGcrzXtCmfmWXKYp", "p2sh": "2MuYSQ1uQ4CJg5Y5QL2vMmVPHNJ2KT5aJ6f", "fulfiller": "mrQzUGU1dwsWRx5gsKKSDPNtrsP65vCA3Z", "fund_tx": "5c5e91a89a08b2d6698f50c9fd9bb2fa22da6c74e226c3dd63d59511566a2fdb"}, "buy": {"amount": 1.2, "redeemScript": "63a82003d58daab37238604b3e57d4a8bdcffa401dc497a9c1aa4f08ffac81616c22b68876a9143ea29256c9d2888ca23de42a8b8e69ca2ec235b167023f0db17576a914c5acca6ef39c843c7a9c3ad01b2da95fe2edf5ba6888ac", "redeemblocknum": 3391, "currency": "zcash", "locktime": 10, "initiator": "tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ", "p2sh": "t2HP59RpfR34nBCWH4VVD497tkc2ikzgniP", "fulfiller": "tmTjZSg4pX2Us6V5HttiwFZwj464fD2ZgpY"}, "commitment": "03d58daab37238604b3e57d4a8bdcffa401dc497a9c1aa4f08ffac81616c22b6"}
|
||||
self.sell = trades.Contract(self.data['sell'])
|
||||
|
||||
def test_create(self):
|
||||
sell = trades.Contract(self.data['sell'])
|
||||
buy = trades.Contract(self.data['buy'])
|
||||
trade = trades.Trade(sell, buy, commitment=self.data['commitment'])
|
||||
db.create(trade, 'test')
|
||||
|
||||
def test_get(self):
|
||||
trade = db.get('test')
|
||||
print("Trade")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -0,0 +1 @@
|
|||
{"sell": {"amount": 3.5, "redeemScript": "63a82003d58daab37238604b3e57d4a8bdcffa401dc497a9c1aa4f08ffac81616c22b68876a9147788b4511a25fba1092e67b307a6dcdb6da125d967022a04b17576a914c7043e62a7391596116f54f6a64c8548e97d3fd96888ac", "redeemblocknum": 1066, "currency": "bitcoin", "initiator": "myfFr5twPYNwgeXyjCmGcrzXtCmfmWXKYp", "p2sh": "2MuYSQ1uQ4CJg5Y5QL2vMmVPHNJ2KT5aJ6f", "fulfiller": "mrQzUGU1dwsWRx5gsKKSDPNtrsP65vCA3Z", "fund_tx": "5c5e91a89a08b2d6698f50c9fd9bb2fa22da6c74e226c3dd63d59511566a2fdb"}, "buy": {"amount": 1.2, "redeemScript": "63a82003d58daab37238604b3e57d4a8bdcffa401dc497a9c1aa4f08ffac81616c22b68876a9143ea29256c9d2888ca23de42a8b8e69ca2ec235b167023f0db17576a914c5acca6ef39c843c7a9c3ad01b2da95fe2edf5ba6888ac", "redeemblocknum": 3391, "currency": "zcash", "locktime": 10, "initiator": "tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ", "p2sh": "t2HP59RpfR34nBCWH4VVD497tkc2ikzgniP", "fulfiller": "tmTjZSg4pX2Us6V5HttiwFZwj464fD2ZgpY"}, "commitment": "03d58daab37238604b3e57d4a8bdcffa401dc497a9c1aa4f08ffac81616c22b6"}
|
|
@ -1,4 +1,8 @@
|
|||
from utils import *
|
||||
from xcat.utils import *
|
||||
|
||||
def enter_trade_id():
|
||||
tradeid = input("Enter a unique identifier for this trade: ")
|
||||
return tradeid
|
||||
|
||||
def get_trade_amounts():
|
||||
amounts = {}
|
|
@ -1,5 +1,5 @@
|
|||
import hashlib, json, random, binascii
|
||||
import trades
|
||||
import xcat.trades
|
||||
|
||||
############################################
|
||||
########### Data conversion utils ##########
|
|
@ -0,0 +1 @@
|
|||
{"sell": {"amount": 3.5, "redeemScript": "63a82003d58daab37238604b3e57d4a8bdcffa401dc497a9c1aa4f08ffac81616c22b68876a9147788b4511a25fba1092e67b307a6dcdb6da125d967022a04b17576a914c7043e62a7391596116f54f6a64c8548e97d3fd96888ac", "redeemblocknum": 1066, "currency": "bitcoin", "initiator": "myfFr5twPYNwgeXyjCmGcrzXtCmfmWXKYp", "p2sh": "2MuYSQ1uQ4CJg5Y5QL2vMmVPHNJ2KT5aJ6f", "fulfiller": "mrQzUGU1dwsWRx5gsKKSDPNtrsP65vCA3Z", "fund_tx": "5c5e91a89a08b2d6698f50c9fd9bb2fa22da6c74e226c3dd63d59511566a2fdb"}, "buy": {"amount": 1.2, "redeemScript": "63a82003d58daab37238604b3e57d4a8bdcffa401dc497a9c1aa4f08ffac81616c22b68876a9143ea29256c9d2888ca23de42a8b8e69ca2ec235b167023f0db17576a914c5acca6ef39c843c7a9c3ad01b2da95fe2edf5ba6888ac", "redeemblocknum": 3391, "currency": "zcash", "locktime": 10, "initiator": "tmFRXyju7ANM7A9mg75ZjyhFW1UJEhUPwfQ", "p2sh": "t2HP59RpfR34nBCWH4VVD497tkc2ikzgniP", "fulfiller": "tmTjZSg4pX2Us6V5HttiwFZwj464fD2ZgpY"}, "commitment": "03d58daab37238604b3e57d4a8bdcffa401dc497a9c1aa4f08ffac81616c22b6"}
|
|
@ -16,7 +16,7 @@ from zcash.core.script import CScript, OP_DUP, OP_IF, OP_ELSE, OP_ENDIF, OP_HASH
|
|||
from zcash.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
|
||||
from zcash.wallet import CBitcoinAddress, CBitcoinSecret, P2SHBitcoinAddress, P2PKHBitcoinAddress
|
||||
|
||||
from utils import *
|
||||
from xcat.utils import *
|
||||
|
||||
# SelectParams('testnet')
|
||||
SelectParams('regtest')
|
Loading…
Reference in New Issue