예제 #1
0
def send_message(sender_key: GcPrivateKey, spend_from_txid, receiver_addr,
                 op_ret_data):
    unspent = get_unspent_by_txid(sender_key, spend_from_txid)
    print(unspent)

    def chunk_data(data, size):
        return (data[i:i + size] for i in range(0, len(data), size))

    messages = []

    if op_ret_data:
        message_chunks = chunk_data(op_ret_data, MESSAGE_LIMIT)

        for message in message_chunks:
            messages.append((message, None))

    fee_amount = get_fee_amount(op_ret_data, len(messages))
    amount_back_to_sender = unspent.amount - fee_amount - MESSAGE_AMOUNT
    outputs = [
        (sender_key.address, amount_back_to_sender),
        (receiver_addr, MESSAGE_AMOUNT),
    ]

    outputs.extend(messages)

    tx_hex = transaction.create_p2pkh_transaction(sender_key.bitcash_key,
                                                  [unspent], outputs)
    tx_id = transaction.calc_txid(tx_hex)

    if which_net.is_testnet():
        network.NetworkAPI.broadcast_tx_testnet(tx_hex)
    else:
        raise Exception("TX broadcasting only tested with testnet")

    return tx_id
예제 #2
0
    def run(self):
        try:
            NetworkAPI.broadcast_tx(self.tx)
            self.ui.broadcasted.emit(calc_txid(self.tx))

        except ConnectionError as e:
            self.ui.broadcast_failed.emit("{}".format(e))
예제 #3
0
def broadcast_transaction(self, transaction):
    txid = calc_txid(transaction)
    LOGGER.info(f'Broadcasting {txid}:  {transaction}')
    txn_check = Transaction.objects.filter(txid=txid)
    success = False
    if txn_check.exists():
        success = True
        return success, txid
    else:
        try:
            obj = BCHDQuery()
            try:
                txid = obj.broadcast_transaction(transaction)
                if txid:
                    if tx_found:
                        success = True
                        return success, txid
                    else:
                        self.retry(countdown=1)
                else:
                    self.retry(countdown=1)
            except Exception as exc:
                error = exc.details()
                LOGGER.error(error)
                return False, error
        except AttributeError:
            self.retry(countdown=1)
예제 #4
0
    async def transfer(self,
                       amount,
                       recipient,
                       memo: str = None,
                       fee_rate=None) -> str:
        """Transfer BCH

        :param amount: amount of BTC to transfer (don't multiply by 10**8)
        :type amount: int, float, decimal
        :param recipient: destination address
        :type recipient: str
        :param memo: optional memo for transaction
        :type memo: str
        :param fee_rate: fee rates for transaction
        :type fee_rate: int
        :returns: The transaction hash
        """
        try:
            fee_rate = fee_rate or (await self.get_fee_rates())['fast']

            KeyClass = PrivateKeyTestnet if self.get_network(
            ) == "testnet" else PrivateKey
            key = KeyClass.from_hex(self.get_private_key())

            tx_hex = await utils.build_tx(amount, recipient, memo, fee_rate,
                                          self.get_address(),
                                          self.get_network(),
                                          self.get_client_url(), key)

            network.NetworkAPI.broadcast_tx_testnet(tx_hex)
            return transaction.calc_txid(tx_hex)

        except Exception as err:
            raise Exception(str(err))
예제 #5
0
    def send(
        self,
        outputs,
        fee=None,
        leftover=None,
        combine=True,
        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`.

        :param outputs: A sequence of outputs you wish to send in the form
                        ``(destination, amount, currency)``. The amount can
                        be either an int, float, or string as long as it is
                        a valid input to ``decimal.Decimal``. The currency
                        must be :ref:`supported <supported currencies>`.
        :type outputs: ``list`` of ``tuple``
        :param fee: The number of satoshi per byte to pay to miners. By default
                    Bitcash will poll `<https://bitcoincashfees.earn.com>`_ and use a fee
                    that will allow your transaction to be confirmed as soon as
                    possible.
        :type fee: ``int``
        :param leftover: The destination that will receive any change from the
                         transaction. By default Bitcash will send any change to
                         the same address you sent from.
        :type leftover: ``str``
        :param combine: Whether or not Bitcash should use all available UTXOs to
                        make future transactions smaller and therefore reduce
                        fees. By default Bitcash will consolidate UTXOs.
        :type combine: ``bool``
        :param message: A message to include in the transaction. This will be
                        stored in the blockchain forever. Due to size limits,
                        each message will be stored in chunks of 220 bytes.
        :type message: ``str``
        :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`
        :returns: The transaction ID.
        :rtype: ``str``
        """

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

        NetworkAPI.broadcast_tx(tx_hex, network=NETWORKS[self._network])

        return calc_txid(tx_hex)
예제 #6
0
def test_calc_txid():
    assert calc_txid(FINAL_TX_1) == '64637ffb0d36003eccbb0317dee000ac8a2744cbea3b8a4c3a477c132bb8ca69'
예제 #7
0
def test_calc_txid():
    assert calc_txid(FINAL_TX_1) == FINAL_TX_ID
예제 #8
0
def test_calc_txid():
    assert calc_txid(
        FINAL_TX_1
    ) == 'e6922a6e3f1ff422113f15543fbe1340a727441202f55519640a70ac4636c16f'