Skip to content

Commit

Permalink
Use automatic detection for encodable message string vs raw bytes. Us…
Browse files Browse the repository at this point in the history
…e a constant for BCH to satoshi multiplier.
  • Loading branch information
lannocc committed Jul 23, 2018
1 parent 11fd0b7 commit b25fe03
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 44 deletions.
3 changes: 2 additions & 1 deletion HISTORY.rst
Expand Up @@ -9,7 +9,8 @@ Unreleased (see `master <https://github.com/ofek/bitcash>`_)
contains some common details of the transaction.

- Allow raw byte string to be used as transaction OP_RETURN
message with new 'bytes=True' parameter. Increase message
message: automatic detection assumes a byte-like object when
message does not have an encode() function. Increase message
size to 220 bytes.

- NetworkAPI.get_tx_amount() is now working and properly handles
Expand Down
2 changes: 1 addition & 1 deletion bitcash/__init__.py
Expand Up @@ -3,4 +3,4 @@
from bitcash.network.services import set_service_timeout
from bitcash.wallet import Key, PrivateKey, PrivateKeyTestnet, wif_to_key

__version__ = '0.5.2.3'
__version__ = '0.5.2.4'
22 changes: 12 additions & 10 deletions bitcash/network/services.py
Expand Up @@ -10,6 +10,8 @@

DEFAULT_TIMEOUT = 30

BCH_TO_SAT_MULTIPLIER = 100000000


def set_service_timeout(seconds):
global DEFAULT_TIMEOUT
Expand Down Expand Up @@ -48,9 +50,9 @@ def get_transaction(cls, txid):
response = r.json(parse_float=Decimal)

tx = Transaction(response['txid'], response['blockheight'],
(Decimal(response['valueIn'])*100000000).normalize(),
(Decimal(response['valueOut'])*100000000).normalize(),
(Decimal(response['fees'])*100000000).normalize())
(Decimal(response['valueIn']) * BCH_TO_SAT_MULTIPLIER).normalize(),
(Decimal(response['valueOut']) * BCH_TO_SAT_MULTIPLIER).normalize(),
(Decimal(response['fees']) * BCH_TO_SAT_MULTIPLIER).normalize())

for txin in response['vin']:
part = TxPart(txin['addr'], txin['valueSat'], txin['scriptSig']['asm'])
Expand All @@ -62,7 +64,7 @@ def get_transaction(cls, txid):
addr = txout['scriptPubKey']['addresses'][0]

part = TxPart(addr,
(Decimal(txout['value'])*100000000).normalize(),
(Decimal(txout['value']) * BCH_TO_SAT_MULTIPLIER).normalize(),
txout['scriptPubKey']['asm'])
tx.add_output(part)

Expand All @@ -74,7 +76,7 @@ def get_tx_amount(cls, txid, txindex):
if r.status_code != 200: # pragma: no cover
raise ConnectionError
response = r.json(parse_float=Decimal)
return (Decimal(response['vout'][txindex]['value'])*100000000).normalize()
return (Decimal(response['vout'][txindex]['value']) * BCH_TO_SAT_MULTIPLIER).normalize()

@classmethod
def get_unspent(cls, address):
Expand Down Expand Up @@ -184,9 +186,9 @@ def get_transaction_testnet(cls, txid):
response = r.json(parse_float=Decimal)

tx = Transaction(response['txid'], response['blockheight'],
(Decimal(response['valueIn'])*100000000).normalize(),
(Decimal(response['valueOut'])*100000000).normalize(),
(Decimal(response['fees'])*100000000).normalize())
(Decimal(response['valueIn']) * BCH_TO_SAT_MULTIPLIER).normalize(),
(Decimal(response['valueOut']) * BCH_TO_SAT_MULTIPLIER).normalize(),
(Decimal(response['fees']) * BCH_TO_SAT_MULTIPLIER).normalize())

for txin in response['vin']:
part = TxPart(txin['addr'], txin['valueSat'], txin['scriptSig']['asm'])
Expand All @@ -198,7 +200,7 @@ def get_transaction_testnet(cls, txid):
addr = txout['scriptPubKey']['addresses'][0]

part = TxPart(addr,
(Decimal(txout['value'])*100000000).normalize(),
(Decimal(txout['value']) * BCH_TO_SAT_MULTIPLIER).normalize(),
txout['scriptPubKey']['asm'])
tx.add_output(part)

