예제 #1
0
    def test_no_combine_with_fee(self):
        """
        Verify that unused unspents do not increase fee.
        """
        unspents_single = [Unspent(5000, 0, '', '', 0)]
        unspents_original = [Unspent(5000, 0, '', '', 0),
                             Unspent(5000, 0, '', '', 0)]
        outputs_original = [(BITCOIN_CASHADDRESS_TEST_COMPRESSED, 1000, 'satoshi')]

        unspents, outputs = sanitize_tx_data(
            unspents_original, outputs_original, fee=1, leftover=RETURN_ADDRESS,
            combine=False, message=None
        )

        unspents_single, outputs_single = sanitize_tx_data(
            unspents_single, outputs_original, fee=1, leftover=RETURN_ADDRESS,
            combine=False, message=None
        )

        assert unspents == [Unspent(5000, 0, '', '', 0)]
        assert unspents_single == [Unspent(5000, 0, '', '', 0)]
        assert len(outputs) == 2
        assert len(outputs_single) == 2
        assert outputs[1][0] == RETURN_ADDRESS
        assert outputs_single[1][0] == RETURN_ADDRESS
        assert outputs[1][1] == outputs_single[1][1]
예제 #2
0
    def test_no_combine_insufficient_funds(self):
        unspents_original = [Unspent(1000, 0, '', '', 0),
                             Unspent(1000, 0, '', '', 0)]
        outputs_original = [(BITCOIN_CASHADDRESS_TEST_COMPRESSED, 2500, 'satoshi')]

        with pytest.raises(InsufficientFunds):
            sanitize_tx_data(
                unspents_original, outputs_original, fee=50, leftover=RETURN_ADDRESS,
                combine=False, message=None
            )
예제 #3
0
    def test_zero_remaining(self):
        unspents_original = [Unspent(1000, 0, '', '', 0),
                             Unspent(1000, 0, '', '', 0)]
        outputs_original = [(BITCOIN_CASHADDRESS_TEST_COMPRESSED, 2000, 'satoshi')]

        unspents, outputs = sanitize_tx_data(
            unspents_original, outputs_original, fee=0, leftover=RETURN_ADDRESS,
            combine=True, message=None
        )

        assert unspents == unspents_original
        assert outputs == [(BITCOIN_CASHADDRESS_TEST_COMPRESSED, 2000)]
예제 #4
0
    def test_message(self):
        unspents_original = [Unspent(10000, 0, '', '', 0),
                             Unspent(10000, 0, '', '', 0)]
        outputs_original = [(BITCOIN_CASHADDRESS_TEST_COMPRESSED, 1000, 'satoshi')]

        unspents, outputs = sanitize_tx_data(
            unspents_original, outputs_original, fee=5, leftover=RETURN_ADDRESS,
            combine=True, message='hello'
        )

        assert len(outputs) == 3
        assert outputs[2][0] == b'hello'
        assert outputs[2][1] == 0
예제 #5
0
    def test_combine_insufficient_funds(self):
        unspents_original = [
            Unspent(1000, 0, '', '', 0),
            Unspent(1000, 0, '', '', 0)
        ]
        outputs_original = [('test', 2500, 'satoshi')]

        with pytest.raises(InsufficientFunds):
            sanitize_tx_data(unspents_original,
                             outputs_original,
                             fee=50,
                             leftover=RETURN_ADDRESS,
                             combine=True,
                             message=None)
예제 #6
0
    def test_no_combine_remaining(self):
        unspents_original = [Unspent(7000, 0, '', '', 0),
                             Unspent(3000, 0, '', '', 0)]
        outputs_original = [(BITCOIN_CASHADDRESS_TEST_COMPRESSED, 2000, 'satoshi')]

        unspents, outputs = sanitize_tx_data(
            unspents_original, outputs_original, fee=0, leftover=RETURN_ADDRESS,
            combine=False, message=None
        )

        assert unspents == [Unspent(3000, 0, '', '', 0)]
        assert len(outputs) == 2
        assert outputs[1][0] == RETURN_ADDRESS
        assert outputs[1][1] == 1000
예제 #7
0
 def test_init(self):
     unspent = Unspent(10000, 7, 'script', 'txid', 0)
     assert unspent.amount == 10000
     assert unspent.confirmations == 7
     assert unspent.script == 'script'
     assert unspent.txid == 'txid'
     assert unspent.txindex == 0
