From ac92e8f81319c95edb605402f4f95365ba8de171 Mon Sep 17 00:00:00 2001 From: Chapman Shoop Date: Thu, 21 Jun 2018 13:50:03 -0700 Subject: [PATCH 1/2] WIP - Check integration with new btcpy --- pypeerassets/kutil.py | 19 +++++++------------ pypeerassets/networks.py | 22 +++++++++++++++++----- pypeerassets/provider/common.py | 9 +++------ requirements.txt | 5 +++-- test/test_pautils.py | 1 - test/test_peerassets.py | 2 -- test/test_provider.py | 14 ++++++-------- 7 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pypeerassets/kutil.py b/pypeerassets/kutil.py index afb5509..4cb052d 100644 --- a/pypeerassets/kutil.py +++ b/pypeerassets/kutil.py @@ -1,10 +1,12 @@ from hashlib import sha256 from os import urandom + from btcpy.structs.crypto import PublicKey, PrivateKey from btcpy.structs.transaction import MutableTransaction, TxOut from btcpy.structs.sig import P2pkhSolver -from btcpy.setup import setup + +from pypeerassets.networks import net_query class Kutil: @@ -23,14 +25,6 @@ def __init__(self, network: str, privkey: bytearray=None, from_string: str=None, self.network = network - try: - if self.network.startswith('t') or self.network.endswith('-testnet'): - setup('testnet') - else: - setup('mainnet') - except ValueError: - pass - if privkey is not None: self._private_key = PrivateKey(privkey) @@ -38,7 +32,8 @@ def __init__(self, network: str, privkey: bytearray=None, from_string: str=None, self._private_key = PrivateKey(sha256(from_string.encode()).digest()) if from_wif is not None: - self._private_key = PrivateKey.from_wif(from_wif) + btcpy_constants = net_query(self.network).btcpy_constants + self._private_key = PrivateKey.from_wif(btcpy_constants, from_wif) if not privkey: if from_string == from_wif is None: # generate a new privkey @@ -51,8 +46,8 @@ def __init__(self, network: str, privkey: bytearray=None, from_string: str=None, @property def address(self) -> str: '''generate an address from pubkey''' - - return str(self._public_key.to_address()) + btcpy_constants = net_query(self.network).btcpy_constants + return str(self._public_key.to_address(btcpy_constants)) @property def wif(self) -> str: diff --git a/pypeerassets/networks.py b/pypeerassets/networks.py index 45dd12c..22f3a60 100644 --- a/pypeerassets/networks.py +++ b/pypeerassets/networks.py @@ -1,6 +1,13 @@ from collections import namedtuple from decimal import Decimal +from btcpy.constants import ( + BitcoinMainnet, + BitcoinTestnet, + PeercoinMainnet, + PeercoinTestnet, +) + from pypeerassets.exceptions import UnsupportedNetwork @@ -16,7 +23,8 @@ 'min_vout_value', 'tx_timestamp', 'denomination', - 'op_return_max_bytes' + 'op_return_max_bytes', + 'btcpy_constants', ]) @@ -29,19 +37,23 @@ # Peercoin mainnet NetworkParams("peercoin", "ppc", b'37', b'b7', b'75', b'e6e8e9e5', b'\x17PPCoin Signed Message:\n', Decimal(0.01), - 0, True, Decimal('1e6'), 80), + 0, True, Decimal('1e6'), 80, + PeercoinMainnet), # Peercoin testnet NetworkParams("peercoin-testnet", "tppc", b'6f', b'ef', b'c4', b'cbf2c0ef', b'\x17PPCoin Signed Message:\n', Decimal(0.01), - 0, True, Decimal('1e6'), 80), + 0, True, Decimal('1e6'), 80, + PeercoinTestnet), # Bitcoin mainnet NetworkParams("bitcoin", "btc", b'00', b'80', b'05', b'd9b4bef9', b'\x18Bitcoin Signed Message:\n', 0, 0, False, - Decimal('1e8'), 80), + Decimal('1e8'), 80, + BitcoinMainnet), # Bitcoin testnet NetworkParams("bitcoin-testnet", "tbtc", b'6f', b'ef', b'c4', b'dab5bffa', b'\x18Bitcoin Signed Message:\n', 0, 0, False, - Decimal('1e8'), 80) + Decimal('1e8'), 80, + BitcoinTestnet) ) diff --git a/pypeerassets/provider/common.py b/pypeerassets/provider/common.py index dad04bc..565c580 100644 --- a/pypeerassets/provider/common.py +++ b/pypeerassets/provider/common.py @@ -112,13 +112,10 @@ def listtransactions(self, address: str) -> list: raise NotImplementedError def validateaddress(self, address: str) -> bool: - """Returns True if the passed address is valid, False otherwise. Note - the limitation that we don't check the address against the underlying - network (i.e. strict=False). When btcpy can support multiple networks at - runtime we can be more precise (i.e. strict=True) ;) - """ + "Returns True if the passed address is valid, False otherwise." + btcpy_constants = self.network_properties.btcpy_constants try: - Address.from_string(address, strict=False) + Address.from_string(btcpy_constants, address) except ValueError: return False diff --git a/requirements.txt b/requirements.txt index e29e376..f42d5e2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ -peerassets-btcpy -protobuf>=3.3.0 \ No newline at end of file +#peerassets-btcpy +git+https://github.com/PeerAssets/btcpy.git@master +protobuf>=3.3.0 diff --git a/test/test_pautils.py b/test/test_pautils.py index 99683e4..6a6949b 100644 --- a/test/test_pautils.py +++ b/test/test_pautils.py @@ -177,7 +177,6 @@ def test_load_deck_p2th_into_local_node(): load_deck_p2th_into_local_node(provider, deck) -@pytest.mark.xfail def test_validate_card_transfer_p2th(): provider = Cryptoid(network="peercoin-testnet") diff --git a/test/test_peerassets.py b/test/test_peerassets.py index efbb100..c59c940 100644 --- a/test/test_peerassets.py +++ b/test/test_peerassets.py @@ -27,7 +27,6 @@ def test_find_deck(prov): } -@pytest.mark.xfail @pytest.mark.parametrize("prov", [pa.Explorer, pa.Cryptoid]) def test_get_card_transfers(prov): @@ -41,7 +40,6 @@ def test_get_card_transfers(prov): assert isinstance(next(cards)[0], pa.CardTransfer) -@pytest.mark.xfail @pytest.mark.parametrize("prov", [pa.Explorer, pa.Cryptoid]) def test_find_all_valid_cards(prov): diff --git a/test/test_provider.py b/test/test_provider.py index 1f2dde4..8b9682b 100644 --- a/test/test_provider.py +++ b/test/test_provider.py @@ -13,10 +13,9 @@ def test_validateaddress_peercoin(provider_cls): assert provider.validateaddress("PAdonateFczhZuKLkKHozrcyMJW7Y6TKvw") is True assert provider.validateaddress("p92W3t7YkKfQEPDb7cG9jQ6iMh7cpKLvwK") is True - # Peercoin Testnet P2PKH address (these _should_ be False, but btcpy cannot - # support it at the moment). - assert provider.validateaddress("mj46gUeZgeD9ufU7Fvz2dWqaX6Nswtbpba") is True - assert provider.validateaddress("n12h8P5LrVXozfhEQEqg8SFUmVKtphBetj") is True + # Peercoin Testnet P2PKH address (these _should_ be False). + assert provider.validateaddress("mj46gUeZgeD9ufU7Fvz2dWqaX6Nswtbpba") is False + assert provider.validateaddress("n12h8P5LrVXozfhEQEqg8SFUmVKtphBetj") is False # Very much not Peercoin addresses. assert provider.validateaddress("1BFQfjM29kubskmaAsPjPCfHYphYvKA7Pj") is False @@ -33,10 +32,9 @@ def test_validateaddress_peercoin_testnet(provider_cls): assert provider.validateaddress("mj46gUeZgeD9ufU7Fvz2dWqaX6Nswtbpba") is True assert provider.validateaddress("n12h8P5LrVXozfhEQEqg8SFUmVKtphBetj") is True - # Peercoin P2PKH, P2SH addresses (these _should_ be False, but btcpy cannot - # support it at the moment). - assert provider.validateaddress("PAdonateFczhZuKLkKHozrcyMJW7Y6TKvw") is True - assert provider.validateaddress("p92W3t7YkKfQEPDb7cG9jQ6iMh7cpKLvwK") is True + # Peercoin P2PKH, P2SH addresses (these _should_ be False). + assert provider.validateaddress("PAdonateFczhZuKLkKHozrcyMJW7Y6TKvw") is False + assert provider.validateaddress("p92W3t7YkKfQEPDb7cG9jQ6iMh7cpKLvwK") is False # Very much not Peercoin Testnet addresses. assert provider.validateaddress("1BFQfjM29kubskmaAsPjPCfHYphYvKA7Pj") is False From bcab249290f5bc35483d604d5ae9410d3932c6d6 Mon Sep 17 00:00:00 2001 From: Chapman Shoop Date: Mon, 25 Jun 2018 15:37:03 -0700 Subject: [PATCH 2/2] issue#122 make_raw_transaction peercoin aware --- pypeerassets/transactions.py | 25 ++++++++++++++++++++++--- test/test_transactions.py | 23 +++++++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/pypeerassets/transactions.py b/pypeerassets/transactions.py index ab24d51..62d0c7f 100644 --- a/pypeerassets/transactions.py +++ b/pypeerassets/transactions.py @@ -13,12 +13,14 @@ ) from btcpy.structs.transaction import ( Locktime, + PeercoinTx, Transaction, TxIn, TxOut, ) from pypeerassets.kutil import Kutil +from pypeerassets.networks import net_query from pypeerassets.provider import Provider @@ -55,6 +57,7 @@ def tx_output(value: Decimal, n: int, script: ScriptSig) -> TxOut: def make_raw_transaction( + network: str, inputs: list, outputs: list, locktime: Locktime, @@ -63,9 +66,25 @@ def make_raw_transaction( ) -> Transaction: '''create raw transaction''' - return Transaction(version=version, timestamp=timestamp, - ins=inputs, outs=outputs, - locktime=locktime) + network_params = net_query(network) + + if network_params.network_name.startswith("peercoin"): + return PeercoinTx( + version=version, + timestamp=timestamp, + ins=inputs, + outs=outputs, + locktime=locktime, + network=network_params.btcpy_constants, + ) + + return Transaction( + version=version, + ins=inputs, + outs=outputs, + locktime=locktime, + network=network_params.btcpy_constants, + ) def find_parent_outputs(provider: Provider, utxo: TxIn) -> TxOut: diff --git a/test/test_transactions.py b/test/test_transactions.py index af4f0cc..4a67046 100644 --- a/test/test_transactions.py +++ b/test/test_transactions.py @@ -1,7 +1,19 @@ -import pytest from decimal import Decimal, getcontext + +from btcpy.structs.transaction import ( + Locktime, + PeercoinTx, + Transaction, +) +import pytest + +from pypeerassets.transactions import ( + calculate_tx_fee, + make_raw_transaction, +) + + getcontext().prec = 6 -from pypeerassets.transactions import * @pytest.mark.parametrize("tx_size", [181, 311]) @@ -17,3 +29,10 @@ def test_nulldata_script(): def test_p2pkh_script(): pass + +def test_make_raw_transaction(): + tx = make_raw_transaction("bitcoin", [], [], Locktime(0)) + assert isinstance(tx, Transaction) + + tx = make_raw_transaction("peercoin", [], [], Locktime(0)) + assert isinstance(tx, PeercoinTx)