Expand All @@ -210,7 +212,7 @@ def get_tx_amount_testnet(cls, txid, txindex):
if r.status_code != 200: # pragma: no cover
raise ConnectionError
response = r.json(parse_float=Decimal)
return (Decimal(response['vout'][txindex]['value'])*100000000).normalize()
return (Decimal(response['vout'][txindex]['value']) * BCH_TO_SAT_MULTIPLIER).normalize()

@classmethod
def get_unspent_testnet(cls, address):
Expand Down
6 changes: 4 additions & 2 deletions bitcash/transaction.py
Expand Up @@ -90,7 +90,7 @@ def estimate_tx_fee(n_in, n_out, satoshis, compressed):
return estimated_fee


def sanitize_tx_data(unspents, outputs, fee, leftover, combine=True, message=None, bytes=False, compressed=True):
def sanitize_tx_data(unspents, outputs, fee, leftover, combine=True, message=None, compressed=True):
"""
sanitize_tx_data()
Expand All @@ -113,8 +113,10 @@ def sanitize_tx_data(unspents, outputs, fee, leftover, combine=True, message=Non
messages = []

if message:
if not bytes:
try:
message = message.encode('utf-8')
except AttributeError:
pass # assume message is already a bytes-like object

message_chunks = chunk_data(message, MESSAGE_LIMIT)

Expand Down
38 changes: 8 additions & 30 deletions bitcash/wallet.py
Expand Up @@ -206,7 +206,7 @@ def get_transactions(self):
return self.transactions

def create_transaction(self, outputs, fee=None, leftover=None, combine=True,
message=None, bytes=False, unspents=None): # pragma: no cover
message=None, unspents=None): # pragma: no cover
"""Creates a signed P2PKH transaction.
:param outputs: A sequence of outputs you wish to send in the form
Expand All @@ -232,9 +232,6 @@ def create_transaction(self, outputs, fee=None, leftover=None, combine=True,
stored in the blockchain forever. Due to size limits,
each message will be stored in chunks of 220 bytes.
:type message: ``str``
:param bytes: Whether or not the supplied message is already bytes. If
false (default), message is automatically encoded to UTF-8.
:type bytes: ``bool``
:param unspents: The UTXOs to use as the inputs. By default Bitcash will
communicate with the blockchain itself.
:type unspents: ``list`` of :class:`~bitcash.network.meta.Unspent`
Expand All @@ -249,14 +246,13 @@ def create_transaction(self, outputs, fee=None, leftover=None, combine=True,
leftover or self.address,
combine=combine,
message=message,
bytes=bytes,
compressed=self.is_compressed()
)

return create_p2pkh_transaction(self, unspents, outputs)

def send(self, outputs, fee=None, leftover=None, combine=True,
message=None, bytes=False, unspents=None): # pragma: no cover
message=None, unspents=None): # pragma: no cover
"""Creates a signed P2PKH transaction and attempts to broadcast it on
the blockchain. This accepts the same arguments as
:func:`~bitcash.PrivateKey.create_transaction`.
Expand Down Expand Up @@ -284,9 +280,6 @@ def send(self, outputs, fee=None, leftover=None, combine=True,
stored in the blockchain forever. Due to size limits,
each message will be stored in chunks of 220 bytes.
:type message: ``str``
:param bytes: Whether or not the supplied message is already bytes. If
false (default), message is automatically encoded to UTF-8.
:type bytes: ``bool``
:param unspents: The UTXOs to use as the inputs. By default Bitcash will
communicate with the blockchain itself.
:type unspents: ``list`` of :class:`~bitcash.network.meta.Unspent`
Expand All @@ -295,7 +288,7 @@ def send(self, outputs, fee=None, leftover=None, combine=True,
"""

tx_hex = self.create_transaction(
outputs, fee=fee, leftover=leftover, combine=combine, message=message, bytes=bytes, unspents=unspents
outputs, fee=fee, leftover=leftover, combine=combine, message=message, unspents=unspents
)