예제 #8
0
    def test_fee_applied(self):
        unspents_original = [
            Unspent(1000, 0, "", "", 0),
            Unspent(1000, 0, "", "", 0)
        ]
        outputs_original = [(BITCOIN_CASHADDRESS_COMPRESSED, 2000, "satoshi")]

        with pytest.raises(InsufficientFunds):
            sanitize_tx_data(
                unspents_original,
                outputs_original,
                fee=1,
                leftover=RETURN_ADDRESS,
                combine=True,
                message=None,
            )
예제 #9
0
 def test_init(self):
     unspent = Unspent(10000, 7, "script", "txid", 0)
     assert unspent.amount == 10000
     assert unspent.confirmations == 7
     assert unspent.script == "script"
     assert unspent.txid == "txid"
     assert unspent.txindex == 0
예제 #10
0
    def test_combine_remaining(self):
        unspents_original = [
            Unspent(1000, 0, '', '', 0),
            Unspent(1000, 0, '', '', 0)
        ]
        outputs_original = [('test', 500, 'satoshi')]

        unspents, outputs = sanitize_tx_data(unspents_original,
                                             outputs_original,
                                             fee=0,
                                             leftover=RETURN_ADDRESS,
                                             combine=True,
                                             message=None)

        assert unspents == unspents_original
        assert len(outputs) == 2
        assert outputs[1][0] == RETURN_ADDRESS
        assert outputs[1][1] == 1500
예제 #11
0
 def get_unspent(cls, address):
     r = requests.get(cls.MAIN_UNSPENT_API.format(address),
                      timeout=DEFAULT_TIMEOUT)
     r.raise_for_status()  # pragma: no cover
     return [
         Unspent(currency_to_satoshi(tx['amount'],
                                     'bch'), tx['confirmations'],
                 tx['scriptPubKey'], tx['txid'], tx['vout'])
         for tx in r.json()
     ]
예제 #12
0
 def get_unspent_testnet(cls, address):
     r = requests.get(cls.TEST_UNSPENT_API.format(address),
                      timeout=DEFAULT_TIMEOUT)
     if r.status_code != 200:  # pragma: no cover
         raise ConnectionError
     return [
         Unspent(currency_to_satoshi(tx['amount'],
                                     'bch'), tx['confirmations'],
                 tx['scriptPubKey'], tx['txid'], tx['vout'])
         for tx in r.json()
     ]
예제 #13
0
    def test_combine_remaining(self):
        unspents_original = [
            Unspent(1000, 0, "", "", 0),
            Unspent(1000, 0, "", "", 0)
        ]
        outputs_original = [(BITCOIN_CASHADDRESS_COMPRESSED, 500, "satoshi")]

        unspents, outputs = sanitize_tx_data(
            unspents_original,
            outputs_original,
            fee=0,
            leftover=RETURN_ADDRESS,
            combine=True,
            message=None,
        )

        assert unspents == unspents_original
        assert len(outputs) == 2
        assert outputs[1][0] == RETURN_ADDRESS
        assert outputs[1][1] == 1500
예제 #14
0
 def get_unspent(cls, address):
     address = address.replace('bitcoincash:', '')
     r = requests.get(cls.MAIN_UNSPENT_API.format(address),
                      timeout=DEFAULT_TIMEOUT)
     r.raise_for_status()  # pragma: no cover
     return [
         Unspent(currency_to_satoshi(tx['value'],
                                     'satoshi'), tx['confirmations'],
                 tx['script'], tx['mintTxid'], tx['mintIndex'])
         for tx in r.json()
     ]
예제 #15
0
    def test_message_pushdata(self):
        unspents_original = [
            Unspent(10000, 0, '', '', 0),
            Unspent(10000, 0, '', '', 0)
        ]
        outputs_original = [(BITCOIN_CASHADDRESS_TEST_COMPRESSED, 1000,
                             'satoshi')]

        BYTES = len(b'hello').to_bytes(1, byteorder='little') + b'hello'

        unspents, outputs = sanitize_tx_data(unspents_original,
                                             outputs_original,
                                             fee=5,
                                             leftover=RETURN_ADDRESS,
                                             combine=True,
                                             message=BYTES,
                                             custom_pushdata=True)

        assert len(outputs) == 3
        assert outputs[2][0] == b'\x05' + b'hello'
        assert outputs[2][1] == 0
예제 #16
0
 async def _get_obj_unspent_list(self, addr):
     unspent_list = await self._get_raw_unspent_list(addr)
     return [
         Unspent(
             int(D(str(unspent['amount'])) * COIN),
             unspent['confirmations'],
             unspent['scriptPubKey'],
             unspent['txid'],
             unspent['vout']
         )
         for unspent in unspent_list
     ]
