Skip to content

Commit

Permalink
Repackage as python module
Browse files Browse the repository at this point in the history
  • Loading branch information
Jay Graber committed Jul 29, 2017
1 parent 043958b commit 94abea7
Show file tree
Hide file tree
Showing 21 changed files with 147 additions and 61 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.pyc
xcatdb/
xcat.egg-info/
2 changes: 0 additions & 2 deletions requirements.txt

This file was deleted.

1 change: 0 additions & 1 deletion secret.json

This file was deleted.

17 changes: 17 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -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="[email protected]",
license="MIT",
url="http://github.com/zcash/xcat",
packages=find_packages()
)
7 changes: 7 additions & 0 deletions xcat-runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from xcat.xcat import main

if __name__ == '__main__':
main()
5 changes: 5 additions & 0 deletions xcat/__init__.py
Original file line number Diff line number Diff line change
@@ -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))
2 changes: 2 additions & 0 deletions xcat/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .cli import main
main()
4 changes: 2 additions & 2 deletions bXcat.py → xcat/bitcoinRPC.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
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')
Expand Down
68 changes: 45 additions & 23 deletions cli.py → xcat/cli.py
Original file line number Diff line number Diff line change
@@ -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':
Expand Down Expand Up @@ -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)
Expand All @@ -91,12 +113,12 @@ def instantiateTrade(trade):
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")
Expand Down
25 changes: 16 additions & 9 deletions database.py → xcat/database.py
Original file line number Diff line number Diff line change
@@ -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))
Expand All @@ -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'
Expand Down
38 changes: 19 additions & 19 deletions xcat.py → xcat/protocol.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down Expand Up @@ -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):
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions xcat/secret.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OBbU9kny
4 changes: 2 additions & 2 deletions test.py → xcat/tests/test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import zXcat
import bXcat
import xcat.zcash
import xcat.bitcoin
from xcat import *

htlcTrade = Trade()
Expand Down
File renamed without changes.
21 changes: 21 additions & 0 deletions xcat/tests/test_db.py
Original file line number Diff line number Diff line change
@@ -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()
1 change: 1 addition & 0 deletions xcat/tests/tradetest.json
Original file line number Diff line number Diff line change
@@ -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"}
File renamed without changes.
6 changes: 5 additions & 1 deletion userInput.py → xcat/userInput.py
Original file line number Diff line number Diff line change
@@ -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 = {}
Expand Down
2 changes: 1 addition & 1 deletion utils.py → xcat/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import hashlib, json, random, binascii
import trades
import xcat.trades

############################################
########### Data conversion utils ##########
Expand Down
1 change: 1 addition & 0 deletions xcat/xcat.json
Original file line number Diff line number Diff line change
@@ -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"}
2 changes: 1 addition & 1 deletion zXcat.py → xcat/zcashRPC.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
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')
Expand Down

0 comments on commit 94abea7

Please sign in to comment.