NetworkAPI.broadcast_tx(tx_hex)
Expand All @@ -304,7 +297,7 @@ def send(self, outputs, fee=None, leftover=None, combine=True,

@classmethod
def prepare_transaction(cls, address, outputs, compressed=True, fee=None, leftover=None,
combine=True, message=None, bytes=False, unspents=None): # pragma: no cover
combine=True, message=None, unspents=None): # pragma: no cover
"""Prepares a P2PKH transaction for offline signing.
:param address: The address the funds will be sent from.
Expand Down Expand Up @@ -335,9 +328,6 @@ def prepare_transaction(cls, address, outputs, compressed=True, fee=None, leftov
stored in the blockchain forever. Due to size limits,
each message will be stored in chunks of 220 bytes.
:type message: ``str``
:param bytes: Whether or not the supplied message is already bytes. If
false (default), message is automatically encoded to UTF-8.
:type bytes: ``bool``
:param unspents: The UTXOs to use as the inputs. By default Bitcash will
communicate with the blockchain itself.
:type unspents: ``list`` of :class:`~bitcash.network.meta.Unspent`
Expand All @@ -351,7 +341,6 @@ def prepare_transaction(cls, address, outputs, compressed=True, fee=None, leftov
leftover or address,
combine=combine,
message=message,
bytes=bytes,
compressed=compressed
)

Expand Down Expand Up @@ -510,7 +499,7 @@ def get_transactions(self):
return self.transactions

def create_transaction(self, outputs, fee=None, leftover=None, combine=True,
message=None, bytes=False, unspents=None):
message=None, unspents=None):
"""Creates a signed P2PKH transaction.
:param outputs: A sequence of outputs you wish to send in the form
Expand All @@ -536,9 +525,6 @@ def create_transaction(self, outputs, fee=None, leftover=None, combine=True,
stored in the blockchain forever. Due to size limits,
each message will be stored in chunks of 220 bytes.
:type message: ``str``
:param bytes: Whether or not the supplied message is already bytes. If
false (default), message is automatically encoded to UTF-8.
:type bytes: ``bool``
:param unspents: The UTXOs to use as the inputs. By default Bitcash will
communicate with the testnet blockchain itself.
:type unspents: ``list`` of :class:`~bitcash.network.meta.Unspent`
Expand All @@ -553,14 +539,13 @@ def create_transaction(self, outputs, fee=None, leftover=None, combine=True,
leftover or self.address,
combine=combine,
message=message,
bytes=bytes,
compressed=self.is_compressed()
)

return create_p2pkh_transaction(self, unspents, outputs)

def send(self, outputs, fee=None, leftover=None, combine=True,
message=None, bytes=False, unspents=None):
message=None, unspents=None):
"""Creates a signed P2PKH transaction and attempts to broadcast it on
the testnet blockchain. This accepts the same arguments as
:func:`~bitcash.PrivateKeyTestnet.create_transaction`.
Expand Down Expand Up @@ -588,9 +573,6 @@ def send(self, outputs, fee=None, leftover=None, combine=True,
stored in the blockchain forever. Due to size limits,
each message will be stored in chunks of 220 bytes.
:type message: ``str``
:param bytes: Whether or not the supplied message is already bytes. If
false (default), message is automatically encoded to UTF-8.
:type bytes: ``bool``
:param unspents: The UTXOs to use as the inputs. By default Bitcash will
communicate with the testnet blockchain itself.
:type unspents: ``list`` of :class:`~bitcash.network.meta.Unspent`
Expand All @@ -599,7 +581,7 @@ def send(self, outputs, fee=None, leftover=None, combine=True,
"""

tx_hex = self.create_transaction(
outputs, fee=fee, leftover=leftover, combine=combine, message=message, bytes=bytes, unspents=unspents
outputs, fee=fee, leftover=leftover, combine=combine, message=message, unspents=unspents
)

NetworkAPI.broadcast_tx_testnet(tx_hex)
Expand All @@ -608,7 +590,7 @@ def send(self, outputs, fee=None, leftover=None, combine=True,

@classmethod
def prepare_transaction(cls, address, outputs, compressed=True, fee=None, leftover=None,
combine=True, message=None, bytes=False, unspents=None):
combine=True, message=None, unspents=None):
"""Prepares a P2PKH transaction for offline signing.
:param address: The address the funds will be sent from.
Expand Down Expand Up @@ -639,9 +621,6 @@ def prepare_transaction(cls, address, outputs, compressed=True, fee=None, leftov
stored in the blockchain forever. Due to size limits,
each message will be stored in chunks of 220 bytes.
:type message: ``str``
:param bytes: Whether or not the supplied message is already bytes. If
false (default), message is automatically encoded to UTF-8.
:type bytes: ``bool``
:param unspents: The UTXOs to use as the inputs. By default Bitcash will
communicate with the blockchain itself.
:type unspents: ``list`` of :class:`~bitcash.network.meta.Unspent`
Expand All @@ -655,7 +634,6 @@ def prepare_transaction(cls, address, outputs, compressed=True, fee=None, leftov
leftover or address,
combine=combine,
message=message,
bytes=bytes,
compressed=compressed
)

Expand Down

0 comments on commit b25fe03

Please sign in to comment.