예제 #17
0
 def get_unspent(cls, address, network):
     API = cls.network_endpoint(network) + cls.UNSPENT_PATH
     r = requests.get(API.format(address), timeout=DEFAULT_TIMEOUT)
     r.raise_for_status()
     return [
         Unspent(
             currency_to_satoshi(tx["amount"], "bch"),
             tx["confirmations"],
             r.json()["scriptPubKey"],
             tx["txid"],
             tx["vout"],
         ) for tx in r.json()["utxos"]
     ]
예제 #18
0
    def test_message_pushdata(self):
        unspents_original = [
            Unspent(10000, 0, "", "", 0),
            Unspent(10000, 0, "", "", 0)
        ]
        outputs_original = [(BITCOIN_CASHADDRESS_COMPRESSED, 1000, "satoshi")]

        BYTES = len(b"hello").to_bytes(1, byteorder="little") + b"hello"

        unspents, outputs = sanitize_tx_data(
            unspents_original,
            outputs_original,
            fee=5,
            leftover=RETURN_ADDRESS,
            combine=True,
            message=BYTES,
            custom_pushdata=True,
        )

        assert len(outputs) == 3
        assert outputs[2][0] == b"\x05" + b"hello"
        assert outputs[2][1] == 0
예제 #19
0
 def get_unspent(cls, address):
     # As of 2018-05-16, cashexplorer.bitcoin.com only supports legacy addresses.
     address = cashaddress.to_legacy_address(address)
     r = requests.get(cls.MAIN_UNSPENT_API.format(address),
                      timeout=DEFAULT_TIMEOUT)
     if r.status_code != 200:  # pragma: no cover
         raise ConnectionError
     return [
         Unspent(currency_to_satoshi(tx['amount'],
                                     'bch'), tx['confirmations'],
                 tx['scriptPubKey'], tx['txid'], tx['vout'])
         for tx in r.json()
     ]
예제 #20
0
 def get_unspent(cls, address):
     if not cls.NEW_ADDRESS_SUPPORTED:
         address = cashaddress.to_legacy_address(address)
     r = requests.get((cls.MAIN_ENDPOINT+cls.MAIN_UNSPENT_API).format(address), timeout=DEFAULT_TIMEOUT)
     if r.status_code != 200:  # pragma: no cover
         raise ConnectionError
     return [
         Unspent(currency_to_satoshi(tx['amount'], 'bch'),
                 tx['confirmations'],
                 tx['scriptPubKey'],
                 tx['txid'],
                 tx['vout'])
         for tx in r.json()
     ]
예제 #21
0
    def sign_transaction(self, tx_data):
        """Creates a signed P2PKH transaction using previously prepared
        transaction data.

        :param tx_data: Output of :func:`~bitcash.PrivateKeyTestnet.prepare_transaction`.
        :type tx_data: ``str``
        :returns: The signed transaction as hex.
        :rtype: ``str``
        """
        data = json.loads(tx_data)

        unspents = [Unspent.from_dict(unspent) for unspent in data['unspents']]
        outputs = data['outputs']

        return create_p2pkh_transaction(self, unspents, outputs)
예제 #22
0
    def test_no_combine_remaining_small_inputs(self):
        unspents_original = [
            Unspent(1500, 0, "", "", 0),
            Unspent(1600, 0, "", "", 0),
            Unspent(1700, 0, "", "", 0),
        ]
        outputs_original = [(BITCOIN_CASHADDRESS_COMPRESSED, 2000, "satoshi")]

        unspents, outputs = sanitize_tx_data(
            unspents_original,
            outputs_original,
            fee=0,
            leftover=RETURN_ADDRESS,
            combine=False,
            message=None,
        )
        print(unspents)
        assert unspents == [
            Unspent(1500, 0, "", "", 0),
            Unspent(1600, 0, "", "", 0)
        ]
        assert len(outputs) == 2
        assert outputs[1][0] == RETURN_ADDRESS
        assert outputs[1][1] == 1100
예제 #23
0
    def get_unspent_testnet(cls, address):
        r = requests.get(cls.TEST_UNSPENT_API.format(address),
                         timeout=DEFAULT_TIMEOUT)
        if r.status_code != 200:  # pragma: no cover
            raise ConnectionError
        unspents = []
        for tx in r.json():
            # In weird conditions, the API will send back unspents without a scriptPubKey.
            if 'scriptPubKey' in tx:
                unspents.append(
                    Unspent(currency_to_satoshi(tx['amount'],
                                                'bch'), tx['confirmations'],
                            tx['scriptPubKey'], tx['txid'], tx['vout']))
            else:
                logging.warning('Unspent without scriptPubKey.')

        return unspents
예제 #24
0
    def get_unspent_testnet(cls, address):
        address = address.replace('bchtest:', '')
        r = requests.get(cls.TEST_UNSPENT_API.format(address),
                         timeout=DEFAULT_TIMEOUT)
        r.raise_for_status()  # pragma: no cover
        unspents = []
        for tx in r.json():
            # In weird conditions, the API will send back unspents
            # without a scriptPubKey.
            if 'script' in tx:
                unspents.append(
                    Unspent(currency_to_satoshi(tx['value'], 'satoshi'),
                            tx['confirmations'], tx['script'], tx['mintTxid'],
                            tx['mintIndex']))
            else:
                logging.warning('Unspent without scriptPubKey.')

        return unspents
예제 #25
0
    def get_unspent(cls, address, network):
        address = cls.remove_prefix(address)
        API = cls.network_endpoint(network) + cls.UNSPENT_API
        r = requests.get(API.format(address), timeout=DEFAULT_TIMEOUT)
        r.raise_for_status()
        unspents = []
        for tx in r.json():
            # In weird conditions, the API will send back unspents
            # without a scriptPubKey.
            if "script" in tx:
                unspents.append(
                    Unspent(
                        currency_to_satoshi(tx["value"], "satoshi"),
                        tx["confirmations"],
                        tx["script"],
                        tx["mintTxid"],
                        tx["mintIndex"],
                    ))
            else:
                logging.warning("Unspent without scriptPubKey.")

        return unspents
예제 #26
0
파일: bch_test.py 프로젝트: aldur/Arcula
def wallet_to_test_faucet(w,
                          tx_hash,
                          faucet_address='mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB'):
    """Transfer BCH from an Arcula wallet address (deterministically generated) back to the faucet."""
    # This is the address holding the funds using our Arcula transaction format.
    cold_storage_key = w.get_cold_storage_public_key()
    cold_storage_address = verification_key_to_address(cold_storage_key)
    from_signing_key, from_certificate = w.get_signing_key_certificate(
        FROM_ACCOUNT)

    r = requests.get(f"{BLOCKDOZER_T_API}/tx/{tx_hash}")
    assert r.status_code == 200, r.status_code
    unspent, *_ = r.json()['vout']
    unspent_output = \
        Unspent(int(float(unspent['value']) * BCH_TO_SATOSHI), -1, unspent['scriptPubKey']['hex'], tx_hash, 0)
    bch_to_send = (unspent_output.amount - BCH_FEES_SATOSHI) / BCH_TO_SATOSHI
    assert bch_to_send > 0, bch_to_send

    print(
        f"Sending {bch_to_send} BCH from the wallet '{cold_storage_address}' node "
        f"with identifier '{from_certificate[1]}' to '{faucet_address}'...")

    tx_hex = _create_apkh2pkh_transaction(
        cold_storage_key,
        bitcash.PrivateKeyTestnet.from_int(
            from_signing_key.privkey.secret_multiplier),
        from_certificate,
        unspent_output,
        (faucet_address, int(bch_to_send * BCH_TO_SATOSHI)),
    )

    bitcash.network.NetworkAPI.broadcast_tx_testnet(tx_hex)
    tx_hash = bitcash.transaction.calc_txid(tx_hex)

    print(f"Transaction: '{BITCOIN_EXPLORER_URL.format(tx_hash)}'.")
    return tx_hash
예제 #27
0
    def test_repr(self):
        unspent = Unspent(10000, 7, "script", "txid", 0)

        assert repr(unspent) == ("Unspent(amount=10000, confirmations=7, "
                                 "script='script', txid='txid', txindex=0)")
예제 #28
0
 def test_equality(self):
     unspent1 = Unspent(10000, 7, "script", "txid", 0)
     unspent2 = Unspent(10000, 7, "script", "txid", 0)
     unspent3 = Unspent(50000, 7, "script", "txid", 0)
     assert unspent1 == unspent2
     assert unspent1 != unspent3
예제 #29
0
    def test_dict_conversion(self):
        unspent = Unspent(10000, 7, "script", "txid", 0)

        assert unspent == Unspent.from_dict(unspent.to_dict())
예제 #30
0
 def test_equality(self):
     unspent1 = Unspent(10000, 7, 'script', 'txid', 0)
     unspent2 = Unspent(10000, 7, 'script', 'txid', 0)
     unspent3 = Unspent(50000, 7, 'script', 'txid', 0)
     assert unspent1 == unspent2
     assert unspent1 != unspent3